1 /*
2  * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
3  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
4  */
5 
6 #ifndef BX_READERWRITER_H_HEADER_GUARD
7 #define BX_READERWRITER_H_HEADER_GUARD
8 
9 #include "allocator.h"
10 #include "endian.h"
11 #include "error.h"
12 #include "filepath.h"
13 #include "math.h"
14 #include "string.h"
15 #include "uint32_t.h"
16 
17 BX_ERROR_RESULT(BX_ERROR_READERWRITER_OPEN,         BX_MAKEFOURCC('R', 'W', 0, 1) );
18 BX_ERROR_RESULT(BX_ERROR_READERWRITER_READ,         BX_MAKEFOURCC('R', 'W', 0, 2) );
19 BX_ERROR_RESULT(BX_ERROR_READERWRITER_WRITE,        BX_MAKEFOURCC('R', 'W', 0, 3) );
20 BX_ERROR_RESULT(BX_ERROR_READERWRITER_EOF,          BX_MAKEFOURCC('R', 'W', 0, 4) );
21 BX_ERROR_RESULT(BX_ERROR_READERWRITER_ALREADY_OPEN, BX_MAKEFOURCC('R', 'W', 0, 5) );
22 
23 namespace bx
24 {
25 	/// The position from where offset is added.
26 	struct Whence
27 	{
28 		/// Whence values:
29 		enum Enum
30 		{
31 			Begin,   //!< From begining of file.
32 			Current, //!< From current position of file.
33 			End,     //!< From end of file.
34 		};
35 	};
36 
37 	/// Reader interface.
38 	struct BX_NO_VTABLE ReaderI
39 	{
40 		///
41 		virtual ~ReaderI() = 0;
42 
43 		///
44 		virtual int32_t read(void* _data, int32_t _size, Error* _err) = 0;
45 	};
46 
47 	/// Writer interface.
48 	struct BX_NO_VTABLE WriterI
49 	{
50 		///
51 		virtual ~WriterI() = 0;
52 
53 		///
54 		virtual int32_t write(const void* _data, int32_t _size, Error* _err) = 0;
55 	};
56 
57 	/// Seeker interface.
58 	struct BX_NO_VTABLE SeekerI
59 	{
60 		///
61 		virtual ~SeekerI() = 0;
62 
63 		///
64 		virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) = 0;
65 	};
66 
67 	/// Reader seeker interface.
68 	struct BX_NO_VTABLE ReaderSeekerI : public ReaderI, public SeekerI
69 	{
70 	};
71 
72 	/// Writer seeker interface.
73 	struct BX_NO_VTABLE WriterSeekerI : public WriterI, public SeekerI
74 	{
75 	};
76 
77 	/// Open for reading interface.
78 	struct BX_NO_VTABLE ReaderOpenI
79 	{
80 		///
81 		virtual ~ReaderOpenI() = 0;
82 
83 		///
84 		virtual bool open(const FilePath& _filePath, Error* _err) = 0;
85 	};
86 
87 	/// Open for writing interface.
88 	struct BX_NO_VTABLE WriterOpenI
89 	{
90 		///
91 		virtual ~WriterOpenI() = 0;
92 
93 		///
94 		virtual bool open(const FilePath& _filePath, bool _append, Error* _err) = 0;
95 	};
96 
97 	/// Open process interface.
98 	struct BX_NO_VTABLE ProcessOpenI
99 	{
100 		///
101 		virtual ~ProcessOpenI() = 0;
102 
103 		///
104 		virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) = 0;
105 	};
106 
107 	/// Closer interface.
108 	struct BX_NO_VTABLE CloserI
109 	{
110 		///
111 		virtual ~CloserI() = 0;
112 
113 		///
114 		virtual void close() = 0;
115 	};
116 
117 	/// File reader interface.
118 	struct BX_NO_VTABLE FileReaderI : public ReaderOpenI, public CloserI, public ReaderSeekerI
119 	{
120 	};
121 
122 	/// File writer interface.
123 	struct BX_NO_VTABLE FileWriterI : public WriterOpenI, public CloserI, public WriterSeekerI
124 	{
125 	};
126 
127 	/// Memory block interface.
128 	struct BX_NO_VTABLE MemoryBlockI
129 	{
130 		virtual void* more(uint32_t _size = 0) = 0;
131 		virtual uint32_t getSize() = 0;
132 	};
133 
134 	/// Static memory block interface.
135 	class StaticMemoryBlock : public MemoryBlockI
136 	{
137 	public:
138 		///
139 		StaticMemoryBlock(void* _data, uint32_t _size);
140 
141 		///
142 		virtual ~StaticMemoryBlock();
143 
144 		///
145 		virtual void* more(uint32_t _size = 0) override;
146 
147 		///
148 		virtual uint32_t getSize() override;
149 
150 	private:
151 		void*    m_data;
152 		uint32_t m_size;
153 	};
154 
155 	/// Memory block.
156 	class MemoryBlock : public MemoryBlockI
157 	{
158 	public:
159 		///
160 		MemoryBlock(AllocatorI* _allocator);
161 
162 		///
163 		virtual ~MemoryBlock();
164 
165 		///
166 		virtual void* more(uint32_t _size = 0) override;
167 
168 		///
169 		virtual uint32_t getSize() override;
170 
171 	private:
172 		AllocatorI* m_allocator;
173 		void*       m_data;
174 		uint32_t    m_size;
175 	};
176 
177 	/// Sizer writer. Dummy writter that only counts number of bytes written into it.
178 	class SizerWriter : public WriterSeekerI
179 	{
180 	public:
181 		///
182 		SizerWriter();
183 
184 		///
185 		virtual ~SizerWriter();
186 
187 		///
188 		virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override;
189 
190 		///
191 		virtual int32_t write(const void* /*_data*/, int32_t _size, Error* _err) override;
192 
193 	private:
194 		int64_t m_pos;
195 		int64_t m_top;
196 	};
197 
198 	/// Memory reader.
199 	class MemoryReader : public ReaderSeekerI
200 	{
201 	public:
202 		///
203 		MemoryReader(const void* _data, uint32_t _size);
204 
205 		///
206 		virtual ~MemoryReader();
207 
208 		///
209 		virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override;
210 
211 		///
212 		virtual int32_t read(void* _data, int32_t _size, Error* _err) override;
213 
214 		///
215 		const uint8_t* getDataPtr() const;
216 
217 		///
218 		int64_t getPos() const;
219 
220 		///
221 		int64_t remaining() const;
222 
223 	private:
224 		const uint8_t* m_data;
225 		int64_t m_pos;
226 		int64_t m_top;
227 	};
228 
229 	/// Memory writer.
230 	class MemoryWriter : public WriterSeekerI
231 	{
232 	public:
233 		///
234 		MemoryWriter(MemoryBlockI* _memBlock);
235 
236 		///
237 		virtual ~MemoryWriter();
238 
239 		///
240 		virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) override;
241 
242 		///
243 		virtual int32_t write(const void* _data, int32_t _size, Error* _err) override;
244 
245 	private:
246 		MemoryBlockI* m_memBlock;
247 		uint8_t* m_data;
248 		int64_t  m_pos;
249 		int64_t  m_top;
250 		int64_t  m_size;
251 	};
252 
253 	/// Static (fixed size) memory block writer.
254 	class StaticMemoryBlockWriter : public MemoryWriter
255 	{
256 	public:
257 		///
258 		StaticMemoryBlockWriter(void* _data, uint32_t _size);
259 
260 		///
261 		virtual ~StaticMemoryBlockWriter();
262 
263 	private:
264 		StaticMemoryBlock m_smb;
265 	};
266 
267 	/// Read data.
268 	int32_t read(ReaderI* _reader, void* _data, int32_t _size, Error* _err = NULL);
269 
270 	/// Read value.
271 	template<typename Ty>
272 	int32_t read(ReaderI* _reader, Ty& _value, Error* _err = NULL);
273 
274 	/// Read value and converts it to host endianess. _fromLittleEndian specifies
275 	/// underlying stream endianess.
276 	template<typename Ty>
277 	int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err = NULL);
278 
279 	/// Write data.
280 	int32_t write(WriterI* _writer, const void* _data, int32_t _size, Error* _err = NULL);
281 
282 	/// Write C string.
283 	int32_t write(WriterI* _writer, const char* _str, Error* _err = NULL);
284 
285 	/// Write string view.
286 	int32_t write(WriterI* _writer, const StringView& _str, Error* _err = NULL);
287 
288 	/// Write formated string.
289 	int32_t write(WriterI* _writer, const StringView& _format, va_list _argList, Error* _err);
290 
291 	/// Write formated string.
292 	int32_t write(WriterI* _writer, Error* _err, const StringView* _format, ...);
293 
294 	/// Write formated string.
295 	int32_t write(WriterI* _writer, Error* _err, const char* _format, ...);
296 
297 	/// Write repeat the same value.
298 	int32_t writeRep(WriterI* _writer, uint8_t _byte, int32_t _size, Error* _err = NULL);
299 
300 	/// Write value.
301 	template<typename Ty>
302 	int32_t write(WriterI* _writer, const Ty& _value, Error* _err = NULL);
303 
304 	/// Write value as little endian.
305 	template<typename Ty>
306 	int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err = NULL);
307 
308 	/// Write value as big endian.
309 	template<typename Ty>
310 	int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err = NULL);
311 
312 	/// Skip _offset bytes forward.
313 	int64_t skip(SeekerI* _seeker, int64_t _offset);
314 
315 	/// Seek to any position in file.
316 	int64_t seek(SeekerI* _seeker, int64_t _offset = 0, Whence::Enum _whence = Whence::Current);
317 
318 	/// Returns size of file.
319 	int64_t getSize(SeekerI* _seeker);
320 
321 	/// Returns remaining size from current offset of file.
322 	int64_t getRemain(SeekerI* _seeker);
323 
324 	/// Peek data.
325 	int32_t peek(ReaderSeekerI* _reader, void* _data, int32_t _size, Error* _err = NULL);
326 
327 	/// Peek value.
328 	template<typename Ty>
329 	int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err = NULL);
330 
331 	/// Align reader stream.
332 	int32_t align(ReaderSeekerI* _reader, uint32_t _alignment, Error* _err = NULL);
333 
334 	/// Align writer stream (pads stream with zeros).
335 	int32_t align(WriterSeekerI* _writer, uint32_t _alignment, Error* _err = NULL);
336 
337 	/// Open for read.
338 	bool open(ReaderOpenI* _reader, const FilePath& _filePath, Error* _err = NULL);
339 
340 	/// Open fro write.
341 	bool open(WriterOpenI* _writer, const FilePath& _filePath, bool _append = false, Error* _err = NULL);
342 
343 	/// Open process.
344 	bool open(ProcessOpenI* _process, const FilePath& _filePath, const StringView& _args, Error* _err = NULL);
345 
346 	/// Close.
347 	void close(CloserI* _reader);
348 
349 } // namespace bx
350 
351 #include "inline/readerwriter.inl"
352 
353 #endif // BX_READERWRITER_H_HEADER_GUARD
354