/src/poco/Foundation/include/Poco/BinaryReader.h
Line | Count | Source (jump to first uncovered line) |
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 readCString(std::string& value); |
121 | | /// Reads zero-terminated C-string into value. |
122 | | |
123 | | void readBOM(); |
124 | | /// Reads a byte-order mark from the stream and configures |
125 | | /// the reader for the encountered byte order. |
126 | | /// A byte-order mark is a 16-bit integer with a value of 0xFEFF, |
127 | | /// written in host byte order. |
128 | | |
129 | | bool good(); |
130 | | /// Returns _istr.good(); |
131 | | |
132 | | bool fail(); |
133 | | /// Returns _istr.fail(); |
134 | | |
135 | | bool bad(); |
136 | | /// Returns _istr.bad(); |
137 | | |
138 | | bool eof(); |
139 | | /// Returns _istr.eof(); |
140 | | |
141 | | std::istream& stream() const; |
142 | | /// Returns the underlying stream. |
143 | | |
144 | | StreamByteOrder byteOrder() const; |
145 | | /// Returns the byte-order used by the reader, which is |
146 | | /// either BIG_ENDIAN_BYTE_ORDER or LITTLE_ENDIAN_BYTE_ORDER. |
147 | | |
148 | | void setExceptions(std::ios_base::iostate st = (std::istream::failbit | std::istream::badbit)); |
149 | | /// Sets the stream to throw exception on specified state (default failbit and badbit); |
150 | | |
151 | | std::streamsize available() const; |
152 | | /// Returns the number of available bytes in the stream. |
153 | | |
154 | | private: |
155 | | std::istream& _istr; |
156 | | bool _flipBytes; |
157 | | TextConverter* _pTextConverter; |
158 | | }; |
159 | | |
160 | | |
161 | | template <typename T> |
162 | | class BasicMemoryBinaryReader : public BinaryReader |
163 | | /// A convenient wrapper for using Buffer and MemoryStream with BinaryReader. |
164 | | { |
165 | | public: |
166 | | BasicMemoryBinaryReader(const Buffer<T>& data, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER): |
167 | | BinaryReader(_istr, byteOrder), |
168 | | _data(data), |
169 | | _istr(data.begin(), data.capacity()) |
170 | | { |
171 | | } |
172 | | |
173 | | BasicMemoryBinaryReader(const Buffer<T>& data, TextEncoding& encoding, StreamByteOrder byteOrder = NATIVE_BYTE_ORDER): |
174 | | BinaryReader(_istr, encoding, byteOrder), |
175 | | _data(data), |
176 | | _istr(data.begin(), data.capacity()) |
177 | | { |
178 | | } |
179 | | |
180 | | ~BasicMemoryBinaryReader() = default; |
181 | | |
182 | | const Buffer<T>& data() const |
183 | | { |
184 | | return _data; |
185 | | } |
186 | | |
187 | | const MemoryInputStream& stream() const |
188 | | { |
189 | | return _istr; |
190 | | } |
191 | | |
192 | | MemoryInputStream& stream() |
193 | | { |
194 | | return _istr; |
195 | | } |
196 | | |
197 | | private: |
198 | | const Buffer<T>& _data; |
199 | | MemoryInputStream _istr; |
200 | | }; |
201 | | |
202 | | using MemoryBinaryReader = BasicMemoryBinaryReader<char>; |
203 | | |
204 | | // |
205 | | // inlines |
206 | | // |
207 | | |
208 | | |
209 | | inline bool BinaryReader::good() |
210 | 0 | { |
211 | 0 | return _istr.good(); |
212 | 0 | } |
213 | | |
214 | | |
215 | | inline bool BinaryReader::fail() |
216 | 0 | { |
217 | 0 | return _istr.fail(); |
218 | 0 | } |
219 | | |
220 | | |
221 | | inline bool BinaryReader::bad() |
222 | 0 | { |
223 | 0 | return _istr.bad(); |
224 | 0 | } |
225 | | |
226 | | |
227 | | inline bool BinaryReader::eof() |
228 | 0 | { |
229 | 0 | return _istr.eof(); |
230 | 0 | } |
231 | | |
232 | | |
233 | | inline std::istream& BinaryReader::stream() const |
234 | 0 | { |
235 | 0 | return _istr; |
236 | 0 | } |
237 | | |
238 | | |
239 | | inline BinaryReader::StreamByteOrder BinaryReader::byteOrder() const |
240 | 0 | { |
241 | 0 | #if defined(POCO_ARCH_BIG_ENDIAN) |
242 | 0 | return _flipBytes ? LITTLE_ENDIAN_BYTE_ORDER : BIG_ENDIAN_BYTE_ORDER; |
243 | 0 | #else |
244 | 0 | return _flipBytes ? BIG_ENDIAN_BYTE_ORDER : LITTLE_ENDIAN_BYTE_ORDER; |
245 | 0 | #endif |
246 | 0 | } |
247 | | |
248 | | |
249 | | inline void BinaryReader::setExceptions(std::ios_base::iostate st) |
250 | 0 | { |
251 | 0 | _istr.exceptions(st); |
252 | 0 | } |
253 | | |
254 | | |
255 | | inline std::streamsize BinaryReader::available() const |
256 | 0 | { |
257 | 0 | return _istr.rdbuf()->in_avail(); |
258 | 0 | } |
259 | | |
260 | | |
261 | | } // namespace Poco |
262 | | |
263 | | |
264 | | #endif // Foundation_BinaryReader_INCLUDED |