BinaryReader.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. //
  2. // BinaryReader.h
  3. //
  4. // $Id: //poco/1.4/Foundation/include/Poco/BinaryReader.h#3 $
  5. //
  6. // Library: Foundation
  7. // Package: Streams
  8. // Module: BinaryReaderWriter
  9. //
  10. // Definition of the BinaryReader class.
  11. //
  12. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_BinaryReader_INCLUDED
  18. #define Foundation_BinaryReader_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include "Poco/Buffer.h"
  21. #include "Poco/MemoryStream.h"
  22. #include <vector>
  23. #include <istream>
  24. namespace Poco {
  25. class TextEncoding;
  26. class TextConverter;
  27. class Foundation_API BinaryReader
  28. /// This class reads basic types (and std::vectors thereof)
  29. /// in binary form into an input stream.
  30. /// It provides an extractor-based interface similar to istream.
  31. /// The reader also supports automatic conversion from big-endian
  32. /// (network byte order) to little-endian and vice-versa.
  33. /// Use a BinaryWriter to create a stream suitable for a BinaryReader.
  34. {
  35. public:
  36. enum StreamByteOrder
  37. {
  38. NATIVE_BYTE_ORDER = 1, /// the host's native byte-order
  39. BIG_ENDIAN_BYTE_ORDER = 2, /// big-endian (network) byte-order
  40. NETWORK_BYTE_ORDER = 2, /// big-endian (network) byte-order
  41. LITTLE_ENDIAN_BYTE_ORDER = 3, /// little-endian byte-order
  42. UNSPECIFIED_BYTE_ORDER = 4 /// unknown, byte-order will be determined by reading the byte-order mark
  43. };
  44. BinaryReader(std::istream& istr, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER);
  45. /// Creates the BinaryReader.
  46. BinaryReader(std::istream& istr, TextEncoding& encoding, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER);
  47. /// Creates the BinaryReader using the given TextEncoding.
  48. ///
  49. /// Strings will be converted from the specified encoding
  50. /// to the currently set global encoding (see Poco::TextEncoding::global()).
  51. ~BinaryReader();
  52. /// Destroys the BinaryReader.
  53. BinaryReader& operator >> (bool& value);
  54. BinaryReader& operator >> (char& value);
  55. BinaryReader& operator >> (unsigned char& value);
  56. BinaryReader& operator >> (signed char& value);
  57. BinaryReader& operator >> (short& value);
  58. BinaryReader& operator >> (unsigned short& value);
  59. BinaryReader& operator >> (int& value);
  60. BinaryReader& operator >> (unsigned int& value);
  61. BinaryReader& operator >> (long& value);
  62. BinaryReader& operator >> (unsigned long& value);
  63. BinaryReader& operator >> (float& value);
  64. BinaryReader& operator >> (double& value);
  65. #if defined(POCO_HAVE_INT64) && !defined(POCO_LONG_IS_64_BIT)
  66. BinaryReader& operator >> (Int64& value);
  67. BinaryReader& operator >> (UInt64& value);
  68. #endif
  69. BinaryReader& operator >> (std::string& value);
  70. template <typename T>
  71. BinaryReader& operator >> (std::vector<T>& value)
  72. {
  73. Poco::UInt32 size(0);
  74. T elem;
  75. *this >> size;
  76. if (!good()) return *this;
  77. value.reserve(size);
  78. while (this->good() && size-- > 0)
  79. {
  80. *this >> elem;
  81. value.push_back(elem);
  82. }
  83. return *this;
  84. }
  85. void read7BitEncoded(UInt32& value);
  86. /// Reads a 32-bit unsigned integer in compressed format.
  87. /// See BinaryWriter::write7BitEncoded() for a description
  88. /// of the compression algorithm.
  89. #if defined(POCO_HAVE_INT64)
  90. void read7BitEncoded(UInt64& value);
  91. /// Reads a 64-bit unsigned integer in compressed format.
  92. /// See BinaryWriter::write7BitEncoded() for a description
  93. /// of the compression algorithm.
  94. #endif
  95. void readRaw(std::streamsize length, std::string& value);
  96. /// Reads length bytes of raw data into value.
  97. void readRaw(char* buffer, std::streamsize length);
  98. /// Reads length bytes of raw data into buffer.
  99. void readBOM();
  100. /// Reads a byte-order mark from the stream and configures
  101. /// the reader for the encountered byte order.
  102. /// A byte-order mark is a 16-bit integer with a value of 0xFEFF,
  103. /// written in host byte order.
  104. bool good();
  105. /// Returns _istr.good();
  106. bool fail();
  107. /// Returns _istr.fail();
  108. bool bad();
  109. /// Returns _istr.bad();
  110. bool eof();
  111. /// Returns _istr.eof();
  112. std::istream& stream() const;
  113. /// Returns the underlying stream.
  114. StreamByteOrder byteOrder() const;
  115. /// Returns the byte-order used by the reader, which is
  116. /// either BIG_ENDIAN_BYTE_ORDER or LITTLE_ENDIAN_BYTE_ORDER.
  117. void setExceptions(std::ios_base::iostate st = (std::istream::failbit | std::istream::badbit));
  118. /// Sets the stream to throw exception on specified state (default failbit and badbit);
  119. std::streamsize available() const;
  120. /// Returns the number of available bytes in the stream.
  121. private:
  122. std::istream& _istr;
  123. bool _flipBytes;
  124. TextConverter* _pTextConverter;
  125. };
  126. template <typename T>
  127. class BasicMemoryBinaryReader : public BinaryReader
  128. /// A convenient wrapper for using Buffer and MemoryStream with BinaryReader.
  129. {
  130. public:
  131. BasicMemoryBinaryReader(const Buffer<T>& data, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
  132. BinaryReader(_istr, byteOrder),
  133. _data(data),
  134. _istr(data.begin(), data.capacity())
  135. {
  136. }
  137. BasicMemoryBinaryReader(const Buffer<T>& data, TextEncoding& encoding, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER):
  138. BinaryReader(_istr, encoding, byteOrder),
  139. _data(data),
  140. _istr(data.begin(), data.capacity())
  141. {
  142. }
  143. ~BasicMemoryBinaryReader()
  144. {
  145. }
  146. const Buffer<T>& data() const
  147. {
  148. return _data;
  149. }
  150. const MemoryInputStream& stream() const
  151. {
  152. return _istr;
  153. }
  154. MemoryInputStream& stream()
  155. {
  156. return _istr;
  157. }
  158. private:
  159. const Buffer<T>& _data;
  160. MemoryInputStream _istr;
  161. };
  162. typedef BasicMemoryBinaryReader<char> MemoryBinaryReader;
  163. //
  164. // inlines
  165. //
  166. inline bool BinaryReader::good()
  167. {
  168. return _istr.good();
  169. }
  170. inline bool BinaryReader::fail()
  171. {
  172. return _istr.fail();
  173. }
  174. inline bool BinaryReader::bad()
  175. {
  176. return _istr.bad();
  177. }
  178. inline bool BinaryReader::eof()
  179. {
  180. return _istr.eof();
  181. }
  182. inline std::istream& BinaryReader::stream() const
  183. {
  184. return _istr;
  185. }
  186. inline BinaryReader::StreamByteOrder BinaryReader::byteOrder() const
  187. {
  188. #if defined(POCO_ARCH_BIG_ENDIAN)
  189. return _flipBytes ? LITTLE_ENDIAN_BYTE_ORDER : BIG_ENDIAN_BYTE_ORDER;
  190. #else
  191. return _flipBytes ? BIG_ENDIAN_BYTE_ORDER : LITTLE_ENDIAN_BYTE_ORDER;
  192. #endif
  193. }
  194. inline void BinaryReader::setExceptions(std::ios_base::iostate st)
  195. {
  196. _istr.exceptions(st);
  197. }
  198. inline std::streamsize BinaryReader::available() const
  199. {
  200. return _istr.rdbuf()->in_avail();
  201. }
  202. } // namespace Poco
  203. #endif // Foundation_BinaryReader_INCLUDED