Coverage Report

Created: 2025-09-05 06:24

/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