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; }
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; }
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; }
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); } } }
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; }
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; }
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;} }
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; }
t_filetimestamp seekabilizer::get_timestamp(abort_callback & p_abort) { p_abort.check_e(); return m_file->get_timestamp(p_abort); }
t_filesize seekabilizer::get_position(abort_callback & p_abort) { p_abort.check_e(); return m_position; }
t_filesize seekabilizer::get_size(abort_callback & p_abort) { p_abort.check_e(); return m_size; }