crtimpl.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * Copyright 2010-2016 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  4. */
  5. #ifndef BX_CRTIMPL_H_HEADER_GUARD
  6. #define BX_CRTIMPL_H_HEADER_GUARD
  7. #if BX_CONFIG_ALLOCATOR_CRT
  8. # include <malloc.h>
  9. # include "allocator.h"
  10. #endif // BX_CONFIG_ALLOCATOR_CRT
  11. #if BX_CONFIG_CRT_FILE_READER_WRITER
  12. # include "readerwriter.h"
  13. #endif // BX_CONFIG_CRT_FILE_READER_WRITER
  14. namespace bx
  15. {
  16. #if BX_CONFIG_ALLOCATOR_CRT
  17. class CrtAllocator : public AllocatorI
  18. {
  19. public:
  20. CrtAllocator()
  21. {
  22. }
  23. virtual ~CrtAllocator()
  24. {
  25. }
  26. virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  27. {
  28. if (0 == _size)
  29. {
  30. if (NULL != _ptr)
  31. {
  32. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  33. {
  34. ::free(_ptr);
  35. return NULL;
  36. }
  37. # if BX_COMPILER_MSVC
  38. BX_UNUSED(_file, _line);
  39. _aligned_free(_ptr);
  40. # else
  41. bx::alignedFree(this, _ptr, _align, _file, _line);
  42. # endif // BX_
  43. }
  44. return NULL;
  45. }
  46. else if (NULL == _ptr)
  47. {
  48. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  49. {
  50. return ::malloc(_size);
  51. }
  52. # if BX_COMPILER_MSVC
  53. BX_UNUSED(_file, _line);
  54. return _aligned_malloc(_size, _align);
  55. # else
  56. return bx::alignedAlloc(this, _size, _align, _file, _line);
  57. # endif // BX_
  58. }
  59. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  60. {
  61. return ::realloc(_ptr, _size);
  62. }
  63. # if BX_COMPILER_MSVC
  64. BX_UNUSED(_file, _line);
  65. return _aligned_realloc(_ptr, _size, _align);
  66. # else
  67. return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line);
  68. # endif // BX_
  69. }
  70. };
  71. #endif // BX_CONFIG_ALLOCATOR_CRT
  72. #if BX_CONFIG_CRT_FILE_READER_WRITER
  73. class CrtFileReader : public FileReaderI
  74. {
  75. public:
  76. CrtFileReader()
  77. : m_file(NULL)
  78. {
  79. }
  80. virtual ~CrtFileReader()
  81. {
  82. }
  83. virtual bool open(const char* _filePath, Error* _err) BX_OVERRIDE
  84. {
  85. BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
  86. m_file = fopen(_filePath, "rb");
  87. if (NULL == m_file)
  88. {
  89. BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileReader: Failed to open file.");
  90. return false;
  91. }
  92. return true;
  93. }
  94. virtual void close() BX_OVERRIDE
  95. {
  96. fclose(m_file);
  97. }
  98. virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
  99. {
  100. fseeko64(m_file, _offset, _whence);
  101. return ftello64(m_file);
  102. }
  103. virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE
  104. {
  105. BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
  106. int32_t size = (int32_t)fread(_data, 1, _size, m_file);
  107. if (size != _size)
  108. {
  109. BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "CrtFileReader: read failed.");
  110. return size >= 0 ? size : 0;
  111. }
  112. return size;
  113. }
  114. private:
  115. FILE* m_file;
  116. };
  117. class CrtFileWriter : public FileWriterI
  118. {
  119. public:
  120. CrtFileWriter()
  121. : m_file(NULL)
  122. {
  123. }
  124. virtual ~CrtFileWriter()
  125. {
  126. }
  127. virtual bool open(const char* _filePath, bool _append, Error* _err) BX_OVERRIDE
  128. {
  129. m_file = fopen(_filePath, _append ? "ab" : "wb");
  130. if (NULL == m_file)
  131. {
  132. BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileWriter: Failed to open file.");
  133. return false;
  134. }
  135. return true;
  136. }
  137. virtual void close() BX_OVERRIDE
  138. {
  139. fclose(m_file);
  140. }
  141. virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) BX_OVERRIDE
  142. {
  143. fseeko64(m_file, _offset, _whence);
  144. return ftello64(m_file);
  145. }
  146. virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE
  147. {
  148. BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
  149. int32_t size = (int32_t)fwrite(_data, 1, _size, m_file);
  150. if (size != _size)
  151. {
  152. BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "CrtFileWriter: write failed.");
  153. return size >= 0 ? size : 0;
  154. }
  155. return size;
  156. }
  157. private:
  158. FILE* m_file;
  159. };
  160. #endif // BX_CONFIG_CRT_FILE_READER_WRITER
  161. #if BX_CONFIG_CRT_PROCESS
  162. #if BX_CRT_MSVC
  163. # define popen _popen
  164. # define pclose _pclose
  165. #endif // BX_CRT_MSVC
  166. class ProcessReader : public ReaderOpenI, public CloserI, public ReaderI
  167. {
  168. public:
  169. ProcessReader()
  170. : m_file(NULL)
  171. {
  172. }
  173. ~ProcessReader()
  174. {
  175. BX_CHECK(NULL == m_file, "Process not closed!");
  176. }
  177. virtual bool open(const char* _command, Error* _err) BX_OVERRIDE
  178. {
  179. BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
  180. m_file = popen(_command, "r");
  181. if (NULL == m_file)
  182. {
  183. BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process.");
  184. return false;
  185. }
  186. return true;
  187. }
  188. virtual void close() BX_OVERRIDE
  189. {
  190. BX_CHECK(NULL != m_file, "Process not open!");
  191. pclose(m_file);
  192. m_file = NULL;
  193. }
  194. virtual int32_t read(void* _data, int32_t _size, Error* _err) BX_OVERRIDE
  195. {
  196. BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
  197. int32_t size = (int32_t)fread(_data, 1, _size, m_file);
  198. if (size != _size)
  199. {
  200. return size >= 0 ? size : 0;
  201. }
  202. return size;
  203. }
  204. private:
  205. FILE* m_file;
  206. };
  207. class ProcessWriter : public WriterOpenI, public CloserI, public WriterI
  208. {
  209. public:
  210. ProcessWriter()
  211. : m_file(NULL)
  212. {
  213. }
  214. ~ProcessWriter()
  215. {
  216. BX_CHECK(NULL == m_file, "Process not closed!");
  217. }
  218. virtual bool open(const char* _command, bool, Error* _err) BX_OVERRIDE
  219. {
  220. BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
  221. m_file = popen(_command, "w");
  222. if (NULL == m_file)
  223. {
  224. BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process.");
  225. return false;
  226. }
  227. return true;
  228. }
  229. virtual void close() BX_OVERRIDE
  230. {
  231. BX_CHECK(NULL != m_file, "Process not open!");
  232. pclose(m_file);
  233. m_file = NULL;
  234. }
  235. virtual int32_t write(const void* _data, int32_t _size, Error* _err) BX_OVERRIDE
  236. {
  237. BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
  238. int32_t size = (int32_t)fwrite(_data, 1, _size, m_file);
  239. if (size != _size)
  240. {
  241. return size >= 0 ? size : 0;
  242. }
  243. return size;
  244. }
  245. private:
  246. FILE* m_file;
  247. };
  248. #endif // BX_CONFIG_CRT_PROCESS
  249. } // namespace bx
  250. #endif // BX_CRTIMPL_H_HEADER_GUARD