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