40 virtual const void * get_buffer() = 0;
41 virtual t_size get_buffer_size() = 0;
44 inline void seek_internal(
t_size p_offset) {
if (p_offset > get_buffer_size())
throw exception_io_seek_out_of_range(); m_offset = p_offset;}
74 if (!ptr->init(p_src,p_abort))
return false;
87 if (p_src->is_in_memory())
return false;
91 t_size size = pfc::downcast_guarded<t_size>(p_src->get_size(p_abort));
95 p_src->reopen(p_abort);
120 if (offset + size < offset)
throw pfc::exception_overflow();
121 r->init(base, offset, offset + size, abort);
143 pos = r->get_position(p_abort);
144 if (p_bytes > end - pos) p_bytes = (
t_size)(end - pos);
145 return r->read(p_buffer,p_bytes,p_abort);
151 return r->get_position(p_abort) -
begin;
155 r->seek(position+begin,p_abort);
168 r->seek(position, abort);
170 t_filesize positionWas = r->get_position(abort);
173 try { r->skip_object(position, abort); }
174 catch (exception_io_data) {
throw exception_io_seek_out_of_range(); }
178 try { r->skip_object(skipMe, abort); }
179 catch (exception_io_data) {
throw exception_io_seek_out_of_range(); }
195 template<
typename t_array>
void set_data(
const t_array & data) {
197 set_data(data.get_ptr(), data.get_size());
202 m_data =
reinterpret_cast<const unsigned char*
>(data);
213 if (p_bytes >
get_remaining())
throw exception_io_data_truncation();
219 if (p_bytes >= remaining) {
227 throw exception_io_data_truncation();
249 if (base + p_bytes < base)
throw std::bad_alloc();
259 template<
class t_storage>
265 PFC_STATIC_ASSERT(
sizeof(
m_output[0]) == 1 );
268 if (base + p_bytes < base)
throw std::bad_alloc();
319 end_offset =
m_writer->get_position(p_abort);
326 m_writer->write(p_buffer,p_bytes,p_abort);
403 template<
typename TArray>
void read_raw(TArray& data) {
405 read_raw(data.get_ptr(),data.get_size());
413 t_uint32 size; *
this >> size; data.set_size(size);
414 for(
t_uint32 walk = 0; walk < size; ++walk) *this >> data[walk];
435 template<
typename TArray>
void write_raw(
const TArray& data) {
437 write_raw(data.get_ptr(),data.get_size());
442 write_int( pfc::downcast_guarded<t_uint32>(data.get_size()) );
446 const t_uint32 size = pfc::downcast_guarded<t_uint32>(data.get_size());
448 for(
t_uint32 walk = 0; walk < size; ++walk) *
this << data[walk];
452 const t_size len = strlen(str);
453 *this << pfc::downcast_guarded<t_uint32>(len);
458 *this << pfc::downcast_guarded<t_uint32>(len);
470 #define __DECLARE_INT_OVERLOADS(TYPE) \
471 template<bool isBigEndian> inline stream_reader_formatter<isBigEndian> & operator>>(stream_reader_formatter<isBigEndian> & p_stream,TYPE & p_int) {typename pfc::sized_int_t<sizeof(TYPE)>::t_unsigned temp;p_stream.read_int(temp); p_int = (TYPE) temp; return p_stream;} \
472 template<bool isBigEndian> inline stream_writer_formatter<isBigEndian> & operator<<(stream_writer_formatter<isBigEndian> & p_stream,TYPE p_int) {p_stream.write_int((typename pfc::sized_int_t<sizeof(TYPE)>::t_unsigned)p_int); return p_stream;}
492 #undef __DECLARE_INT_OVERLOADS
503 for(
t_size walk = 0; walk < Count; ++walk) p_stream >> p_array[walk];
510 p_stream.write_raw(p_array,Count);
512 for(
t_size walk = 0; walk < Count; ++walk) p_stream << p_array[walk];
517 #define FB2K_STREAM_READER_OVERLOAD(type) \
518 template<bool isBigEndian> stream_reader_formatter<isBigEndian> & operator>>(stream_reader_formatter<isBigEndian> & stream,type & value)
520 #define FB2K_STREAM_WRITER_OVERLOAD(type) \
521 template<bool isBigEndian> stream_writer_formatter<isBigEndian> & operator<<(stream_writer_formatter<isBigEndian> & stream,const type & value)
524 return stream >> value.Data1 >> value.Data2 >> value.Data3 >> value.Data4;
528 return stream << value.Data1 << value.Data2 << value.Data3 << value.Data4;
533 value = stream.m_stream.read_string_ex(len,stream.m_abort);
538 stream << pfc::downcast_guarded<t_uint32>(value.length());
539 stream.write_raw(value.ptr(),value.length());
544 stream.m_stream.read_string(value, stream.m_abort);
548 const char * val = value.get_ptr();
549 const t_size len = strlen(val);
550 stream << pfc::downcast_guarded<t_uint32>(len);
551 stream.write_raw(val,len);
560 return stream << u.i;
565 stream >> u.i; value = u.f;
573 return stream << u.i;
578 stream >> u.i; value = u.f;
584 return stream << temp;
587 t_uint8 temp; stream >> temp; value = temp != 0;
591 template<
bool BE = false>
603 template<
bool BE = false>
622 template<
bool BE = false>
633 template<
typename TSource>
void set_data(
const TSource & source) {
666 #define FB2K_STREAM_RECORD_OVERLOAD(type, code) \
667 FB2K_STREAM_READER_OVERLOAD(type) { \
668 _stream_reader_formatter_translator<isBigEndian> streamEx(stream); \
672 FB2K_STREAM_WRITER_OVERLOAD(type) { \
673 _stream_writer_formatter_translator<isBigEndian> streamEx(stream); \
681 #define FB2K_RETRY_ON_EXCEPTION(OP, ABORT, TIMEOUT, EXCEPTION) \
683 pfc::lores_timer timer; timer.start(); \
685 try { {OP;} break; } \
686 catch(EXCEPTION) { if (timer.query() > TIMEOUT) throw;} \
691 #define FB2K_RETRY_ON_EXCEPTION2(OP, ABORT, TIMEOUT, EXCEPTION1, EXCEPTION2) \
693 pfc::lores_timer timer; timer.start(); \
695 try { {OP;} break; } \
696 catch(EXCEPTION1) { if (timer.query() > TIMEOUT) throw;} \
697 catch(EXCEPTION2) { if (timer.query() > TIMEOUT) throw;} \
702 #define FB2K_RETRY_ON_EXCEPTION3(OP, ABORT, TIMEOUT, EXCEPTION1, EXCEPTION2, EXCEPTION3) \
704 pfc::lores_timer timer; timer.start(); \
706 try { {OP;} break; } \
707 catch(EXCEPTION1) { if (timer.query() > TIMEOUT) throw;} \
708 catch(EXCEPTION2) { if (timer.query() > TIMEOUT) throw;} \
709 catch(EXCEPTION3) { if (timer.query() > TIMEOUT) throw;} \
714 #define FB2K_RETRY_ON_SHARING_VIOLATION(OP, ABORT, TIMEOUT) FB2K_RETRY_ON_EXCEPTION(OP, ABORT, TIMEOUT, exception_io_sharing_violation)
718 #define FB2K_RETRY_FILE_MOVE(OP, ABORT, TIMEOUT) FB2K_RETRY_ON_EXCEPTION3(OP, ABORT, TIMEOUT, exception_io_sharing_violation, exception_io_denied, exception_io_already_exists)
749 if (p_bytes >
remaining())
throw exception_io_data_truncation();
759 if (p_bytes >
remaining())
throw exception_io_data_truncation();
766 if (p_position >
m_mem.
size())
throw exception_io_seek_out_of_range();
792 source->reopen(abort);
794 if (fs > 1024*1024*1024) {
795 throw std::bad_alloc();
797 size_t s = (size_t) fs;
805 m_ts = source->get_timestamp( abort );
823 return m_file->read(p_buffer, p_bytes, p_abort);
826 m_file->read_object(p_buffer, p_bytes, p_abort);
829 return m_file->skip( p_bytes, p_abort );
832 m_file->skip_object(p_bytes, p_abort);
835 m_file->write( p_buffer, p_bytes, p_abort );
839 return m_file->get_size( p_abort );
843 return m_file->get_position( p_abort );
847 m_file->resize( p_size, p_abort );
851 m_file->seek( p_position, p_abort );
855 m_file->seek_ex( p_position, p_mode, p_abort );
862 #if FOOBAR2000_TARGET_VERSION >= 2000
void reopen(abort_callback &p_abort)
void read(const service_ptr_t< file > &p_file, abort_callback &p_abort, pfc::string_base &p_out, bool &is_utf8)
__DECLARE_INT_OVERLOADS(char)
void read_object(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
void read_object(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
void reopen(abort_callback &p_abort)
t_filesize get_size(HANDLE p_handle)
t_filetimestamp get_timestamp(abort_callback &p_abort)
t_filesize get_position(abort_callback &p_abort)
t_filesize get_position(abort_callback &p_abort)
t_filesize get_position(abort_callback &p_abort)
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
const t_item * get_ptr() const
t_int64 t_sfilesize
Type used for file size related variables when a signed value is needed.
const t_item * get_ptr() const
Template implementing reference-counting features of service_base. Intended for dynamic instantiation...
reader_membuffer_simple(const void *ptr, t_size size, t_filetimestamp ts=filetimestamp_invalid, bool is_remote=false)
bool get_content_type(pfc::string_base &p_out)
T min_t(const T &item1, const T &item2)
t_filetimestamp get_timestamp(abort_callback &p_abort)
void seek(HANDLE p_handle, t_sfilesize p_position, file::t_seek_mode p_mode)
FB2K_STREAM_READER_OVERLOAD(GUID)
void flush(abort_callback &p_abort)
const char * get_ptr() const
t_filesize skip(t_filesize p_bytes, abort_callback &p_abort)
file_chain_readonly(file::ptr chain)
void write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
file_path_display(const char *src)
t_filesize skip(t_filesize p_bytes, abort_callback &p_abort)
stream_writer_buffer_append_ref_t(t_storage &p_output)
abort_callback_impl abort_callback_dummy
static file::ptr create(file::ptr chain)
virtual bool get_content_type(pfc::string_base &)
size_t _sliceSize(size_t which)
reader_limited(const service_ptr_t< file > &p_r, t_filesize p_begin, t_filesize p_end, abort_callback &p_abort)
t_size get_remaining() const
fileRestorePositionScope(file::ptr f, abort_callback &a)
const char * get_ptr() const
t_filesize get_size(abort_callback &p_abort)
stream_reader_memblock_ref(const t_array &p_array)
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
const void * get_buffer()
t_filesize get_position(abort_callback &p_abort)
void resize(t_filesize p_size, abort_callback &p_abort)
static const t_filesize filesize_invalid
Invalid/unknown file size constant. Also see: t_filesize.
t_size get_length() const
pfc::string8 m_contentType
t_size get_length() const
void init(const service_ptr_t< file > &p_r, t_filesize p_begin, t_filesize p_end, abort_callback &p_abort)
static file::ptr g_create(file::ptr base, t_filesize offset, t_filesize size, abort_callback &abort)
t_filetimestamp get_timestamp(abort_callback &p_abort)
stream_reader_memblock_ref()
unsigned char m_buffer[255]
void skip_object(t_filesize p_bytes, abort_callback &p_abort)
void flush_remaining(abort_callback &p_abort)
uint8_t * _slicePtr(size_t which)
void set_data(const void *data, t_size dataSize)
t_filetimestamp get_timestamp(abort_callback &p_abort)
file_chain(file::ptr chain)
t_filesize skip(t_filesize p_bytes, abort_callback &p_abort)
void write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
void seek(t_filesize p_position, abort_callback &p_abort)
const t_filetimestamp filetimestamp_invalid
Invalid/unknown file timestamp constant. Also see: t_filetimestamp.
void seek_(t_size offset)
const char * get_ptr() const
void seekInternal(t_filesize position, abort_callback &abort)
t_filesize get_size(abort_callback &p_abort)
t_filestats get_stats(abort_callback &abort)
stream_reader_formatter< isBigEndian > & operator>>(stream_reader_formatter< isBigEndian > &p_stream, TVal(&p_array)[Count])
t_size strlen_max(const char *ptr, t_size max)
static bool g_create(service_ptr_t< file > &p_out, const service_ptr_t< file > &p_src, abort_callback &p_abort)
Returns false when the object could not be mirrored (too big) or did not need mirroring.
t_filesize get_size(abort_callback &p_abort)
stream_reader_memblock_ref(const void *p_data, t_size p_data_size)
void set_size(t_size p_size)
void resize(t_filesize p_size, abort_callback &p_abort)
bool fb2kFileSelfTest(file::ptr f, abort_callback &aborter)
Debug self-test function for testing a file object implementation, performs various behavior validity...
void skip_object(t_filesize p_bytes, abort_callback &p_abort)
t_filesize skip(t_filesize p_bytes, abort_callback &p_abort)
pfc::string8 m_contentType
t_filetimestamp get_timestamp(abort_callback &p_abort)
void read(void *ptrOut, size_t bytes, size_t offset)
t_filetimestamp get_timestamp(abort_callback &p_abort)
void flush(abort_callback &p_abort)
~fileRestorePositionScope()
bool get_content_type(pfc::string_base &out)
t_filetimestamp m_timestamp
static void g_skip(stream_reader *p_stream, abort_callback &p_abort)
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
stream_writer_chunk(stream_writer *p_writer)
bool get_content_type(pfc::string_base &)
void reopen(abort_callback &p_abort)
void resize(size_t newSize)
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
t_uint64 t_filetimestamp
Type used for file timestamp related variables. 64-bit value representing the number of 100-nanosecon...
void set_data_fromptr(const t_source *p_buffer, t_size p_count)
Warning: buffer pointer must not point to buffer allocated by this array (fixme). ...
void seek(t_filesize p_position, abort_callback &p_abort)
void reopen(abort_callback &p_abort)
void write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
t_uint64 t_filesize
Type used for file size related variables.
void write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
void seek(t_filesize position, abort_callback &p_abort)
const void * get_buffer()
bool init(const service_ptr_t< file > &p_src, abort_callback &p_abort)
stream_reader_limited_ref(stream_reader *p_reader, t_filesize p_limit)
void resize(size_t newSize)
void init(file::ptr source, abort_callback &abort)
pfc::array_staticsize_t< t_uint8 > m_data
t_size get_length() const
unsigned char m_buffer[255]
bool get_content_type(pfc::string_base &p_out)
void seek_internal(t_size p_offset)
pfc::array_t< char > m_buffer
void seek_ex(t_sfilesize p_position, t_seek_mode p_mode, abort_callback &p_abort)
stream_reader_chunk(stream_reader *p_reader)
const void * get_ptr_() const
const unsigned char * m_data
New EXPERIMENTAL string class, allowing efficient copies and returning from functions. Does not implement the string_base interface so you still need string8 in many cases. Safe to pass between DLLs, but since a reference is used, objects possibly created by other DLLs must be released before owning DLLs are unloaded.
void skip_object(t_filesize p_bytes, abort_callback &p_abort)
void read_object(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
void on_idle(abort_callback &p_abort)
void write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
pfc::array_t< t_uint8, pfc::alloc_fast > t_buffer
void set_size_discard(t_size p_size)
t_filesize get_remaining() const
t_size read(void *p_buffer, t_size p_bytes, abort_callback &p_abort)
void write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort)
t_filesize get_size(abort_callback &p_abort)
void set_data(const t_array &data)
file_path_canonical(const char *src)
void min_acc(t_val &p_acc, const t_val &p_val)
FB2K_STREAM_WRITER_OVERLOAD(GUID)
pfc::array_t< t_uint8, pfc::alloc_fast > m_buffer
bool get_content_type(pfc::string_base &p_out)