readerwriter.h 8.4 KB

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