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