BsDataStream.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #pragma once
  2. #include "BsPrerequisitesUtil.h"
  3. #include <istream>
  4. namespace BansheeEngine
  5. {
  6. /**
  7. * @brief General purpose class used for encapsulating the reading and writing of data from
  8. * and to various sources using a common interface.
  9. */
  10. class BS_UTILITY_EXPORT DataStream
  11. {
  12. public:
  13. enum AccessMode
  14. {
  15. READ = 1,
  16. WRITE = 2
  17. };
  18. public:
  19. /**
  20. * @brief Creates an unnamed stream.
  21. */
  22. DataStream(UINT16 accessMode = READ)
  23. :mSize(0), mAccess(accessMode)
  24. { }
  25. /**
  26. * @brief Creates a named stream.
  27. */
  28. DataStream(const String& name, UINT16 accessMode = READ)
  29. :mName(name), mSize(0), mAccess(accessMode) {}
  30. virtual ~DataStream() {}
  31. const String& getName(void) { return mName; }
  32. UINT16 getAccessMode() const { return mAccess; }
  33. virtual bool isReadable() const { return (mAccess & READ) != 0; }
  34. virtual bool isWriteable() const { return (mAccess & WRITE) != 0; }
  35. /**
  36. * @brief Reads data from the buffer and copies it to the specified value.
  37. */
  38. template<typename T> DataStream& operator>>(T& val);
  39. /**
  40. * @brief Read the requisite number of bytes from the stream,
  41. * stopping at the end of the file.
  42. *
  43. * @param buf Pre-allocated buffer to read the data into.
  44. * @param count Number of bytes to read.
  45. *
  46. * @return Number of bytes actually read.
  47. *
  48. * @note Stream must be created with READ access mode.
  49. */
  50. virtual size_t read(void* buf, size_t count) = 0;
  51. /**
  52. * @brief Write the requisite number of bytes to the stream.
  53. *
  54. * @param buf Buffer containing bytes to write.
  55. * @param count Number of bytes to write.
  56. *
  57. * @return Number of bytes actually written.
  58. *
  59. * @note Stream must be created with WRITE access mode.
  60. */
  61. virtual size_t write(const void* buf, size_t count) { return 0; }
  62. /**
  63. * @brief Returns a string containing the entire stream.
  64. *
  65. * @note This is a convenience method for text streams only, allowing you to
  66. * retrieve a String object containing all the data in the stream.
  67. */
  68. virtual String getAsString();
  69. /**
  70. * @brief Returns a wide string containing the entire stream.
  71. *
  72. * @note This is a convenience method for text streams only, allowing you to
  73. * retrieve a WString object containing all the data in the stream.
  74. */
  75. virtual WString getAsWString();
  76. /**
  77. * @brief Skip a defined number of bytes. This can also be a negative value, in which case
  78. * the file pointer rewinds a defined number of bytes.
  79. */
  80. virtual void skip(size_t count) = 0;
  81. /**
  82. * @brief Repositions the read point to a specified byte.
  83. */
  84. virtual void seek(size_t pos) = 0;
  85. /**
  86. * @brief Returns the current byte offset from beginning
  87. */
  88. virtual size_t tell() const = 0;
  89. /**
  90. * @brief Returns true if the stream has reached the end.
  91. */
  92. virtual bool eof() const = 0;
  93. /**
  94. * @brief Returns the total size of the data to be read from the stream,
  95. * or 0 if this is indeterminate for this stream.
  96. */
  97. size_t size() const { return mSize; }
  98. /**
  99. * @brief Close the stream. This makes further operations invalid.
  100. */
  101. virtual void close() = 0;
  102. protected:
  103. static const UINT32 StreamTempSize;
  104. String mName;
  105. size_t mSize;
  106. UINT16 mAccess;
  107. };
  108. /**
  109. * @brief Data stream for handling data from memory.
  110. */
  111. class BS_UTILITY_EXPORT MemoryDataStream : public DataStream
  112. {
  113. public:
  114. /**
  115. * @brief Wrap an existing memory chunk in a stream.
  116. *
  117. * @param memory Memory to wrap the data stream around.
  118. * @param size Size of the memory chunk in bytes.
  119. */
  120. MemoryDataStream(void* memory, size_t size);
  121. /**
  122. * @brief Create a stream which pre-buffers the contents of another stream. Data
  123. * from the other buffer will be entirely read and stored in an internal buffer.
  124. *
  125. * @param [in] sourceStream Stream to read data from.
  126. */
  127. MemoryDataStream(DataStream& sourceStream);
  128. /**
  129. * @brief Create a stream which pre-buffers the contents of another stream. Data
  130. * from the other buffer will be entirely read and stored in an internal buffer.
  131. *
  132. * @param [in] sourceStream Stream to read data from.
  133. */
  134. MemoryDataStream(const DataStreamPtr& sourceStream);
  135. ~MemoryDataStream();
  136. /**
  137. * @brief Get a pointer to the start of the memory block this stream holds.
  138. */
  139. UINT8* getPtr() { return mData; }
  140. /**
  141. * @brief Get a pointer to the current position in the memory block this stream holds.
  142. */
  143. UINT8* getCurrentPtr() { return mPos; }
  144. /**
  145. * @copydoc DataStream::read
  146. */
  147. size_t read(void* buf, size_t count) override;
  148. /**
  149. * @copydoc DataStream::write
  150. */
  151. size_t write(const void* buf, size_t count) override;
  152. /**
  153. * @copydoc DataStream::skip
  154. */
  155. void skip(size_t count) override;
  156. /**
  157. * @copydoc DataStream::seek
  158. */
  159. void seek(size_t pos) override;
  160. /**
  161. * @copydoc DataStream::tell
  162. */
  163. size_t tell(void) const override;
  164. /**
  165. * @copydoc DataStream::eof
  166. */
  167. bool eof(void) const override;
  168. /**
  169. * @copydoc DataStream::close
  170. */
  171. void close(void) override;
  172. protected:
  173. UINT8* mData;
  174. UINT8* mPos;
  175. UINT8* mEnd;
  176. bool mFreeOnClose;
  177. };
  178. /**
  179. * @brief Data stream for handling data from standard streams.
  180. */
  181. class BS_UTILITY_EXPORT FileDataStream : public DataStream
  182. {
  183. public:
  184. /**
  185. * @brief Construct read-only stream from an standard stream.
  186. *
  187. * If "freeOnClose" is true, the STL stream will be freed once the data stream is closed.
  188. */
  189. FileDataStream(std::shared_ptr<std::ifstream> s, bool freeOnClose = true);
  190. /**
  191. * @brief Construct read-write stream from an standard stream.
  192. *
  193. * If "freeOnClose" is true, the STL stream will be freed once the data stream is closed.
  194. */
  195. FileDataStream(std::shared_ptr<std::fstream> s, bool freeOnClose = true);
  196. /**
  197. * @brief Construct read-only stream from an standard stream, and tell it the size.
  198. *
  199. * Size parameter allows you to specify the size without requiring us to seek to the end of the stream
  200. * to find the size.
  201. *
  202. * If "freeOnClose" is true, the STL stream will be freed once the data stream is closed.
  203. */
  204. FileDataStream(std::shared_ptr<std::ifstream> s, size_t size, bool freeOnClose = true);
  205. /**
  206. * @brief Construct read-write stream from an standard stream, and tell it the size.
  207. *
  208. * Size parameter allows you to specify the size without requiring us to seek to the end of the stream
  209. * to find the size.
  210. *
  211. * If "freeOnClose" is true, the STL stream will be freed once the data stream is closed.
  212. */
  213. FileDataStream(std::shared_ptr<std::fstream> s, size_t size, bool freeOnClose = true);
  214. ~FileDataStream();
  215. /**
  216. * @copydoc DataStream::read
  217. */
  218. size_t read(void* buf, size_t count) override;
  219. /**
  220. * @copydoc DataStream::write
  221. */
  222. size_t write(const void* buf, size_t count) override;
  223. /**
  224. * @copydoc DataStream::skip
  225. */
  226. void skip(size_t count) override;
  227. /**
  228. * @copydoc DataStream::seek
  229. */
  230. void seek(size_t pos) override;
  231. /**
  232. * @copydoc DataStream::tell
  233. */
  234. size_t tell() const override;
  235. /**
  236. * @copydoc DataStream::eof
  237. */
  238. bool eof() const override;
  239. /**
  240. * @copydoc DataStream::close
  241. */
  242. void close() override;
  243. protected:
  244. std::shared_ptr<std::istream> mpInStream;
  245. std::shared_ptr<std::ifstream> mpFStreamRO;
  246. std::shared_ptr<std::fstream> mpFStream;
  247. bool mFreeOnClose;
  248. void determineAccess();
  249. };
  250. }