readerwriter.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /*
  2. * Copyright 2010-2013 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #ifndef BX_READERWRITER_H_HEADER_GUARD
  6. #define BX_READERWRITER_H_HEADER_GUARD
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "bx.h"
  10. #include "uint32_t.h"
  11. #if BX_COMPILER_MSVC
  12. # define fseeko64 _fseeki64
  13. # define ftello64 _ftelli64
  14. #elif BX_PLATFORM_ANDROID|BX_PLATFORM_IOS|BX_PLATFORM_OSX|BX_PLATFORM_QNX
  15. # define fseeko64 fseeko
  16. # define ftello64 ftello
  17. #endif // BX_
  18. namespace bx
  19. {
  20. struct Whence
  21. {
  22. enum Enum
  23. {
  24. Begin,
  25. Current,
  26. End,
  27. };
  28. };
  29. struct BX_NO_VTABLE ReaderI
  30. {
  31. virtual ~ReaderI() = 0;
  32. virtual int32_t read(void* _data, int32_t _size) = 0;
  33. };
  34. inline ReaderI::~ReaderI()
  35. {
  36. }
  37. struct BX_NO_VTABLE WriterI
  38. {
  39. virtual ~WriterI() = 0;
  40. virtual int32_t write(const void* _data, int32_t _size) = 0;
  41. };
  42. inline WriterI::~WriterI()
  43. {
  44. }
  45. struct BX_NO_VTABLE SeekerI
  46. {
  47. virtual ~SeekerI() = 0;
  48. virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) = 0;
  49. };
  50. inline SeekerI::~SeekerI()
  51. {
  52. }
  53. /// Read data.
  54. inline int32_t read(ReaderI* _reader, void* _data, int32_t _size)
  55. {
  56. return _reader->read(_data, _size);
  57. }
  58. /// Write value.
  59. template<typename Ty>
  60. inline int32_t read(ReaderI* _reader, Ty& _value)
  61. {
  62. return _reader->read(&_value, sizeof(Ty) );
  63. }
  64. /// Read value and converts it to host endianess. _fromLittleEndian specifies
  65. /// underlying stream endianess.
  66. template<typename Ty>
  67. inline int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian)
  68. {
  69. Ty value;
  70. int32_t result = _reader->read(&value, sizeof(Ty) );
  71. _value = toHostEndian(value, _fromLittleEndian);
  72. return result;
  73. }
  74. /// Write data.
  75. inline int32_t write(WriterI* _writer, const void* _data, int32_t _size)
  76. {
  77. return _writer->write(_data, _size);
  78. }
  79. /// Write value.
  80. template<typename Ty>
  81. inline int32_t write(WriterI* _writer, const Ty& _value)
  82. {
  83. return _writer->write(&_value, sizeof(Ty) );
  84. }
  85. /// Write value as little endian.
  86. template<typename Ty>
  87. inline int32_t writeLE(WriterI* _writer, const Ty& _value)
  88. {
  89. Ty value = toLittleEndian(_value);
  90. int32_t result = _writer->write(&value, sizeof(Ty) );
  91. return result;
  92. }
  93. /// Write value as big endian.
  94. template<typename Ty>
  95. inline int32_t writeBE(WriterI* _writer, const Ty& _value)
  96. {
  97. Ty value = toBigEndian(_value);
  98. int32_t result = _writer->write(&value, sizeof(Ty) );
  99. return result;
  100. }
  101. inline int64_t skip(SeekerI* _seeker, int64_t _offset)
  102. {
  103. return _seeker->seek(_offset, Whence::Current);
  104. }
  105. inline int64_t getSize(SeekerI* _seeker)
  106. {
  107. int64_t offset = _seeker->seek();
  108. int64_t size = _seeker->seek(0, Whence::End);
  109. _seeker->seek(offset, Whence::Begin);
  110. return size;
  111. }
  112. struct BX_NO_VTABLE ReaderSeekerI : public ReaderI, public SeekerI
  113. {
  114. };
  115. struct BX_NO_VTABLE WriterSeekerI : public WriterI, public SeekerI
  116. {
  117. };
  118. struct BX_NO_VTABLE FileReaderI : public ReaderSeekerI
  119. {
  120. virtual int32_t open(const char* _filePath) = 0;
  121. virtual int32_t close() = 0;
  122. };
  123. struct BX_NO_VTABLE FileWriterI : public WriterSeekerI
  124. {
  125. virtual int32_t open(const char* _filePath, bool _append = false) = 0;
  126. virtual int32_t close() = 0;
  127. };
  128. inline int32_t open(FileReaderI* _reader, const char* _filePath)
  129. {
  130. return _reader->open(_filePath);
  131. }
  132. inline int32_t close(FileReaderI* _reader)
  133. {
  134. return _reader->close();
  135. }
  136. inline int32_t open(FileWriterI* _writer, const char* _filePath, bool _append = false)
  137. {
  138. return _writer->open(_filePath, _append);
  139. }
  140. inline int32_t close(FileWriterI* _writer)
  141. {
  142. return _writer->close();
  143. }
  144. struct BX_NO_VTABLE MemoryBlockI
  145. {
  146. virtual void* more(uint32_t _size = 0) = 0;
  147. virtual uint32_t getSize() = 0;
  148. };
  149. class StaticMemoryBlock : public MemoryBlockI
  150. {
  151. public:
  152. StaticMemoryBlock(void* _data, uint32_t _size)
  153. : m_data(_data)
  154. , m_size(_size)
  155. {
  156. }
  157. virtual ~StaticMemoryBlock()
  158. {
  159. }
  160. virtual void* more(uint32_t /*_size*/ = 0) BX_OVERRIDE
  161. {
  162. return m_data;
  163. }
  164. virtual uint32_t getSize() BX_OVERRIDE
  165. {
  166. return m_size;
  167. }
  168. private:
  169. void* m_data;
  170. uint32_t m_size;
  171. };
  172. inline int64_t int64_min(int64_t _a, int64_t _b)
  173. {
  174. return _a < _b ? _a : _b;
  175. }
  176. inline int64_t int64_max(int64_t _a, int64_t _b)
  177. {
  178. return _a > _b ? _a : _b;
  179. }
  180. inline int64_t int64_clamp(int64_t _a, int64_t _min, int64_t _max)
  181. {
  182. const int64_t min = int64_min(_a, _max);
  183. const int64_t result = int64_max(_min, min);
  184. return result;
  185. }
  186. class SizerWriter : public WriterSeekerI
  187. {
  188. public:
  189. SizerWriter()
  190. : m_pos(0)
  191. , m_top(0)
  192. {
  193. }
  194. virtual ~SizerWriter()
  195. {
  196. }
  197. virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
  198. {
  199. switch (_whence)
  200. {
  201. case Whence::Begin:
  202. m_pos = _offset;
  203. break;
  204. case Whence::Current:
  205. m_pos = int64_clamp(m_pos + _offset, 0, m_top);
  206. break;
  207. case Whence::End:
  208. m_pos = int64_clamp(m_top - _offset, 0, m_top);
  209. break;
  210. }
  211. return m_pos;
  212. }
  213. virtual int32_t write(const void* /*_data*/, int32_t _size) BX_OVERRIDE
  214. {
  215. int32_t morecore = int32_t(m_pos - m_top) + _size;
  216. if (0 < morecore)
  217. {
  218. m_top += morecore;
  219. }
  220. int64_t reminder = m_top-m_pos;
  221. int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) );
  222. m_pos += size;
  223. return size;
  224. }
  225. private:
  226. int64_t m_pos;
  227. int64_t m_top;
  228. };
  229. class MemoryReader : public ReaderSeekerI
  230. {
  231. public:
  232. MemoryReader(const void* _data, uint32_t _size)
  233. : m_data( (const uint8_t*)_data)
  234. , m_pos(0)
  235. , m_top(_size)
  236. {
  237. }
  238. virtual ~MemoryReader()
  239. {
  240. }
  241. virtual int64_t seek(int64_t _offset, Whence::Enum _whence) BX_OVERRIDE
  242. {
  243. switch (_whence)
  244. {
  245. case Whence::Begin:
  246. m_pos = _offset;
  247. break;
  248. case Whence::Current:
  249. m_pos = int64_clamp(m_pos + _offset, 0, m_top);
  250. break;
  251. case Whence::End:
  252. m_pos = int64_clamp(m_top - _offset, 0, m_top);
  253. break;
  254. }
  255. return m_pos;
  256. }
  257. virtual int32_t read(void* _data, int32_t _size) BX_OVERRIDE
  258. {
  259. int64_t reminder = m_top-m_pos;
  260. int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) );
  261. memcpy(_data, &m_data[m_pos], size);
  262. m_pos += size;
  263. return size;
  264. }
  265. const uint8_t* getDataPtr() const
  266. {
  267. return &m_data[m_pos];
  268. }
  269. int64_t getPos() const
  270. {
  271. return m_pos;
  272. }
  273. int64_t remaining() const
  274. {
  275. return m_top-m_pos;
  276. }
  277. private:
  278. const uint8_t* m_data;
  279. int64_t m_pos;
  280. int64_t m_top;
  281. };
  282. class MemoryWriter : public WriterSeekerI
  283. {
  284. public:
  285. MemoryWriter(MemoryBlockI* _memBlock)
  286. : m_memBlock(_memBlock)
  287. , m_data(NULL)
  288. , m_pos(0)
  289. , m_top(0)
  290. , m_size(0)
  291. {
  292. }
  293. virtual ~MemoryWriter()
  294. {
  295. }
  296. virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
  297. {
  298. switch (_whence)
  299. {
  300. case Whence::Begin:
  301. m_pos = _offset;
  302. break;
  303. case Whence::Current:
  304. m_pos = int64_clamp(m_pos + _offset, 0, m_top);
  305. break;
  306. case Whence::End:
  307. m_pos = int64_clamp(m_top - _offset, 0, m_top);
  308. break;
  309. }
  310. return m_pos;
  311. }
  312. virtual int32_t write(const void* _data, int32_t _size) BX_OVERRIDE
  313. {
  314. int32_t morecore = int32_t(m_pos - m_size) + _size;
  315. if (0 < morecore)
  316. {
  317. morecore = BX_ALIGN_MASK(morecore, 0xfff);
  318. m_data = (uint8_t*)m_memBlock->more(morecore);
  319. m_size = m_memBlock->getSize();
  320. }
  321. int64_t reminder = m_size-m_pos;
  322. int32_t size = uint32_min(_size, int32_t(reminder > INT32_MAX ? INT32_MAX : reminder) );
  323. memcpy(&m_data[m_pos], _data, size);
  324. m_pos += size;
  325. m_top = int64_max(m_top, m_pos);
  326. return size;
  327. }
  328. private:
  329. MemoryBlockI* m_memBlock;
  330. uint8_t* m_data;
  331. int64_t m_pos;
  332. int64_t m_top;
  333. int64_t m_size;
  334. };
  335. class StaticMemoryBlockWriter : public MemoryWriter
  336. {
  337. public:
  338. StaticMemoryBlockWriter(void* _data, uint32_t _size)
  339. : MemoryWriter(&m_smb)
  340. , m_smb(_data, _size)
  341. {
  342. }
  343. ~StaticMemoryBlockWriter()
  344. {
  345. }
  346. private:
  347. StaticMemoryBlock m_smb;
  348. };
  349. #if BX_CONFIG_CRT_FILE_READER_WRITER
  350. class CrtFileReader : public FileReaderI
  351. {
  352. public:
  353. CrtFileReader()
  354. : m_file(NULL)
  355. {
  356. }
  357. virtual ~CrtFileReader()
  358. {
  359. }
  360. virtual int32_t open(const char* _filePath) BX_OVERRIDE
  361. {
  362. m_file = fopen(_filePath, "rb");
  363. return NULL == m_file;
  364. }
  365. virtual int32_t close() BX_OVERRIDE
  366. {
  367. fclose(m_file);
  368. return 0;
  369. }
  370. virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
  371. {
  372. fseeko64(m_file, _offset, _whence);
  373. return ftello64(m_file);
  374. }
  375. virtual int32_t read(void* _data, int32_t _size) BX_OVERRIDE
  376. {
  377. return (int32_t)fread(_data, 1, _size, m_file);
  378. }
  379. private:
  380. FILE* m_file;
  381. };
  382. class CrtFileWriter : public FileWriterI
  383. {
  384. public:
  385. CrtFileWriter()
  386. : m_file(NULL)
  387. {
  388. }
  389. virtual ~CrtFileWriter()
  390. {
  391. }
  392. virtual int32_t open(const char* _filePath, bool _append = false) BX_OVERRIDE
  393. {
  394. if (_append)
  395. {
  396. m_file = fopen(_filePath, "ab");
  397. }
  398. else
  399. {
  400. m_file = fopen(_filePath, "wb");
  401. }
  402. return NULL == m_file;
  403. }
  404. virtual int32_t close() BX_OVERRIDE
  405. {
  406. fclose(m_file);
  407. return 0;
  408. }
  409. virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
  410. {
  411. fseeko64(m_file, _offset, _whence);
  412. return ftello64(m_file);
  413. }
  414. virtual int32_t write(const void* _data, int32_t _size) BX_OVERRIDE
  415. {
  416. return (int32_t)fwrite(_data, 1, _size, m_file);
  417. }
  418. private:
  419. FILE* m_file;
  420. };
  421. #endif // BX_CONFIG_CRT_FILE_READER_WRITER
  422. } // namespace bx
  423. #endif // BX_READERWRITER_H_HEADER_GUARD