Coverage Report

Created: 2025-10-14 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poco/Foundation/src/BinaryReader.cpp
Line
Count
Source
1
//
2
// BinaryReader.cpp
3
//
4
// Library: Foundation
5
// Package: Streams
6
// Module:  BinaryReaderWriter
7
//
8
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9
// and Contributors.
10
//
11
// SPDX-License-Identifier: BSL-1.0
12
//
13
14
15
#include "Poco/BinaryReader.h"
16
#include "Poco/ByteOrder.h"
17
#include "Poco/TextEncoding.h"
18
#include "Poco/TextConverter.h"
19
#include <algorithm>
20
21
22
namespace Poco {
23
24
25
BinaryReader::BinaryReader(std::istream& istr, StreamByteOrder byteOrder):
26
88.9k
  _istr(istr),
27
88.9k
  _pTextConverter(0)
28
88.9k
{
29
#if defined(POCO_ARCH_BIG_ENDIAN)
30
  _flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER);
31
#else
32
88.9k
  _flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER);
33
88.9k
#endif
34
88.9k
}
35
36
37
BinaryReader::BinaryReader(std::istream& istr, TextEncoding& encoding, StreamByteOrder byteOrder):
38
0
  _istr(istr),
39
0
  _pTextConverter(new TextConverter(encoding, Poco::TextEncoding::global()))
40
0
{
41
#if defined(POCO_ARCH_BIG_ENDIAN)
42
  _flipBytes = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER);
43
#else
44
0
  _flipBytes = (byteOrder == BIG_ENDIAN_BYTE_ORDER);
45
0
#endif
46
0
}
47
48
49
BinaryReader::~BinaryReader()
50
88.9k
{
51
88.9k
  delete _pTextConverter;
52
88.9k
}
53
54
55
BinaryReader& BinaryReader::operator >> (bool& value)
56
0
{
57
0
  _istr.read((char*) &value, sizeof(value));
58
0
  return *this;
59
0
}
60
61
62
BinaryReader& BinaryReader::operator >> (char& value)
63
0
{
64
0
  _istr.read((char*) &value, sizeof(value));
65
0
  return *this;
66
0
}
67
68
69
BinaryReader& BinaryReader::operator >> (unsigned char& value)
70
385
{
71
385
  _istr.read((char*) &value, sizeof(value));
72
385
  return *this;
73
385
}
74
75
76
BinaryReader& BinaryReader::operator >> (signed char& value)
77
0
{
78
0
  _istr.read((char*) &value, sizeof(value));
79
0
  return *this;
80
0
}
81
82
83
BinaryReader& BinaryReader::operator >> (short& value)
84
0
{
85
0
  _istr.read((char*) &value, sizeof(value));
86
0
  if (_flipBytes) value = ByteOrder::flipBytes(value);
87
0
  return *this;
88
0
}
89
90
91
BinaryReader& BinaryReader::operator >> (unsigned short& value)
92
1.01k
{
93
1.01k
  _istr.read((char*) &value, sizeof(value));
94
1.01k
  if (_flipBytes) value = ByteOrder::flipBytes(value);
95
1.01k
  return *this;
96
1.01k
}
97
98
99
BinaryReader& BinaryReader::operator >> (int& value)
100
0
{
101
0
  _istr.read((char*) &value, sizeof(value));
102
0
  if (_flipBytes) value = ByteOrder::flipBytes(value);
103
0
  return *this;
104
0
}
105
106
107
BinaryReader& BinaryReader::operator >> (unsigned int& value)
108
1.17k
{
109
1.17k
  _istr.read((char*) &value, sizeof(value));
110
1.17k
  if (_flipBytes) value = ByteOrder::flipBytes(value);
111
1.17k
  return *this;
112
1.17k
}
113
114
115
BinaryReader& BinaryReader::operator >> (long& value)
116
0
{
117
0
  _istr.read((char*) &value, sizeof(value));
118
0
#if defined(POCO_LONG_IS_64_BIT)
119
0
  if (_flipBytes) value = ByteOrder::flipBytes((Int64) value);
120
#else
121
  if (_flipBytes) value = ByteOrder::flipBytes((Int32) value);
122
#endif
123
0
  return *this;
124
0
}
125
126
127
BinaryReader& BinaryReader::operator >> (unsigned long& value)
128
88.7k
{
129
88.7k
  _istr.read((char*) &value, sizeof(value));
130
88.7k
#if defined(POCO_LONG_IS_64_BIT)
131
88.7k
  if (_flipBytes) value = ByteOrder::flipBytes((UInt64) value);
132
#else
133
  if (_flipBytes) value = ByteOrder::flipBytes((UInt32) value);
134
#endif
135
88.7k
  return *this;
136
88.7k
}
137
138
139
BinaryReader& BinaryReader::operator >> (float& value)
140
0
{
141
0
  if (_flipBytes)
142
0
  {
143
0
    char* ptr = (char*) &value;
144
0
    ptr += sizeof(value);
145
0
    for (unsigned i = 0; i < sizeof(value); ++i)
146
0
      _istr.read(--ptr, 1);
147
0
  }
148
0
  else
149
0
  {
150
0
    _istr.read((char*) &value, sizeof(value));
151
0
  }
152
0
  return *this;
153
0
}
154
155
156
BinaryReader& BinaryReader::operator >> (double& value)
157
0
{
158
0
  if (_flipBytes)
159
0
  {
160
0
    char* ptr = (char*) &value;
161
0
    ptr += sizeof(value);
162
0
    for (unsigned i = 0; i < sizeof(value); ++i)
163
0
      _istr.read(--ptr, 1);
164
0
  }
165
0
  else
166
0
  {
167
0
    _istr.read((char*) &value, sizeof(value));
168
0
  }
169
0
  return *this;
170
0
}
171
172
173
#if defined(POCO_HAVE_INT64)
174
175
176
BinaryReader& BinaryReader::operator >> (long long& value)
177
0
{
178
0
  _istr.read((char*) &value, sizeof(value));
179
0
  if (_flipBytes) value = ByteOrder::flipBytes(static_cast<Poco::Int64>(value));
180
0
  return *this;
181
0
}
182
183
184
BinaryReader& BinaryReader::operator >> (unsigned long long& value)
185
0
{
186
0
  _istr.read((char*) &value, sizeof(value));
187
0
  if (_flipBytes) value = ByteOrder::flipBytes(static_cast<Poco::UInt64>(value));
188
0
  return *this;
189
0
}
190
191
192
#endif
193
194
195
BinaryReader& BinaryReader::operator >> (std::string& value)
196
0
{
197
0
  UInt32 size = 0;
198
0
  read7BitEncoded(size);
199
0
  value.clear();
200
0
  if (!_istr.good()) return *this;
201
0
  value.reserve(size);
202
0
  while (size--)
203
0
  {
204
0
    char c;
205
0
    if (!_istr.read(&c, 1).good()) break;
206
0
    value += c;
207
0
  }
208
0
  if (_pTextConverter)
209
0
  {
210
0
    std::string converted;
211
0
    _pTextConverter->convert(value, converted);
212
0
    std::swap(value, converted);
213
0
  }
214
0
  return *this;
215
0
}
216
217
218
void BinaryReader::read7BitEncoded(UInt32& value)
219
0
{
220
0
  char c;
221
0
  value = 0;
222
0
  int s = 0;
223
0
  do
224
0
  {
225
0
    c = 0;
226
0
    _istr.read(&c, 1);
227
0
    UInt32 x = (c & 0x7F);
228
0
    x <<= s;
229
0
    value += x;
230
0
    s += 7;
231
0
  }
232
0
  while (c & 0x80);
233
0
}
234
235
236
#if defined(POCO_HAVE_INT64)
237
238
239
void BinaryReader::read7BitEncoded(UInt64& value)
240
0
{
241
0
  char c;
242
0
  value = 0;
243
0
  int s = 0;
244
0
  do
245
0
  {
246
0
    c = 0;
247
0
    _istr.read(&c, 1);
248
0
    UInt64 x = (c & 0x7F);
249
0
    x <<= s;
250
0
    value += x;
251
0
    s += 7;
252
0
  }
253
0
  while (c & 0x80);
254
0
}
255
256
257
#endif
258
259
260
void BinaryReader::readRaw(std::streamsize length, std::string& value)
261
408
{
262
408
  value.clear();
263
408
  value.reserve(static_cast<std::string::size_type>(length));
264
3.22k
  while (length--)
265
2.82k
  {
266
2.82k
    char c;
267
2.82k
    if (!_istr.read(&c, 1).good()) break;
268
2.81k
    value += c;
269
2.81k
  }
270
408
}
271
272
273
void BinaryReader::readRaw(char* buffer, std::streamsize length)
274
290
{
275
290
  _istr.read(buffer, length);
276
290
}
277
278
279
void BinaryReader::readCString(std::string& value)
280
0
{
281
0
  value.clear();
282
0
  if (!_istr.good())
283
0
  {
284
0
    return;
285
0
  }
286
0
  value.reserve(256);
287
0
  while (true)
288
0
  {
289
0
    char c;
290
0
    _istr.get(c);
291
0
    if (!_istr.good())
292
0
    {
293
0
      break;
294
0
    }
295
0
    if (c == '\0')
296
0
    {
297
0
      break;
298
0
    }
299
0
    value += c;
300
0
  }
301
0
}
302
303
304
void BinaryReader::readBOM()
305
0
{
306
0
  UInt16 bom;
307
0
  _istr.read((char*) &bom, sizeof(bom));
308
0
  _flipBytes = bom != 0xFEFF;
309
0
}
310
311
312
} // namespace Poco