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