예제 #1
0
void seekabilizer::seek(t_filesize p_position,abort_callback & p_abort) {
	assert(m_position_base >= m_buffer.get_depth());
	p_abort.check_e();

	if (m_size != filesize_invalid && p_position > m_size) throw exception_io_seek_out_of_range();

	t_filesize lowest = m_position_base - m_buffer.get_depth();

	if (p_position < lowest) {
		if (m_file->can_seek()) {
			m_buffer.reset();
			t_filesize target = p_position;
			t_size delta = m_buffer.get_max_depth();
			if (delta > backread_on_seek) delta = backread_on_seek;
			if (target > delta) target -= delta;
			else target = 0;
			m_file->seek(target,p_abort);
			m_position_base = target;
		}
		else {
			m_buffer.reset();
			m_file->reopen(p_abort);
			m_position_base = 0;
		}
	}

	m_position = p_position;
}
void stream_writer_buffered::write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
	p_abort.check_e();
	const char * source = (const char*)p_buffer;
	t_size source_remaining = p_bytes;
	const t_size buffer_size = m_buffer.get_size();
	if (source_remaining >= buffer_size)
	{
		flush(p_abort);
		m_base->write_object(source,source_remaining,p_abort);
		return;
	}

	if (m_buffer_ptr + source_remaining >= buffer_size)
	{
		t_size delta = buffer_size - m_buffer_ptr;
		memcpy(m_buffer.get_ptr() + m_buffer_ptr, source,delta);
		source += delta;
		source_remaining -= delta;
		m_buffer_ptr += delta;
		flush(p_abort);
	}

	memcpy(m_buffer.get_ptr() + m_buffer_ptr, source,source_remaining);
	m_buffer_ptr += source_remaining;
}
예제 #3
0
t_size seekabilizer::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
	p_abort.check_e();

	if (m_position > m_position_base + pfc::max_t<t_size>(m_buffer.get_max_depth(),backread_on_seek) && m_file->can_seek()) {
		m_buffer.reset();
		t_filesize target = m_position;
		if (target < backread_on_seek) target = 0;
		else target -= backread_on_seek;
		m_file->seek(target,p_abort);
		m_position_base = target;
	}

	//seek ahead
	while(m_position > m_position_base) {
		enum {tempsize = 1024};
		t_uint8 temp[tempsize];
		t_size delta = (t_size) pfc::min_t<t_filesize>(tempsize,m_position - m_position_base);
		t_size bytes_read = 0;
		bytes_read = m_file->read(temp,delta,p_abort);
		m_buffer.write(temp,bytes_read);
		m_position_base += bytes_read;

		if (bytes_read < delta) {
			return 0;
		}
	}

	t_size done = 0;
	t_uint8 * targetptr = (t_uint8*) p_buffer;

	//try to read backbuffer
	if (m_position < m_position_base) {
		if (m_position_base - m_position > (t_filesize)m_buffer.get_depth()) throw exception_io_seek_out_of_range();
		t_size backread_depth = (t_size) (m_position_base - m_position);
		t_size delta = pfc::min_t<t_size>(backread_depth,p_bytes-done);
		m_buffer.read(backread_depth,targetptr,delta);
		done += delta;
		m_position += delta;
	}

	//regular read
	if (done < p_bytes)
	{
		t_size bytes_read;
		bytes_read = m_file->read(targetptr+done,p_bytes-done,p_abort);

		m_buffer.write(targetptr+done,bytes_read);

		done += bytes_read;
		m_position += bytes_read;
		m_position_base += bytes_read;
	}

	return done;
}
예제 #4
0
t_size reader_membuffer_base::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
	p_abort.check_e();
	t_size max = get_buffer_size();
	if (max < m_offset) uBugCheck();
	max -= m_offset;
	t_size delta = p_bytes;
	if (delta > max) delta = max;
	memcpy(p_buffer,(char*)get_buffer() + m_offset,delta);
	m_offset += delta;
	return delta;
}
예제 #5
0
void stream_reader_chunk::flush(abort_callback & p_abort) {
	while(!m_eof) {
		p_abort.check_e();
		t_uint8 temp;
		m_reader->read_lendian_t(temp,p_abort);
		m_buffer_size = temp;
		if (temp != sizeof(m_buffer)) m_eof = true;
		m_buffer_state = 0;
		if (m_buffer_size>0) {
			m_reader->skip_object(m_buffer_size,p_abort);
		}
	}
}
예제 #6
0
bool directory_callback_impl::on_entry(filesystem * owner,abort_callback & p_abort,const char * url,bool is_subdirectory,const t_filestats & p_stats) {
	p_abort.check_e();
	if (is_subdirectory) {
		if (m_recur) {
			try {
				owner->list_directory(url,*this,p_abort);
			} catch(exception_io const &) {}
		}
	} else {
		m_data.add_item(pfc::rcnew_t<t_entry>(url,p_stats));
	}
	return true;
}
예제 #7
0
t_filesize file::g_transfer(stream_reader * p_src,stream_writer * p_dst,t_filesize p_bytes,abort_callback & p_abort) {
	enum {BUFSIZE = 1024*1024*8};
	pfc::array_t<t_uint8> temp;
	temp.set_size((t_size)pfc::min_t<t_filesize>(BUFSIZE,p_bytes));
	void* ptr = temp.get_ptr();
	t_filesize done = 0;
	while(done<p_bytes) {
		p_abort.check_e();
		t_size delta = (t_size)pfc::min_t<t_filesize>(BUFSIZE,p_bytes-done);
		delta = p_src->read(ptr,delta,p_abort);
		if (delta<=0) break;
		p_dst->write(ptr,delta,p_abort);
		done += delta;
	}
	return done;
}
예제 #8
0
static bool grab_items_by_path(pfc::list_base_t<metadb_handle_ptr> & p_out,const char * p_path,abort_callback & p_abort)
{
	try {
		pfc::string8 path;
		filesystem::g_get_canonical_path(p_path,path);
		p_out.remove_all();
		service_ptr_t<input_info_reader> reader;
		input_entry::g_open_for_info_read(reader,0,path,p_abort);

		static_api_ptr_t<metadb> l_metadb;
		
		const t_uint32 count = reader->get_subsong_count();
		for(t_uint32 n=0;n<count;n++) {
			p_abort.check_e();
			metadb_handle_ptr ptr;
			l_metadb->handle_create(ptr,make_playable_location(path,reader->get_subsong(n)));
			p_out.add_item(ptr);
		}

		return p_out.get_count() > 0;
	} catch(std::exception const &) {return false;}
}
예제 #9
0
void reader_membuffer_base::seek(t_filesize position,abort_callback & p_abort) {
	p_abort.check_e();
	t_filesize max = get_buffer_size();
	if (position == filesize_invalid || position > max) throw exception_io_seek_out_of_range();
	m_offset = (t_size)position;
}
예제 #10
0
t_filetimestamp seekabilizer::get_timestamp(abort_callback & p_abort) {
	p_abort.check_e();
	return m_file->get_timestamp(p_abort);
}
예제 #11
0
t_filesize seekabilizer::get_position(abort_callback & p_abort) {
	p_abort.check_e();
	return m_position;
}
예제 #12
0
t_filesize seekabilizer::get_size(abort_callback & p_abort) {
	p_abort.check_e();
	return m_size;
}