BsDataStream.h 8.6 KB

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