13 operator const char * ()
const {
return m_data.get_ptr();}
14 const char *
get_ptr()
const {
return m_data.get_ptr();}
23 operator const char * ()
const {
return m_data.get_ptr();}
24 const char *
get_ptr()
const {
return m_data.get_ptr();}
48 virtual const void * get_buffer() = 0;
49 virtual t_size get_buffer_size() = 0;
52 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;}
60 m_data.set_size_discard(size);
61 memcpy(m_data.get_ptr(), ptr, size);
82 if (!ptr->init(p_src,p_abort))
return false;
87 if (m_contentType.is_empty())
return false;
88 out = m_contentType;
return true;
95 if (p_src->is_in_memory())
return false;
96 if (!p_src->get_content_type(m_contentType)) m_contentType.reset();
97 m_remote = p_src->is_remote();
99 t_size size = pfc::downcast_guarded<t_size>(p_src->get_size(p_abort));
101 m_buffer.set_size(size);
103 p_src->reopen(p_abort);
105 p_src->read_object(m_buffer.get_ptr(),size,p_abort);
107 m_timestamp = p_src->get_timestamp(p_abort);
128 if (offset + size < offset)
throw pfc::exception_overflow();
129 r->init(base, offset, offset + size, abort);
151 pos = r->get_position(p_abort);
152 if (p_bytes > end - pos) p_bytes = (
t_size)(end - pos);
153 return r->read(p_buffer,p_bytes,p_abort);
159 return r->get_position(p_abort) - begin;
163 r->seek(position+begin,p_abort);
171 seekInternal(begin, p_abort);
176 r->seek(position, abort);
178 t_filesize positionWas = r->get_position(abort);
181 try { r->skip_object(position, abort); }
182 catch (exception_io_data) {
throw exception_io_seek_out_of_range(); }
186 try { r->skip_object(skipMe, abort); }
187 catch (exception_io_data) {
throw exception_io_seek_out_of_range(); }
203 template<
typename t_array>
void set_data(
const t_array & data) {
205 set_data(data.get_ptr(), data.get_size());
210 m_data =
reinterpret_cast<const unsigned char*
>(data);
211 m_data_size = dataSize;
216 memcpy(p_buffer,m_data+m_pointer,delta);
221 if (p_bytes > get_remaining())
throw exception_io_data_truncation();
222 memcpy(p_buffer,m_data+m_pointer,p_bytes);
223 m_pointer += p_bytes;
226 t_size remaining = get_remaining();
227 if (p_bytes >= remaining) {
228 m_pointer = m_data_size;
return remaining;
230 m_pointer += (
t_size)p_bytes;
return p_bytes;
234 if (p_bytes > get_remaining()) {
235 throw exception_io_data_truncation();
237 m_pointer += (
t_size)p_bytes;
241 PFC_ASSERT( offset <= m_data_size );
244 const void *
get_ptr_()
const {
return m_data + m_pointer;}
256 t_size base = m_buffer.get_size();
257 if (base + p_bytes < base)
throw std::bad_alloc();
258 m_buffer.set_size(base + p_bytes);
259 memcpy( (
t_uint8*) m_buffer.get_ptr() + base, p_buffer, p_bytes );
267 template<
class t_storage>
273 PFC_STATIC_ASSERT(
sizeof(m_output[0]) == 1 );
275 t_size base = m_output.get_size();
276 if (base + p_bytes < base)
throw std::bad_alloc();
277 m_output.set_size(base + p_bytes);
278 memcpy( (
t_uint8*) m_output.get_ptr() + base, p_buffer, p_bytes );
289 if (p_bytes > m_remaining) p_bytes = (
t_size)m_remaining;
291 t_size done = m_reader->read(p_buffer,p_bytes,p_abort);
299 if (p_bytes > m_remaining) p_bytes = m_remaining;
300 t_filesize done = m_reader->skip(p_bytes,p_abort);
306 if (m_remaining > 0) skip_object(m_remaining,p_abort);
320 m_headerposition = m_writer->get_position(p_abort);
322 m_writer->write_lendian_t((
t_uint32)0,p_abort);
327 end_offset = m_writer->get_position(p_abort);
328 m_writer->seek(m_headerposition,p_abort);
329 m_writer->write_lendian_t(pfc::downcast_guarded<t_uint32>(m_written),p_abort);
330 m_writer->seek(end_offset,p_abort);
334 m_writer->write(p_buffer,p_bytes,p_abort);
335 m_written += p_bytes;
356 unsigned char m_buffer[255];
374 unsigned char m_buffer[255];
401 if (isBigEndian) m_stream.read_bendian_t(p_out,m_abort);
402 else m_stream.read_lendian_t(p_out,m_abort);
406 m_stream.read_object(p_buffer,p_bytes,m_abort);
409 void skip(
t_size p_bytes) {m_stream.skip_object(p_bytes,m_abort);}
411 template<
typename TArray>
void read_raw(TArray& data) {
413 read_raw(data.get_ptr(),data.get_size());
417 t_uint32 size; read_int(size); data.set_size(size);
421 t_uint32 size; *
this >> size; data.set_size(size);
422 for(
t_uint32 walk = 0; walk < size; ++walk) *this >> data[walk];
425 m_stream.read_string_nullterm( out, m_abort );
436 if (isBigEndian) m_stream.write_bendian_t(p_int,m_abort);
437 else m_stream.write_lendian_t(p_int,m_abort);
441 m_stream.write_object(p_buffer,p_bytes,m_abort);
443 template<
typename TArray>
void write_raw(
const TArray& data) {
445 write_raw(data.get_ptr(),data.get_size());
450 write_int( pfc::downcast_guarded<t_uint32>(data.get_size()) );
454 const t_uint32 size = pfc::downcast_guarded<t_uint32>(data.get_size());
456 for(
t_uint32 walk = 0; walk < size; ++walk) *
this << data[walk];
460 const t_size len = strlen(str);
461 *this << pfc::downcast_guarded<t_uint32>(len);
466 *this << pfc::downcast_guarded<t_uint32>(len);
470 this->write_raw( str, strlen(str)+1 );
478 #define __DECLARE_INT_OVERLOADS(TYPE) \ 479 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;} \ 480 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;} 500 #undef __DECLARE_INT_OVERLOADS 511 for(
t_size walk = 0; walk < Count; ++walk) p_stream >> p_array[walk];
518 p_stream.write_raw(p_array,Count);
520 for(
t_size walk = 0; walk < Count; ++walk) p_stream << p_array[walk];
525 #define FB2K_STREAM_READER_OVERLOAD(type) \ 526 template<bool isBigEndian> stream_reader_formatter<isBigEndian> & operator>>(stream_reader_formatter<isBigEndian> & stream,type & value) 528 #define FB2K_STREAM_WRITER_OVERLOAD(type) \ 529 template<bool isBigEndian> stream_writer_formatter<isBigEndian> & operator<<(stream_writer_formatter<isBigEndian> & stream,const type & value) 532 return stream >> value.Data1 >> value.Data2 >> value.Data3 >> value.Data4;
536 return stream << value.Data1 << value.Data2 << value.Data3 << value.Data4;
541 value = stream.m_stream.read_string_ex(len,stream.m_abort);
546 stream << pfc::downcast_guarded<t_uint32>(value.length());
547 stream.write_raw(value.ptr(),value.length());
552 stream.m_stream.read_string(value, stream.m_abort);
556 const char * val = value.get_ptr();
557 const t_size len = strlen(val);
558 stream << pfc::downcast_guarded<t_uint32>(len);
559 stream.write_raw(val,len);
568 return stream << u.i;
573 stream >> u.i; value = u.f;
581 return stream << u.i;
586 stream >> u.i; value = u.f;
592 return stream << temp;
595 t_uint8 temp; stream >> temp; value = temp != 0;
599 template<
bool BE = false>
611 template<
bool BE = false>
618 void set_data(
const void * source,
t_size sourceSize) {_m_stream.set_data(source,sourceSize);}
619 template<
typename TSource>
void set_data(
const TSource & source) {_m_stream.set_data(source);}
624 const void *
get_ptr_()
const {
return _m_stream.get_ptr_();}
630 template<
bool BE = false>
638 m_content.set_data_fromptr(reinterpret_cast<const t_uint8*>(source), sourceSize);
641 template<
typename TSource>
void set_data(
const TSource & source) {
661 template<
typename t_what> t_self &
operator||(t_what & out) {m_stream >> out;
return *
this;}
669 template<
typename t_what> t_self &
operator||(
const t_what & in) {m_stream << in;
return *
this;}
674 #define FB2K_STREAM_RECORD_OVERLOAD(type, code) \ 675 FB2K_STREAM_READER_OVERLOAD(type) { \ 676 _stream_reader_formatter_translator<isBigEndian> streamEx(stream); \ 680 FB2K_STREAM_WRITER_OVERLOAD(type) { \ 681 _stream_writer_formatter_translator<isBigEndian> streamEx(stream); \ 689 #define FB2K_RETRY_ON_EXCEPTION(OP, ABORT, TIMEOUT, EXCEPTION) \ 691 pfc::lores_timer timer; timer.start(); \ 693 try { {OP;} break; } \ 694 catch(EXCEPTION) { if (timer.query() > TIMEOUT) throw;} \ 699 #define FB2K_RETRY_ON_EXCEPTION2(OP, ABORT, TIMEOUT, EXCEPTION1, EXCEPTION2) \ 701 pfc::lores_timer timer; timer.start(); \ 703 try { {OP;} break; } \ 704 catch(EXCEPTION1) { if (timer.query() > TIMEOUT) throw;} \ 705 catch(EXCEPTION2) { if (timer.query() > TIMEOUT) throw;} \ 710 #define FB2K_RETRY_ON_EXCEPTION3(OP, ABORT, TIMEOUT, EXCEPTION1, EXCEPTION2, EXCEPTION3) \ 712 pfc::lores_timer timer; timer.start(); \ 714 try { {OP;} break; } \ 715 catch(EXCEPTION1) { if (timer.query() > TIMEOUT) throw;} \ 716 catch(EXCEPTION2) { if (timer.query() > TIMEOUT) throw;} \ 717 catch(EXCEPTION3) { if (timer.query() > TIMEOUT) throw;} \ 722 #define FB2K_RETRY_ON_SHARING_VIOLATION(OP, ABORT, TIMEOUT) FB2K_RETRY_ON_EXCEPTION(OP, ABORT, TIMEOUT, exception_io_sharing_violation) 726 #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) 731 m_offset = f->get_position(a);
735 if (!m_abort.is_aborting()) m_file->seek(m_offset, m_abort);
752 m_mem.read( p_buffer, p_bytes, m_offset );
757 if (p_bytes > remaining())
throw exception_io_data_truncation();
758 m_mem.read( p_buffer, p_bytes, m_offset );
763 m_offset += (size_t) p_bytes;
767 if (p_bytes > remaining())
throw exception_io_data_truncation();
768 m_offset += (size_t) p_bytes;
774 if (p_position > m_mem.size())
throw exception_io_seek_out_of_range();
775 m_offset = (size_t) p_position;
788 m_mem.resize( newSize );
790 size_t remaining()
const {
return m_mem.size() - m_offset;}
800 source->reopen(abort);
802 if (fs > 1024*1024*1024) {
803 throw std::bad_alloc();
805 size_t s = (size_t) fs;
807 for(
size_t walk = 0; walk < m_mem._sliceCount(); ++walk) {
808 source->read( m_mem._slicePtr(walk), m_mem._sliceSize(walk), abort );
811 if (!source->get_content_type( m_contentType ) ) m_contentType.reset();
812 m_isRemote = source->is_remote();
813 m_ts = source->get_timestamp( abort );
817 if (m_contentType.is_empty())
return false;
818 p_out = m_contentType;
return true;
831 return m_file->read(p_buffer, p_bytes, p_abort);
834 m_file->read_object(p_buffer, p_bytes, p_abort);
837 return m_file->skip( p_bytes, p_abort );
840 m_file->skip_object(p_bytes, p_abort);
843 m_file->write( p_buffer, p_bytes, p_abort );
847 return m_file->get_size( p_abort );
851 return m_file->get_position( p_abort );
855 m_file->resize( p_size, p_abort );
859 m_file->seek( p_position, p_abort );
863 m_file->seek_ex( p_position, p_mode, p_abort );
870 #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)
t_int64 t_sfilesize
Type used for file size related variables when a signed value is needed.
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)
This class is used to signal underlying worker code whether user has decided to abort a potentially t...
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)
const char * get_ptr() const
t_filesize skip(t_filesize p_bytes, abort_callback &p_abort)
file_chain_readonly(file::ptr chain)
static void g_get_canonical_path(const char *path, pfc::string_base &out)
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 &)
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)
void listDirectory(const char *path, abort_callback &aborter, listDirectoryFunc_t func)
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.
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()
void skip_object(t_filesize p_bytes, abort_callback &p_abort)
void flush_remaining(abort_callback &p_abort)
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)
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.
Contains various I/O related structures and interfaces.
void seek_(t_size offset)
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 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)
t_filetimestamp get_timestamp(abort_callback &p_abort)
~fileRestorePositionScope()
bool get_content_type(pfc::string_base &out)
t_filetimestamp m_timestamp
void write(const service_ptr_t< file > &p_file, abort_callback &p_abort, const char *p_string, bool is_utf8)
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 seek(t_filesize p_position, abort_callback &p_abort)
static void g_get_display_path(const char *path, pfc::string_base &out)
void reopen(abort_callback &p_abort)
std::function< void(const char *, t_filestats const &, bool) > listDirectoryFunc_t
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 init(file::ptr source, abort_callback &abort)
pfc::array_staticsize_t< t_uint8 > m_data
t_size get_length() const
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
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)