C++ Utilities 5.26.1
Useful C++ classes and routines such as argument parser, IO and conversion utilities
Loading...
Searching...
No Matches
binaryreader.h
Go to the documentation of this file.
1#ifndef IOUTILITIES_BINERYREADER_H
2#define IOUTILITIES_BINERYREADER_H
3
5
6#include <istream>
7#include <string>
8#include <vector>
9
10namespace CppUtilities {
12
13public:
14 BinaryReader(std::istream *stream, bool giveOwnership = false);
15 BinaryReader(const BinaryReader &other);
16 BinaryReader &operator=(const BinaryReader &rhs) = delete;
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
94private:
95 void bufferVariableLengthInteger();
96
97 std::istream *m_stream;
98 bool m_ownership;
99 char m_buffer[8];
100};
101
107inline 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
138inline std::istream *BinaryReader::stream()
139{
140 return m_stream;
141}
142
148inline const std::istream *BinaryReader::stream() const
149{
150 return m_stream;
151}
152
160inline 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
194inline bool BinaryReader::fail() const
195{
196 return m_stream ? m_stream->fail() : false;
197}
198
202inline bool BinaryReader::eof() const
203{
204 return m_stream && m_stream->eof();
205}
206
210inline bool BinaryReader::canRead() const
211{
212 return m_stream && m_stream->good();
213}
214
218inline void BinaryReader::read(char *buffer, std::streamsize length)
219{
220 m_stream->read(buffer, length);
221}
222
226inline void BinaryReader::read(std::uint8_t *buffer, std::streamsize length)
227{
228 m_stream->read(reinterpret_cast<char *>(buffer), length);
229}
230
234inline 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
243inline std::int16_t BinaryReader::readInt16BE()
244{
245 m_stream->read(m_buffer, sizeof(std::int16_t));
246 return BE::toInt<std::int16_t>(m_buffer);
247}
248
252inline std::uint16_t BinaryReader::readUInt16BE()
253{
254 m_stream->read(m_buffer, sizeof(std::uint16_t));
255 return BE::toInt<std::uint16_t>(m_buffer);
256}
257
261inline std::int32_t BinaryReader::readInt24BE()
262{
263 *m_buffer = 0;
264 m_stream->read(m_buffer + 1, 3);
265 auto val = BE::toInt<std::int32_t>(m_buffer);
266 if (val >= 0x800000) {
267 val = -(0x1000000 - val);
268 }
269 return val;
270}
271
275inline std::uint32_t BinaryReader::readUInt24BE()
276{
277 *m_buffer = 0;
278 m_stream->read(m_buffer + 1, 3);
279 return BE::toInt<std::uint32_t>(m_buffer);
280}
281
285inline std::int32_t BinaryReader::readInt32BE()
286{
287 m_stream->read(m_buffer, sizeof(std::int32_t));
288 return BE::toInt<std::int32_t>(m_buffer);
289}
290
294inline std::uint32_t BinaryReader::readUInt32BE()
295{
296 m_stream->read(m_buffer, sizeof(std::uint32_t));
297 return BE::toInt<std::uint32_t>(m_buffer);
298}
299
303inline 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::toInt<std::int64_t>(m_buffer);
308 if (val >= 0x8000000000) {
309 val = -(0x10000000000 - val);
310 }
311 return val;
312}
313
317inline 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::toInt<std::uint64_t>(m_buffer);
322}
323
327inline std::int64_t BinaryReader::readInt56BE()
328{
329 *m_buffer = 0;
330 m_stream->read(m_buffer + 1, 7);
331 auto val = BE::toInt<std::int64_t>(m_buffer);
332 if (val >= 0x80000000000000) {
333 val = -(0x100000000000000 - val);
334 }
335 return val;
336}
337
341inline std::uint64_t BinaryReader::readUInt56BE()
342{
343 *m_buffer = 0;
344 m_stream->read(m_buffer + 1, 7);
345 return BE::toInt<std::uint64_t>(m_buffer);
346}
347
351inline std::int64_t BinaryReader::readInt64BE()
352{
353 m_stream->read(m_buffer, sizeof(std::int64_t));
354 return BE::toInt<std::int64_t>(m_buffer);
355}
356
360inline std::uint64_t BinaryReader::readUInt64BE()
361{
362 m_stream->read(m_buffer, sizeof(std::uint64_t));
363 return BE::toInt<std::uint64_t>(m_buffer);
364}
365
371{
372 bufferVariableLengthInteger();
373 return BE::toInt<std::uint64_t>(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
397inline std::int16_t BinaryReader::readInt16LE()
398{
399 m_stream->read(m_buffer, sizeof(std::int16_t));
400 return LE::toInt<std::int16_t>(m_buffer);
401}
402
406inline std::uint16_t BinaryReader::readUInt16LE()
407{
408 m_stream->read(m_buffer, sizeof(std::uint16_t));
409 return LE::toInt<std::uint16_t>(m_buffer);
410}
411
415inline std::int32_t BinaryReader::readInt24LE()
416{
417 *(m_buffer + 3) = 0;
418 m_stream->read(m_buffer, 3);
419 auto val = LE::toInt<std::int32_t>(m_buffer);
420 if (val >= 0x800000) {
421 val = -(0x1000000 - val);
422 }
423 return val;
424}
425
429inline std::uint32_t BinaryReader::readUInt24LE()
430{
431 *(m_buffer + 3) = 0;
432 m_stream->read(m_buffer, 3);
433 return LE::toInt<std::uint32_t>(m_buffer);
434}
435
439inline std::int32_t BinaryReader::readInt32LE()
440{
441 m_stream->read(m_buffer, sizeof(std::int32_t));
442 return LE::toInt<std::int32_t>(m_buffer);
443}
444
448inline std::uint32_t BinaryReader::readUInt32LE()
449{
450 m_stream->read(m_buffer, sizeof(std::uint32_t));
451 return LE::toInt<std::uint32_t>(m_buffer);
452}
453
457inline 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::toInt<std::int64_t>(m_buffer);
462 if (val >= 0x8000000000) {
463 val = -(0x10000000000 - val);
464 }
465 return val;
466}
467
471inline 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::toInt<std::uint64_t>(m_buffer);
476}
477
481inline std::int64_t BinaryReader::readInt56LE()
482{
483 *(m_buffer + 7) = 0;
484 m_stream->read(m_buffer, 7);
485 auto val = LE::toInt<std::int64_t>(m_buffer);
486 if (val >= 0x80000000000000) {
487 val = -(0x100000000000000 - val);
488 }
489 return val;
490}
491
495inline std::uint64_t BinaryReader::readUInt56LE()
496{
497 *(m_buffer + 7) = 0;
498 m_stream->read(m_buffer, 7);
499 return LE::toInt<std::uint64_t>(m_buffer);
500}
501
505inline std::int64_t BinaryReader::readInt64LE()
506{
507 m_stream->read(m_buffer, sizeof(std::int64_t));
508 return LE::toInt<std::int64_t>(m_buffer);
509}
510
514inline std::uint64_t BinaryReader::readUInt64LE()
515{
516 m_stream->read(m_buffer, sizeof(std::uint64_t));
517 return LE::toInt<std::uint64_t>(m_buffer);
518}
519
525{
526 bufferVariableLengthInteger();
527 return LE::toInt<std::uint64_t>(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
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
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
640inline void BinaryReader::read(char &oneCharacter)
641{
642 oneCharacter = readChar();
643}
644
648inline void BinaryReader::read(std::uint8_t &oneByte)
649{
650 oneByte = readByte();
651}
652
657inline void BinaryReader::read(bool &oneBool)
658{
659 oneBool = readBool();
660}
661
668inline void BinaryReader::read(std::string &lengthPrefixedString)
669{
670 lengthPrefixedString = readLengthPrefixedString();
671}
672
676inline void BinaryReader::read(std::int16_t &one16BitInt)
677{
678 one16BitInt = readInt16BE();
679}
680
684inline void BinaryReader::read(std::uint16_t &one16BitUInt)
685{
686 one16BitUInt = readUInt16BE();
687}
688
692inline void BinaryReader::read(std::int32_t &one32BitInt)
693{
694 one32BitInt = readInt32BE();
695}
696
700inline void BinaryReader::read(std::uint32_t &one32BitUInt)
701{
702 one32BitUInt = readUInt32BE();
703}
704
708inline void BinaryReader::read(std::int64_t &one64BitInt)
709{
710 one64BitInt = readInt64BE();
711}
712
716inline void BinaryReader::read(std::uint64_t &one64BitUInt)
717{
718 one64BitUInt = readUInt64BE();
719}
720
724inline void BinaryReader::read(float &one32BitFloat)
725{
726 one32BitFloat = readFloat32BE();
727}
728
732inline 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.
float readFixed8LE()
Reads a 8.8 fixed point little endian representation from the current stream and returns it as 32-bit...
void detatchOwnership()
The reader will not take ownership over the assigned stream.
std::int64_t readInt64LE()
Reads a 64-bit little endian signed integer from the current stream and advances the current position...
float readFloat32BE()
Reads a 32-bit big endian floating point value from the current stream and advances the current posit...
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...
float readFixed16BE()
Reads a 16.16 fixed point big endian representation from the current stream and returns it as 32-bit ...
std::string readLengthPrefixedString()
Reads a length prefixed string from the current stream.
std::int64_t readInt40LE()
Reads a 40-bit little endian signed integer from the current stream and advances the current position...
std::int32_t readInt32BE()
Reads a 32-bit big endian signed integer from the current stream and advances the current position of...
std::int32_t readInt24LE()
Reads a 24-bit little endian signed integer from the current stream and advances the current position...
std::uint32_t readUInt32LE()
Reads a 32-bit little endian unsigned integer from the current stream and advances the current positi...
std::uint16_t readUInt16LE()
Reads a 16-bit little endian unsigned integer from the current stream and advances the current positi...
std::uint64_t readVariableLengthUIntBE()
Reads an up to 8 byte long big endian unsigned integer from the current stream and advances the curre...
std::uint64_t readUInt56BE()
Reads a 56-bit big endian unsigned integer from the current stream and advances the current position ...
bool readBool()
Reads a boolean value from the current stream and advances the current position of the stream by one ...
std::uint32_t readUInt24BE()
Reads a 24-bit big endian unsigned integer from the current stream and advances the current position ...
std::int32_t readInt32LE()
Reads a 32-bit little endian signed integer from the current stream and advances the current position...
bool fail() const
Returns an indication whether the fail bit of the assigned stream is set.
const std::istream * stream() const
Returns a pointer to the stream the reader will read from when calling one of the read-methods.
std::int16_t readInt16BE()
Reads a 16-bit big endian signed integer from the current stream and advances the current position of...
std::uint32_t readSynchsafeUInt32LE()
Reads a 32-bit little endian synchsafe integer from the current stream and advances the current posit...
std::uint32_t readUInt24LE()
Reads a 24-bit little endian unsigned integer from the current stream and advances the current positi...
std::int64_t readInt56LE()
Reads a 56-bit little endian signed integer from the current stream and advances the current position...
~BinaryReader()
Destroys the BinaryReader.
std::uint64_t readUInt64BE()
Reads a 64-bit big endian unsigned integer from the current stream and advances the current position ...
bool hasOwnership() const
Returns whether the reader takes ownership over the assigned stream.
std::uint64_t readUInt40LE()
Reads a 40-bit little endian unsigned integer from the current stream and advances the current positi...
char readChar()
Reads a single character from the current stream and advances the current position of the stream by o...
std::uint64_t readUInt56LE()
Reads a 56-bit little endian unsigned integer from the current stream and advances the current positi...
BinaryReader(std::istream *stream, bool giveOwnership=false)
Constructs a new BinaryReader.
float readFixed16LE()
Reads a 16.16 fixed point little endian representation from the current stream and returns it as 32-b...
std::uint16_t readUInt16BE()
Reads a 16-bit big endian unsigned integer from the current stream and advances the current position ...
std::int32_t readInt24BE()
Reads a 24-bit big endian signed integer from the current stream and advances the current position of...
void read(char *buffer, std::streamsize length)
Reads the specified number of characters from the stream in the character array.
std::int64_t readInt40BE()
Reads a 40-bit big endian signed integer from the current stream and advances the current position of...
void giveOwnership()
The reader will take ownership over the assigned stream.
double readFloat64BE()
Reads a 64-bit big endian floating point value from the current stream and advances the current posit...
std::uint32_t readUInt32BE()
Reads a 32-bit big endian unsigned integer from the current stream and advances the current position ...
std::int64_t readInt56BE()
Reads a 56-bit big endian signed integer from the current stream and advances the current position of...
std::int16_t readInt16LE()
Reads a 16-bit little endian signed integer from the current stream and advances the current position...
double readFloat64LE()
Reads a 64-bit little endian floating point value from the current stream and advances the current po...
std::int64_t readInt64BE()
Reads a 64-bit big endian signed integer from the current stream and advances the current position of...
std::uint64_t readUInt40BE()
Reads a 40-bit big endian unsigned integer from the current stream and advances the current position ...
std::uint32_t readSynchsafeUInt32BE()
Reads a 32-bit big endian synchsafe integer from the current stream and advances the current position...
bool eof() const
Returns an indication whether the end-of-stream bit of the assigned stream is set.
bool canRead() const
Returns an indication whether a stream is assigned the reader can read from.
float readFloat32LE()
Reads a 32-bit little endian floating point value from the current stream and advances the current po...
BinaryReader & operator=(const BinaryReader &rhs)=delete
std::uint64_t readVariableLengthUIntLE()
Reads an up to 8 byte long little endian unsigned integer from the current stream and advances the cu...
float readFixed8BE()
Reads a 8.8 fixed point big endian representation from the current stream and returns it as 32-bit fl...
std::uint8_t readByte()
Reads a single byte/unsigned character from the current stream and advances the current position of t...
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
Definition global.h:14
CPP_UTILITIES_EXPORT float toFloat32(const char *value)
Returns a 32-bit floating point number converted from four bytes at a specified position in a char ar...
CPP_UTILITIES_EXPORT T toInt(const char *value)
Returns the specified (unsigned) integer converted from the specified char array.
CPP_UTILITIES_EXPORT double toFloat64(const char *value)
Returns a 64-bit floating point number converted from eight bytes at a specified position in a char a...
CPP_UTILITIES_EXPORT double toFloat64(const char *value)
Returns a 64-bit floating point number converted from eight bytes at a specified position in a char a...
CPP_UTILITIES_EXPORT T toInt(const char *value)
Returns the specified (unsigned) integer converted from the specified char array.
CPP_UTILITIES_EXPORT float toFloat32(const char *value)
Returns a 32-bit floating point number converted from four bytes at a specified position in a char ar...
Contains all utilities provides by the c++utilities library.
CPP_UTILITIES_EXPORT constexpr float toFloat32(std::uint16_t fixed8value)
Returns a 32-bit floating point number converted from the specified 8.8 fixed point representation.
CPP_UTILITIES_EXPORT constexpr std::uint32_t toNormalInt(std::uint32_t synchsafeInt)
Returns a normal 32-bit integer converted from a 32-bit synchsafe integer.