BsDataStream.h 8.5 KB

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