C++ Utilities  5.10.5
Useful C++ classes and routines such as argument parser, IO and conversion utilities
binaryreader.h
Go to the documentation of this file.
1 #ifndef IOUTILITIES_BINERYREADER_H
2 #define IOUTILITIES_BINERYREADER_H
3 
4 #include "../conversion/binaryconversion.h"
5 
6 #include <istream>
7 #include <string>
8 #include <vector>
9 
10 namespace CppUtilities {
12 
13 public:
14  BinaryReader(std::istream *stream, bool giveOwnership = false);
15  BinaryReader(const BinaryReader &other);
16  BinaryReader &operator=(const BinaryReader &rhs) = delete;
17  ~BinaryReader();
18 
19  const std::istream *stream() const;
20  std::istream *stream();
21  void setStream(std::istream *stream, bool giveOwnership = false);
22  bool hasOwnership() const;
23  void giveOwnership();
24  void detatchOwnership();
25  bool fail() const;
26  bool eof() const;
27  bool canRead() const;
28  std::istream::pos_type readStreamsize();
29  std::istream::pos_type readRemainingBytes();
30  void read(char *buffer, std::streamsize length);
31  void read(std::uint8_t *buffer, std::streamsize length);
32  void read(std::vector<char> &buffer, std::streamsize length);
33  std::int16_t readInt16BE();
34  std::uint16_t readUInt16BE();
35  std::int32_t readInt24BE();
36  std::uint32_t readUInt24BE();
37  std::int32_t readInt32BE();
38  std::uint32_t readUInt32BE();
39  std::int64_t readInt40BE();
40  std::uint64_t readUInt40BE();
41  std::int64_t readInt56BE();
42  std::uint64_t readUInt56BE();
43  std::int64_t readInt64BE();
44  std::uint64_t readUInt64BE();
45  std::uint64_t readVariableLengthUIntBE();
46  float readFloat32BE();
47  double readFloat64BE();
48  std::int16_t readInt16LE();
49  std::uint16_t readUInt16LE();
50  std::int32_t readInt24LE();
51  std::uint32_t readUInt24LE();
52  std::int32_t readInt32LE();
53  std::uint32_t readUInt32LE();
54  std::int64_t readInt40LE();
55  std::uint64_t readUInt40LE();
56  std::int64_t readInt56LE();
57  std::uint64_t readUInt56LE();
58  std::int64_t readInt64LE();
59  std::uint64_t readUInt64LE();
60  std::uint64_t readVariableLengthUIntLE();
61  float readFloat32LE();
62  double readFloat64LE();
63  char readChar();
64  std::uint8_t readByte();
65  bool readBool();
66  std::string readLengthPrefixedString();
67  std::string readString(std::size_t length);
68  std::string readTerminatedString(std::uint8_t termination = 0);
69  std::string readTerminatedString(std::size_t maxBytesToRead, std::uint8_t termination = 0);
70  std::uint32_t readSynchsafeUInt32BE();
71  float readFixed8BE();
72  float readFixed16BE();
73  std::uint32_t readSynchsafeUInt32LE();
74  float readFixed8LE();
75  float readFixed16LE();
76  std::uint32_t readCrc32(std::size_t length);
77  static std::uint32_t computeCrc32(const char *buffer, std::size_t length);
78  static const std::uint32_t crc32Table[];
79 
80  // declare further overloads for read() to ease use of BinaryReader in templates
81  void read(char &oneCharacter);
82  void read(std::uint8_t &oneByte);
83  void read(bool &oneBool);
84  void read(std::string &lengthPrefixedString);
85  void read(std::int16_t &one16BitInt);
86  void read(std::uint16_t &one16BitUInt);
87  void read(std::int32_t &one32BitInt);
88  void read(std::uint32_t &one32BitUInt);
89  void read(std::int64_t &one64BitInt);
90  void read(std::uint64_t &one64BitUInt);
91  void read(float &one32BitFloat);
92  void read(double &one64BitFloat);
93 
94 private:
95  void bufferVariableLengthInteger();
96 
97  std::istream *m_stream;
98  bool m_ownership;
99  char m_buffer[8];
100 };
101 
107 inline BinaryReader::BinaryReader(std::istream *stream, bool giveOwnership)
108  : m_stream(stream)
109  , m_ownership(giveOwnership)
110 {
111 }
112 
118  : m_stream(other.m_stream)
119  , m_ownership(false)
120 {
121 }
122 
127 {
128  if (m_ownership) {
129  delete m_stream;
130  }
131 }
132 
138 inline std::istream *BinaryReader::stream()
139 {
140  return m_stream;
141 }
142 
148 inline const std::istream *BinaryReader::stream() const
149 {
150  return m_stream;
151 }
152 
160 inline bool BinaryReader::hasOwnership() const
161 {
162  return m_ownership;
163 }
164 
173 {
174  if (m_stream) {
175  m_ownership = true;
176  }
177 }
178 
187 {
188  m_ownership = false;
189 }
190 
194 inline bool BinaryReader::fail() const
195 {
196  return m_stream ? m_stream->fail() : false;
197 }
198 
202 inline bool BinaryReader::eof() const
203 {
204  return m_stream && m_stream->eof();
205 }
206 
210 inline bool BinaryReader::canRead() const
211 {
212  return m_stream && m_stream->good();
213 }
214 
218 inline void BinaryReader::read(char *buffer, std::streamsize length)
219 {
220  m_stream->read(buffer, length);
221 }
222 
226 inline void BinaryReader::read(std::uint8_t *buffer, std::streamsize length)
227 {
228  m_stream->read(reinterpret_cast<char *>(buffer), length);
229 }
230 
234 inline void BinaryReader::read(std::vector<char> &buffer, std::streamsize length)
235 {
236  buffer.resize(static_cast<std::vector<char>::size_type>(length));
237  m_stream->read(buffer.data(), length);
238 }
239 
243 inline std::int16_t BinaryReader::readInt16BE()
244 {
245  m_stream->read(m_buffer, sizeof(std::int16_t));
246  return BE::toInt16(m_buffer);
247 }
248 
252 inline std::uint16_t BinaryReader::readUInt16BE()
253 {
254  m_stream->read(m_buffer, sizeof(std::uint16_t));
255  return BE::toUInt16(m_buffer);
256 }
257 
261 inline std::int32_t BinaryReader::readInt24BE()
262 {
263  *m_buffer = 0;
264  m_stream->read(m_buffer + 1, 3);
265  auto val = BE::toInt32(m_buffer);
266  if (val >= 0x800000) {
267  val = -(0x1000000 - val);
268  }
269  return val;
270 }
271 
275 inline std::uint32_t BinaryReader::readUInt24BE()
276 {
277  *m_buffer = 0;
278  m_stream->read(m_buffer + 1, 3);
279  return BE::toUInt32(m_buffer);
280 }
281 
285 inline std::int32_t BinaryReader::readInt32BE()
286 {
287  m_stream->read(m_buffer, sizeof(std::int32_t));
288  return BE::toInt32(m_buffer);
289 }
290 
294 inline std::uint32_t BinaryReader::readUInt32BE()
295 {
296  m_stream->read(m_buffer, sizeof(std::uint32_t));
297  return BE::toUInt32(m_buffer);
298 }
299 
303 inline std::int64_t BinaryReader::readInt40BE()
304 {
305  *m_buffer = *(m_buffer + 1) = *(m_buffer + 2) = 0;
306  m_stream->read(m_buffer + 3, 5);
307  auto val = BE::toInt64(m_buffer);
308  if (val >= 0x8000000000) {
309  val = -(0x10000000000 - val);
310  }
311  return val;
312 }
313 
317 inline std::uint64_t BinaryReader::readUInt40BE()
318 {
319  *m_buffer = *(m_buffer + 1) = *(m_buffer + 2) = 0;
320  m_stream->read(m_buffer + 3, 5);
321  return BE::toUInt64(m_buffer);
322 }
323 
327 inline std::int64_t BinaryReader::readInt56BE()
328 {
329  *m_buffer = 0;
330  m_stream->read(m_buffer + 1, 7);
331  auto val = BE::toInt64(m_buffer);
332  if (val >= 0x80000000000000) {
333  val = -(0x100000000000000 - val);
334  }
335  return val;
336 }
337 
341 inline std::uint64_t BinaryReader::readUInt56BE()
342 {
343  *m_buffer = 0;
344  m_stream->read(m_buffer + 1, 7);
345  return BE::toUInt64(m_buffer);
346 }
347 
351 inline std::int64_t BinaryReader::readInt64BE()
352 {
353  m_stream->read(m_buffer, sizeof(std::int64_t));
354  return BE::toInt64(m_buffer);
355 }
356 
360 inline std::uint64_t BinaryReader::readUInt64BE()
361 {
362  m_stream->read(m_buffer, sizeof(std::uint64_t));
363  return BE::toUInt64(m_buffer);
364 }
365 
371 {
372  bufferVariableLengthInteger();
373  return BE::toUInt64(m_buffer);
374 }
375 
380 {
381  m_stream->read(m_buffer, sizeof(float));
382  return BE::toFloat32(m_buffer);
383 }
384 
389 {
390  m_stream->read(m_buffer, sizeof(double));
391  return BE::toFloat64(m_buffer);
392 }
393 
397 inline std::int16_t BinaryReader::readInt16LE()
398 {
399  m_stream->read(m_buffer, sizeof(std::int16_t));
400  return LE::toInt16(m_buffer);
401 }
402 
406 inline std::uint16_t BinaryReader::readUInt16LE()
407 {
408  m_stream->read(m_buffer, sizeof(std::uint16_t));
409  return LE::toUInt16(m_buffer);
410 }
411 
415 inline std::int32_t BinaryReader::readInt24LE()
416 {
417  *(m_buffer + 3) = 0;
418  m_stream->read(m_buffer, 3);
419  auto val = LE::toInt32(m_buffer);
420  if (val >= 0x800000) {
421  val = -(0x1000000 - val);
422  }
423  return val;
424 }
425 
429 inline std::uint32_t BinaryReader::readUInt24LE()
430 {
431  *(m_buffer + 3) = 0;
432  m_stream->read(m_buffer, 3);
433  return LE::toUInt32(m_buffer);
434 }
435 
439 inline std::int32_t BinaryReader::readInt32LE()
440 {
441  m_stream->read(m_buffer, sizeof(std::int32_t));
442  return LE::toInt32(m_buffer);
443 }
444 
448 inline std::uint32_t BinaryReader::readUInt32LE()
449 {
450  m_stream->read(m_buffer, sizeof(std::uint32_t));
451  return LE::toUInt32(m_buffer);
452 }
453 
457 inline std::int64_t BinaryReader::readInt40LE()
458 {
459  *(m_buffer + 5) = *(m_buffer + 6) = *(m_buffer + 7) = 0;
460  m_stream->read(m_buffer, 5);
461  auto val = LE::toInt64(m_buffer);
462  if (val >= 0x8000000000) {
463  val = -(0x10000000000 - val);
464  }
465  return val;
466 }
467 
471 inline std::uint64_t BinaryReader::readUInt40LE()
472 {
473  *(m_buffer + 5) = *(m_buffer + 6) = *(m_buffer + 7) = 0;
474  m_stream->read(m_buffer, 5);
475  return LE::toUInt64(m_buffer);
476 }
477 
481 inline std::int64_t BinaryReader::readInt56LE()
482 {
483  *(m_buffer + 7) = 0;
484  m_stream->read(m_buffer, 7);
485  auto val = LE::toInt64(m_buffer);
486  if (val >= 0x80000000000000) {
487  val = -(0x100000000000000 - val);
488  }
489  return val;
490 }
491 
495 inline std::uint64_t BinaryReader::readUInt56LE()
496 {
497  *(m_buffer + 7) = 0;
498  m_stream->read(m_buffer, 7);
499  return LE::toUInt64(m_buffer);
500 }
501 
505 inline std::int64_t BinaryReader::readInt64LE()
506 {
507  m_stream->read(m_buffer, sizeof(std::int64_t));
508  return LE::toInt64(m_buffer);
509 }
510 
514 inline std::uint64_t BinaryReader::readUInt64LE()
515 {
516  m_stream->read(m_buffer, sizeof(std::uint64_t));
517  return LE::toUInt64(m_buffer);
518 }
519 
525 {
526  bufferVariableLengthInteger();
527  return LE::toUInt64(m_buffer);
528 }
529 
534 {
535  m_stream->read(m_buffer, sizeof(float));
536  return LE::toFloat32(m_buffer);
537 }
538 
543 {
544  m_stream->read(m_buffer, sizeof(double));
545  return LE::toFloat64(m_buffer);
546 }
547 
552 {
553  m_stream->read(m_buffer, sizeof(char));
554  return m_buffer[0];
555 }
556 
560 inline uint8_t BinaryReader::readByte()
561 {
562  m_stream->read(m_buffer, sizeof(char));
563  return static_cast<std::uint8_t>(m_buffer[0]);
564 }
565 
571 {
572  return readByte() != 0;
573 }
574 
581 {
583 }
584 
591 {
592  return toNormalInt(readUInt32BE());
593 }
594 
599 {
600  return toFloat32(readUInt16BE());
601 }
602 
607 {
608  return toFloat32(readUInt32BE());
609 }
610 
617 {
618  return toNormalInt(readUInt32LE());
619 }
620 
625 {
626  return toFloat32(readUInt16LE());
627 }
628 
633 {
634  return toFloat32(readUInt32LE());
635 }
636 
640 inline void BinaryReader::read(char &oneCharacter)
641 {
642  oneCharacter = readChar();
643 }
644 
648 inline void BinaryReader::read(std::uint8_t &oneByte)
649 {
650  oneByte = readByte();
651 }
652 
657 inline void BinaryReader::read(bool &oneBool)
658 {
659  oneBool = readBool();
660 }
661 
668 inline void BinaryReader::read(std::string &lengthPrefixedString)
669 {
670  lengthPrefixedString = readLengthPrefixedString();
671 }
672 
676 inline void BinaryReader::read(std::int16_t &one16BitInt)
677 {
678  one16BitInt = readInt16BE();
679 }
680 
684 inline void BinaryReader::read(std::uint16_t &one16BitUInt)
685 {
686  one16BitUInt = readUInt16BE();
687 }
688 
692 inline void BinaryReader::read(std::int32_t &one32BitInt)
693 {
694  one32BitInt = readInt32BE();
695 }
696 
700 inline void BinaryReader::read(std::uint32_t &one32BitUInt)
701 {
702  one32BitUInt = readUInt32BE();
703 }
704 
708 inline void BinaryReader::read(std::int64_t &one64BitInt)
709 {
710  one64BitInt = readInt64BE();
711 }
712 
716 inline void BinaryReader::read(std::uint64_t &one64BitUInt)
717 {
718  one64BitUInt = readUInt64BE();
719 }
720 
724 inline void BinaryReader::read(float &one32BitFloat)
725 {
726  one32BitFloat = readFloat32BE();
727 }
728 
732 inline void BinaryReader::read(double &one64BitFloat)
733 {
734  one64BitFloat = readFloat64BE();
735 }
736 } // namespace CppUtilities
737 
738 #endif // IOUTILITIES_BINERYREADER_H
Reads primitive data types from a std::istream.
Definition: binaryreader.h:11
float readFixed8LE()
Reads a 8.8 fixed point little endian representation from the current stream and returns it as 32-bit...
Definition: binaryreader.h:624
void detatchOwnership()
The reader will not take ownership over the assigned stream.
Definition: binaryreader.h:186
BinaryReader & operator=(const BinaryReader &rhs)=delete
std::int64_t readInt64LE()
Reads a 64-bit little endian signed integer from the current stream and advances the current position...
Definition: binaryreader.h:505
float readFloat32BE()
Reads a 32-bit big endian floating point value from the current stream and advances the current posit...
Definition: binaryreader.h:379
std::string readString(std::size_t length)
Reads a string from the current stream of the given length from the stream and advances the current p...
std::uint64_t readUInt64LE()
Reads a 64-bit little endian unsigned integer from the current stream and advances the current positi...
Definition: binaryreader.h:514
float readFixed16BE()
Reads a 16.16 fixed point big endian representation from the current stream and returns it as 32-bit ...
Definition: binaryreader.h:606
std::string readLengthPrefixedString()
Reads a length prefixed string from the current stream.
Definition: binaryreader.h:580
std::int64_t readInt40LE()
Reads a 40-bit little endian signed integer from the current stream and advances the current position...
Definition: binaryreader.h:457
std::int32_t readInt32BE()
Reads a 32-bit big endian signed integer from the current stream and advances the current position of...
Definition: binaryreader.h:285
std::int32_t readInt24LE()
Reads a 24-bit little endian signed integer from the current stream and advances the current position...
Definition: binaryreader.h:415
std::uint32_t readUInt32LE()
Reads a 32-bit little endian unsigned integer from the current stream and advances the current positi...
Definition: binaryreader.h:448
std::uint16_t readUInt16LE()
Reads a 16-bit little endian unsigned integer from the current stream and advances the current positi...
Definition: binaryreader.h:406
std::uint64_t readVariableLengthUIntBE()
Reads an up to 8 byte long big endian unsigned integer from the current stream and advances the curre...
Definition: binaryreader.h:370
std::uint64_t readUInt56BE()
Reads a 56-bit big endian unsigned integer from the current stream and advances the current position ...
Definition: binaryreader.h:341
bool readBool()
Reads a boolean value from the current stream and advances the current position of the stream by one ...
Definition: binaryreader.h:570
std::uint32_t readUInt24BE()
Reads a 24-bit big endian unsigned integer from the current stream and advances the current position ...
Definition: binaryreader.h:275
std::int32_t readInt32LE()
Reads a 32-bit little endian signed integer from the current stream and advances the current position...
Definition: binaryreader.h:439
bool fail() const
Returns an indication whether the fail bit of the assigned stream is set.
Definition: binaryreader.h:194
const std::istream * stream() const
Returns a pointer to the stream the reader will read from when calling one of the read-methods.
Definition: binaryreader.h:148
std::int16_t readInt16BE()
Reads a 16-bit big endian signed integer from the current stream and advances the current position of...
Definition: binaryreader.h:243
std::uint32_t readSynchsafeUInt32LE()
Reads a 32-bit little endian synchsafe integer from the current stream and advances the current posit...
Definition: binaryreader.h:616
std::uint32_t readUInt24LE()
Reads a 24-bit little endian unsigned integer from the current stream and advances the current positi...
Definition: binaryreader.h:429
std::int64_t readInt56LE()
Reads a 56-bit little endian signed integer from the current stream and advances the current position...
Definition: binaryreader.h:481
~BinaryReader()
Destroys the BinaryReader.
Definition: binaryreader.h:126
std::uint64_t readUInt64BE()
Reads a 64-bit big endian unsigned integer from the current stream and advances the current position ...
Definition: binaryreader.h:360
bool hasOwnership() const
Returns whether the reader takes ownership over the assigned stream.
Definition: binaryreader.h:160
std::uint64_t readUInt40LE()
Reads a 40-bit little endian unsigned integer from the current stream and advances the current positi...
Definition: binaryreader.h:471
char readChar()
Reads a single character from the current stream and advances the current position of the stream by o...
Definition: binaryreader.h:551
std::uint64_t readUInt56LE()
Reads a 56-bit little endian unsigned integer from the current stream and advances the current positi...
Definition: binaryreader.h:495
BinaryReader(std::istream *stream, bool giveOwnership=false)
Constructs a new BinaryReader.
Definition: binaryreader.h:107
float readFixed16LE()
Reads a 16.16 fixed point little endian representation from the current stream and returns it as 32-b...
Definition: binaryreader.h:632
std::uint16_t readUInt16BE()
Reads a 16-bit big endian unsigned integer from the current stream and advances the current position ...
Definition: binaryreader.h:252
std::int32_t readInt24BE()
Reads a 24-bit big endian signed integer from the current stream and advances the current position of...
Definition: binaryreader.h:261
void read(char *buffer, std::streamsize length)
Reads the specified number of characters from the stream in the character array.
Definition: binaryreader.h:218
std::int64_t readInt40BE()
Reads a 40-bit big endian signed integer from the current stream and advances the current position of...
Definition: binaryreader.h:303
void giveOwnership()
The reader will take ownership over the assigned stream.
Definition: binaryreader.h:172
double readFloat64BE()
Reads a 64-bit big endian floating point value from the current stream and advances the current posit...
Definition: binaryreader.h:388
std::uint32_t readUInt32BE()
Reads a 32-bit big endian unsigned integer from the current stream and advances the current position ...
Definition: binaryreader.h:294
std::int64_t readInt56BE()
Reads a 56-bit big endian signed integer from the current stream and advances the current position of...
Definition: binaryreader.h:327
std::int16_t readInt16LE()
Reads a 16-bit little endian signed integer from the current stream and advances the current position...
Definition: binaryreader.h:397
double readFloat64LE()
Reads a 64-bit little endian floating point value from the current stream and advances the current po...
Definition: binaryreader.h:542
std::int64_t readInt64BE()
Reads a 64-bit big endian signed integer from the current stream and advances the current position of...
Definition: binaryreader.h:351
std::uint64_t readUInt40BE()
Reads a 40-bit big endian unsigned integer from the current stream and advances the current position ...
Definition: binaryreader.h:317
std::uint32_t readSynchsafeUInt32BE()
Reads a 32-bit big endian synchsafe integer from the current stream and advances the current position...
Definition: binaryreader.h:590
bool eof() const
Returns an indication whether the end-of-stream bit of the assigned stream is set.
Definition: binaryreader.h:202
bool canRead() const
Returns an indication whether a stream is assigned the reader can read from.
Definition: binaryreader.h:210
float readFloat32LE()
Reads a 32-bit little endian floating point value from the current stream and advances the current po...
Definition: binaryreader.h:533
std::uint64_t readVariableLengthUIntLE()
Reads an up to 8 byte long little endian unsigned integer from the current stream and advances the cu...
Definition: binaryreader.h:524
float readFixed8BE()
Reads a 8.8 fixed point big endian representation from the current stream and returns it as 32-bit fl...
Definition: binaryreader.h:598
std::uint8_t readByte()
Reads a single byte/unsigned character from the current stream and advances the current position of t...
Definition: binaryreader.h:560
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
Contains all utilities provides by the c++utilities library.
constexpr CPP_UTILITIES_EXPORT std::uint32_t toNormalInt(std::uint32_t synchsafeInt)
Returns a normal 32-bit integer converted from a 32-bit synchsafe integer.
constexpr CPP_UTILITIES_EXPORT float toFloat32(std::uint16_t fixed8value)
Returns a 32-bit floating point number converted from the specified 8.8 fixed point representation.