annotate foosdk/sdk/foobar2000/SDK/filesystem_helper.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include <functional>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include "filesystem.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 namespace foobar2000_io {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 typedef std::function< void (const char *, t_filestats const & , bool ) > listDirectoryFunc_t;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 void listDirectory( const char * path, abort_callback & aborter, listDirectoryFunc_t func);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 pfc::string8 stripParentFolders( const char * inPath );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 void retryOnSharingViolation( std::function<void () > f, double timeout, abort_callback & a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 void retryOnSharingViolation( double timeout, abort_callback & a, std::function<void() > f);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 // **** WINDOWS SUCKS ****
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 // Special version of retryOnSharingViolation with workarounds for known MoveFile() bugs.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 void retryFileMove( double timeout, abort_callback & a, std::function<void()> f);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 // **** WINDOWS SUCKS ****
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 // Special version of retryOnSharingViolation with workarounds for known idiotic problems with folder removal.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 void retryFileDelete( double timeout, abort_callback & a, std::function<void()> f);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 class listDirectoryCallbackImpl : public directory_callback {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 listDirectoryCallbackImpl() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 listDirectoryCallbackImpl( listDirectoryFunc_t f ) : m_func(f) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 bool on_entry(filesystem *, abort_callback &, const char * p_url, bool p_is_subdirectory, const t_filestats & p_stats) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 m_func(p_url, p_stats, p_is_subdirectory);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 listDirectoryFunc_t m_func;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 pfc::string8 winGetVolumePath(const char * fb2kPath );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 DWORD winVolumeFlags( const char * fb2kPath );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 pfc::string8 file_path_canonical(const char* src);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 pfc::string8 file_path_display(const char* src);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 namespace fb2k {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 //! Sane replacement for pfc::string_filename_ext(), which isn't safe to use in cross-platform code.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 //! @returns Filename with extension extracted from path.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 pfc::string8 filename_ext( const char * path );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 pfc::string8 filename_ext( const char * path, filesystem::ptr & fs_reuse);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 //! Sane replacement for pfc::string_filename(), which isn't safe to use in cross-platform code
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 //! @returns Filename without extension extracted from path.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 pfc::string8 filename( const char * path );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 class stream_reader_memblock_ref : public stream_reader
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 template<typename t_array> stream_reader_memblock_ref(const t_array & p_array) : m_data(p_array.get_ptr()), m_data_size(p_array.get_size()), m_pointer(0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 pfc::assert_byte_type<typename t_array::t_item>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 stream_reader_memblock_ref(const void * p_data,t_size p_data_size) : m_data((const unsigned char*)p_data), m_data_size(p_data_size), m_pointer(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 stream_reader_memblock_ref() : m_data(NULL), m_data_size(0), m_pointer(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 template<typename t_array> void set_data(const t_array & data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 pfc::assert_byte_type<typename t_array::t_item>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 set_data(data.get_ptr(), data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 void set_data(const void * data, t_size dataSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 m_pointer = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 m_data = reinterpret_cast<const unsigned char*>(data);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 m_data_size = dataSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 t_size delta = pfc::min_t(p_bytes, get_remaining());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 memcpy(p_buffer,m_data+m_pointer,delta);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 m_pointer += delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 return delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 void read_object(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 if (p_bytes > get_remaining()) throw exception_io_data_truncation();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 memcpy(p_buffer,m_data+m_pointer,p_bytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 m_pointer += p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 t_filesize skip(t_filesize p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 t_size remaining = get_remaining();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 if (p_bytes >= remaining) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 m_pointer = m_data_size; return remaining;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 m_pointer += (t_size)p_bytes; return p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 void skip_object(t_filesize p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 if (p_bytes > get_remaining()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 throw exception_io_data_truncation();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 m_pointer += (t_size)p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 void seek_(t_size offset) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 PFC_ASSERT( offset <= m_data_size );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 m_pointer = offset;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 const void * get_ptr_() const {return m_data + m_pointer;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 t_size get_remaining() const {return m_data_size - m_pointer;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 void reset() {m_pointer = 0;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 const unsigned char * m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 t_size m_data_size,m_pointer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 template<typename buffer_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 class stream_writer_buffer_simple_t : public stream_writer {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 void write(const void * p_buffer, t_size p_bytes, abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 t_size base = m_buffer.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 if (base + p_bytes < base) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 m_buffer.set_size(base + p_bytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 memcpy((t_uint8*)m_buffer.get_ptr() + base, p_buffer, p_bytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 typedef buffer_t t_buffer; // other classes reference this
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 t_buffer m_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 typedef stream_writer_buffer_simple_t< pfc::array_t<t_uint8, pfc::alloc_fast> > stream_writer_buffer_simple;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 template<class t_storage>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 class stream_writer_buffer_append_ref_t : public stream_writer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 stream_writer_buffer_append_ref_t(t_storage & p_output) : m_output(p_output) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 PFC_STATIC_ASSERT( sizeof(m_output[0]) == 1 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 p_abort.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 t_size base = m_output.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 if (base + p_bytes < base) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 m_output.set_size(base + p_bytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 memcpy( (t_uint8*) m_output.get_ptr() + base, p_buffer, p_bytes );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 t_storage & m_output;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 class stream_reader_limited_ref : public stream_reader {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 stream_reader_limited_ref(stream_reader * p_reader,t_filesize p_limit) : m_reader(p_reader), m_remaining(p_limit) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 if (p_bytes > m_remaining) p_bytes = (t_size)m_remaining;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 t_size done = m_reader->read(p_buffer,p_bytes,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 m_remaining -= done;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 return done;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 inline t_filesize get_remaining() const {return m_remaining;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 t_filesize skip(t_filesize p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 if (p_bytes > m_remaining) p_bytes = m_remaining;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 t_filesize done = m_reader->skip(p_bytes,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 m_remaining -= done;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 return done;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 void flush_remaining(abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 if (m_remaining > 0) skip_object(m_remaining,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 stream_reader * m_reader;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 t_filesize m_remaining;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 class stream_writer_chunk_dwordheader : public stream_writer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 stream_writer_chunk_dwordheader(const service_ptr_t<file> & p_writer) : m_writer(p_writer) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 void initialize(abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 m_headerposition = m_writer->get_position(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 m_written = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 m_writer->write_lendian_t((t_uint32)0,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 void finalize(abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 t_filesize end_offset;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 end_offset = m_writer->get_position(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 m_writer->seek(m_headerposition,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 m_writer->write_lendian_t(pfc::downcast_guarded<t_uint32>(m_written),p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 m_writer->seek(end_offset,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 m_writer->write(p_buffer,p_bytes,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 m_written += p_bytes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 service_ptr_t<file> m_writer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 t_filesize m_headerposition;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 t_filesize m_written;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 class stream_writer_chunk : public stream_writer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 stream_writer_chunk(stream_writer * p_writer) : m_writer(p_writer), m_buffer_state(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 void flush(abort_callback & p_abort);//must be called after writing before object is destroyed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 stream_writer * m_writer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 unsigned m_buffer_state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 unsigned char m_buffer[255];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 class stream_reader_chunk : public stream_reader
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 stream_reader_chunk(stream_reader * p_reader) : m_reader(p_reader), m_buffer_state(0), m_buffer_size(0), m_eof(false) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 void flush(abort_callback & p_abort);//must be called after reading before object is destroyed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 static void g_skip(stream_reader * p_stream,abort_callback & p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 stream_reader * m_reader;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 t_size m_buffer_state, m_buffer_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 bool m_eof;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 unsigned char m_buffer[255];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 class stream_reader_dummy : public stream_reader { t_size read(void *,t_size,abort_callback &) override {return 0;} };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 template<bool isBigEndian = false> class stream_reader_formatter {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 stream_reader_formatter(stream_reader & p_stream,abort_callback & p_abort) : m_stream(p_stream), m_abort(p_abort) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 template<typename t_int> void read_int(t_int & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 if (isBigEndian) m_stream.read_bendian_t(p_out,m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 else m_stream.read_lendian_t(p_out,m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 void read_raw(void * p_buffer,t_size p_bytes) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 m_stream.read_object(p_buffer,p_bytes,m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 void skip(t_size p_bytes) {m_stream.skip_object(p_bytes,m_abort);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 template<typename TArray> void read_raw(TArray& data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 pfc::assert_byte_type<typename TArray::t_item>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 read_raw(data.get_ptr(),data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 template<typename TArray> void read_byte_block(TArray & data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 pfc::assert_byte_type<typename TArray::t_item>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 t_uint32 size; read_int(size); data.set_size(size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 read_raw(data);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 template<typename TArray> void read_array(TArray & data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 t_uint32 size; *this >> size; data.set_size(size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 for(t_uint32 walk = 0; walk < size; ++walk) *this >> data[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 void read_string_nullterm( pfc::string_base & ret ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 m_stream.read_string_nullterm( ret, m_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 pfc::string8 read_string_nullterm() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 pfc::string8 ret; this->read_string_nullterm(ret); return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 pfc::string8 read_string() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 return m_stream.read_string(m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 stream_reader & m_stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 abort_callback & m_abort;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 template<bool isBigEndian = false> class stream_writer_formatter {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 stream_writer_formatter(stream_writer & p_stream,abort_callback & p_abort) : m_stream(p_stream), m_abort(p_abort) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 template<typename t_int> void write_int(t_int p_int) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 if (isBigEndian) m_stream.write_bendian_t(p_int,m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 else m_stream.write_lendian_t(p_int,m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 void write_raw(const void * p_buffer,t_size p_bytes) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 m_stream.write_object(p_buffer,p_bytes,m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 template<typename TArray> void write_raw(const TArray& data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 pfc::assert_byte_type<typename TArray::t_item>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 write_raw(data.get_ptr(),data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 template<typename TArray> void write_byte_block(const TArray& data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 pfc::assert_byte_type<typename TArray::t_item>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 write_int( pfc::downcast_guarded<t_uint32>(data.get_size()) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 write_raw( data );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 template<typename TArray> void write_array(const TArray& data) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 const t_uint32 size = pfc::downcast_guarded<t_uint32>(data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 *this << size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 for(t_uint32 walk = 0; walk < size; ++walk) *this << data[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 void write_string(const char * str) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 const t_size len = strlen(str);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 *this << pfc::downcast_guarded<t_uint32>(len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 write_raw(str, len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 void write_string(const char * str, t_size len_) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 const t_size len = pfc::strlen_max(str, len_);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 *this << pfc::downcast_guarded<t_uint32>(len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 write_raw(str, len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 void write_string_nullterm( const char * str ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 this->write_raw( str, strlen(str)+1 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 stream_writer & m_stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 abort_callback & m_abort;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 #define __DECLARE_INT_OVERLOADS(TYPE) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 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;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 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;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 __DECLARE_INT_OVERLOADS(char);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 __DECLARE_INT_OVERLOADS(signed char);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 __DECLARE_INT_OVERLOADS(unsigned char);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 __DECLARE_INT_OVERLOADS(signed short);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 __DECLARE_INT_OVERLOADS(unsigned short);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 __DECLARE_INT_OVERLOADS(signed int);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 __DECLARE_INT_OVERLOADS(unsigned int);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 __DECLARE_INT_OVERLOADS(signed long);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 __DECLARE_INT_OVERLOADS(unsigned long);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 __DECLARE_INT_OVERLOADS(signed long long);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 __DECLARE_INT_OVERLOADS(unsigned long long);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 __DECLARE_INT_OVERLOADS(wchar_t);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 #undef __DECLARE_INT_OVERLOADS
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 template<typename TVal> class _IsTypeByte {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 enum {value = pfc::is_same_type<TVal,char>::value || pfc::is_same_type<TVal,unsigned char>::value || pfc::is_same_type<TVal,signed char>::value};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 template<bool isBigEndian,typename TVal,size_t Count> stream_reader_formatter<isBigEndian> & operator>>(stream_reader_formatter<isBigEndian> & p_stream,TVal (& p_array)[Count]) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 if constexpr (_IsTypeByte<TVal>::value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 p_stream.read_raw(p_array,Count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 for(t_size walk = 0; walk < Count; ++walk) p_stream >> p_array[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 return p_stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 template<bool isBigEndian,typename TVal,size_t Count> stream_writer_formatter<isBigEndian> & operator<<(stream_writer_formatter<isBigEndian> & p_stream,TVal const (& p_array)[Count]) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 if constexpr (_IsTypeByte<TVal>::value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 p_stream.write_raw(p_array,Count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 for(t_size walk = 0; walk < Count; ++walk) p_stream << p_array[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 return p_stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 #define FB2K_STREAM_READER_OVERLOAD(type) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 template<bool isBigEndian> stream_reader_formatter<isBigEndian> & operator>>(stream_reader_formatter<isBigEndian> & stream,type & value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 #define FB2K_STREAM_WRITER_OVERLOAD(type) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 template<bool isBigEndian> stream_writer_formatter<isBigEndian> & operator<<(stream_writer_formatter<isBigEndian> & stream,const type & value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 FB2K_STREAM_READER_OVERLOAD(GUID) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 return stream >> value.Data1 >> value.Data2 >> value.Data3 >> value.Data4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 FB2K_STREAM_WRITER_OVERLOAD(GUID) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 return stream << value.Data1 << value.Data2 << value.Data3 << value.Data4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 FB2K_STREAM_READER_OVERLOAD(pfc::string) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 t_uint32 len; stream >> len;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414 value = stream.m_stream.read_string_ex(len,stream.m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 return stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418 FB2K_STREAM_WRITER_OVERLOAD(pfc::string) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 stream << pfc::downcast_guarded<t_uint32>(value.length());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 stream.write_raw(value.ptr(),value.length());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 return stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 FB2K_STREAM_READER_OVERLOAD(pfc::string_base) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 stream.m_stream.read_string(value, stream.m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426 return stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 FB2K_STREAM_WRITER_OVERLOAD(pfc::string_base) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 const char * val = value.get_ptr();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 const t_size len = strlen(val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 stream << pfc::downcast_guarded<t_uint32>(len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 stream.write_raw(val,len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 return stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 FB2K_STREAM_WRITER_OVERLOAD(float) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 union {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 float f; t_uint32 i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 } u; u.f = value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 return stream << u.i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 FB2K_STREAM_READER_OVERLOAD(float) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 union { float f; t_uint32 i;} u;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446 stream >> u.i; value = u.f;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 return stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450 FB2K_STREAM_WRITER_OVERLOAD(double) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 union {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 double f; t_uint64 i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 } u; u.f = value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454 return stream << u.i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 FB2K_STREAM_READER_OVERLOAD(double) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 union { double f; t_uint64 i;} u;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 stream >> u.i; value = u.f;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 return stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463 FB2K_STREAM_WRITER_OVERLOAD(bool) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464 t_uint8 temp = value ? 1 : 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 return stream << temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467 FB2K_STREAM_READER_OVERLOAD(bool) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468 t_uint8 temp; stream >> temp; value = temp != 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469 return stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 template<bool BE = false>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 class stream_writer_formatter_simple : public stream_writer_formatter<BE> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 stream_writer_formatter_simple() : stream_writer_formatter<BE>(_m_stream,fb2k::noAbort), m_buffer(_m_stream.m_buffer) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 typedef stream_writer_buffer_simple::t_buffer t_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 t_buffer & m_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 stream_writer_buffer_simple _m_stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 template<bool BE = false>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 class stream_reader_formatter_simple_ref : public stream_reader_formatter<BE> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486 stream_reader_formatter_simple_ref(const void * source, t_size sourceSize) : stream_reader_formatter<BE>(_m_stream,fb2k::noAbort), _m_stream(source,sourceSize) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 template<typename TSource> stream_reader_formatter_simple_ref(const TSource& source) : stream_reader_formatter<BE>(_m_stream,fb2k::noAbort), _m_stream(source) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 stream_reader_formatter_simple_ref() : stream_reader_formatter<BE>(_m_stream,fb2k::noAbort) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 void set_data(const void * source, t_size sourceSize) {_m_stream.set_data(source,sourceSize);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 template<typename TSource> void set_data(const TSource & source) {_m_stream.set_data(source);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493 void reset() {_m_stream.reset();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 t_size get_remaining() {return _m_stream.get_remaining();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 const void * get_ptr_() const {return _m_stream.get_ptr_();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
498 stream_reader_memblock_ref _m_stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
499 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501 template<bool BE = false>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502 class stream_reader_formatter_simple : public stream_reader_formatter_simple_ref<BE> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504 stream_reader_formatter_simple() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505 stream_reader_formatter_simple(const void * source, t_size sourceSize) {set_data(source,sourceSize);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506 template<typename TSource> stream_reader_formatter_simple(const TSource & source) {set_data(source);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
508 void set_data(const void * source, t_size sourceSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
509 m_content.set_data_fromptr(reinterpret_cast<const t_uint8*>(source), sourceSize);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 onContentChange();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512 template<typename TSource> void set_data(const TSource & source) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513 m_content = source;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514 onContentChange();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
515 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
516 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
517 void onContentChange() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
518 stream_reader_formatter_simple_ref<BE>::set_data(m_content);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
519 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
520 pfc::array_t<t_uint8> m_content;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
521 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
522
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
523
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
524
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
525
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
526
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
527
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
528 template<bool isBigEndian> class _stream_reader_formatter_translator {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
529 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
530 _stream_reader_formatter_translator(stream_reader_formatter<isBigEndian> & stream) : m_stream(stream) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
531 typedef _stream_reader_formatter_translator<isBigEndian> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
532 template<typename t_what> t_self & operator||(t_what & out) {m_stream >> out; return *this;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
533 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
534 stream_reader_formatter<isBigEndian> & m_stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
535 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
536 template<bool isBigEndian> class _stream_writer_formatter_translator {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
537 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
538 _stream_writer_formatter_translator(stream_writer_formatter<isBigEndian> & stream) : m_stream(stream) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
539 typedef _stream_writer_formatter_translator<isBigEndian> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
540 template<typename t_what> t_self & operator||(const t_what & in) {m_stream << in; return *this;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
541 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
542 stream_writer_formatter<isBigEndian> & m_stream;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
543 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
544
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
545 #define FB2K_STREAM_RECORD_OVERLOAD(type, code) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
546 FB2K_STREAM_READER_OVERLOAD(type) { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
547 _stream_reader_formatter_translator<isBigEndian> streamEx(stream); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
548 streamEx || code; \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
549 return stream; \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
550 } \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
551 FB2K_STREAM_WRITER_OVERLOAD(type) { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
552 _stream_writer_formatter_translator<isBigEndian> streamEx(stream); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
553 streamEx || code; \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
554 return stream; \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
555 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
556
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
557
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
558
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
559
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
560 #define FB2K_RETRY_ON_EXCEPTION(OP, ABORT, TIMEOUT, EXCEPTION) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
561 { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
562 pfc::lores_timer timer; timer.start(); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
563 for(;;) { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
564 try { {OP;} break; } \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
565 catch(const EXCEPTION &) { if (timer.query() > TIMEOUT) throw;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
566 ABORT.sleep(0.05); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
567 } \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
568 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
569
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
570 #define FB2K_RETRY_ON_EXCEPTION2(OP, ABORT, TIMEOUT, EXCEPTION1, EXCEPTION2) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
571 { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
572 pfc::lores_timer timer; timer.start(); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
573 for(;;) { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
574 try { {OP;} break; } \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
575 catch(const EXCEPTION1 &) { if (timer.query() > TIMEOUT) throw;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
576 catch(const EXCEPTION2 &) { if (timer.query() > TIMEOUT) throw;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
577 ABORT.sleep(0.05); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
578 } \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
579 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
580
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
581 #define FB2K_RETRY_ON_EXCEPTION3(OP, ABORT, TIMEOUT, EXCEPTION1, EXCEPTION2, EXCEPTION3) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
582 { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
583 pfc::lores_timer timer; timer.start(); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
584 for(;;) { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
585 try { {OP;} break; } \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
586 catch(const EXCEPTION1 &) { if (timer.query() > TIMEOUT) throw;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
587 catch(const EXCEPTION2 &) { if (timer.query() > TIMEOUT) throw;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
588 catch(const EXCEPTION3 &) { if (timer.query() > TIMEOUT) throw;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
589 ABORT.sleep(0.05); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
590 } \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
591 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
592
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
593 #define FB2K_RETRY_ON_SHARING_VIOLATION(OP, ABORT, TIMEOUT) FB2K_RETRY_ON_EXCEPTION(OP, ABORT, TIMEOUT, exception_io_sharing_violation)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
594
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
595 // **** WINDOWS SUCKS ****
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
596 // File move ops must be retried on all these because you get access-denied when someone is holding open handles to something you're trying to move, or already-exists on something you just told Windows to move away
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
597 #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)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
598
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
599 class fileRestorePositionScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
600 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
601 fileRestorePositionScope(file::ptr f, abort_callback & a) : m_file(f), m_abort(a) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
602 m_offset = f->get_position(a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
603 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
604 ~fileRestorePositionScope() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
605 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
606 if (!m_abort.is_aborting()) m_file->seek(m_offset, m_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
607 } catch(...) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
608 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
609 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
610 file::ptr m_file;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
611 t_filesize m_offset;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
612 abort_callback & m_abort;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
613 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
614
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
615
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
616 //! Debug self-test function for testing a file object implementation, performs various behavior validity checks, random access etc. Output goes to fb2k console.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
617 //! Returns true on success, false on failure (buggy file object implementation).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
618 bool fb2kFileSelfTest(file::ptr f, abort_callback & aborter);