C++ Utilities 5.26.1
Useful C++ classes and routines such as argument parser, IO and conversion utilities
Loading...
Searching...
No Matches
binarywriter.h
Go to the documentation of this file.
1#ifndef IOUTILITIES_BINARYWRITER_H
2#define IOUTILITIES_BINARYWRITER_H
3
5
6#include <cstdint>
7#include <cstring>
8#include <ostream>
9#include <string>
10#include <vector>
11
12namespace CppUtilities {
13
15public:
16 BinaryWriter(std::ostream *stream, bool giveOwnership = false);
17 BinaryWriter(const BinaryWriter &other);
18 BinaryWriter &operator=(const BinaryWriter &rhs) = delete;
20
21 const std::ostream *stream() const;
22 std::ostream *stream();
23 void setStream(std::ostream *stream, bool giveOwnership = false);
24 bool hasOwnership() const;
25 void giveOwnership();
26 void detatchOwnership();
27 void flush();
28 bool fail() const;
29 void write(const char *buffer, std::streamsize length);
30 void write(const std::vector<char> &buffer, std::streamsize length);
31 void writeChar(char value);
32 void writeByte(std::uint8_t value);
33 void writeInt16BE(std::int16_t value);
34 void writeUInt16BE(std::uint16_t value);
35 void writeInt24BE(std::int32_t value);
36 void writeUInt24BE(std::uint32_t value);
37 void writeInt32BE(std::int32_t value);
38 void writeUInt32BE(std::uint32_t value);
39 void writeInt40BE(std::int64_t value);
40 void writeUInt40BE(std::uint64_t value);
41 void writeInt56BE(std::int64_t value);
42 void writeUInt56BE(std::uint64_t value);
43 void writeInt64BE(std::int64_t value);
44 void writeUInt64BE(std::uint64_t value);
45 void writeVariableLengthUIntBE(std::uint64_t value);
46 void writeFloat32BE(float value);
47 void writeFloat64BE(double value);
48 void writeInt16LE(std::int16_t value);
49 void writeUInt16LE(std::uint16_t value);
50 void writeInt24LE(std::int32_t value);
51 void writeUInt24LE(std::uint32_t value);
52 void writeInt32LE(std::int32_t value);
53 void writeUInt32LE(std::uint32_t value);
54 void writeInt40LE(std::int64_t value);
55 void writeUInt40LE(std::uint64_t value);
56 void writeInt56LE(std::int64_t value);
57 void writeUInt56LE(std::uint64_t value);
58 void writeInt64LE(std::int64_t value);
59 void writeUInt64LE(std::uint64_t value);
60 void writeVariableLengthUIntLE(std::uint64_t value);
61 void writeFloat32LE(float value);
62 void writeFloat64LE(double value);
63 void writeString(const std::string &value);
64 void writeTerminatedString(const std::string &value);
65 void writeLengthPrefixedString(const std::string &value);
66 void writeLengthPrefixedCString(const char *value, std::size_t size);
67 void writeBool(bool value);
68 void writeSynchsafeUInt32BE(std::uint32_t valueToConvertAndWrite);
69 void writeFixed8BE(float valueToConvertAndWrite);
70 void writeFixed16BE(float valueToConvertAndWrite);
71 void writeSynchsafeUInt32LE(std::uint32_t valueToConvertAndWrite);
72 void writeFixed8LE(float valueToConvertAndWrite);
73 void writeFixed16LE(float valueToConvertAndWrite);
74
75 // declare further overloads for write() to ease use of BinaryWriter in templates
76 void write(char oneChar);
77 void write(std::uint8_t oneByte);
78 void write(bool oneBool);
79 void write(const std::string &lengthPrefixedString);
80 void write(std::string_view lengthPrefixedString);
81 void write(const char *lengthPrefixedString);
82 void write(std::int16_t one16BitInt);
83 void write(std::uint16_t one16BitUint);
84 void write(std::int32_t one32BitInt);
85 void write(std::uint32_t one32BitUint);
86 void write(std::int64_t one64BitInt);
87 void write(std::uint64_t one64BitUint);
88 void write(float one32BitFloat);
89 void write(double one64BitFloat);
90
91private:
92 void writeVariableLengthInteger(std::uint64_t size, void (*getBytes)(std::uint64_t, char *));
93
94 std::ostream *m_stream;
95 bool m_ownership;
96 char m_buffer[8];
97};
98
104inline BinaryWriter::BinaryWriter(std::ostream *stream, bool giveOwnership)
105 : m_stream(stream)
106 , m_ownership(giveOwnership)
107{
108}
109
115 : m_stream(other.m_stream)
116 , m_ownership(false)
117{
118}
119
124{
125 if (m_ownership) {
126 delete m_stream;
127 }
128}
129
135inline std::ostream *BinaryWriter::stream()
136{
137 return m_stream;
138}
139
145inline const std::ostream *BinaryWriter::stream() const
146{
147 return m_stream;
148}
149
157inline bool BinaryWriter::hasOwnership() const
158{
159 return m_ownership;
160}
161
170{
171 if (m_stream) {
172 m_ownership = true;
173 }
174}
175
184{
185 m_ownership = false;
186}
187
192{
193 m_stream->flush();
194}
195
199inline bool BinaryWriter::fail() const
200{
201 return m_stream ? m_stream->fail() : false;
202}
203
207inline void BinaryWriter::write(const char *buffer, std::streamsize length)
208{
209 m_stream->write(buffer, length);
210}
211
216inline void BinaryWriter::write(const std::vector<char> &buffer, std::streamsize length)
217{
218 m_stream->write(buffer.data(), length);
219}
220
224inline void BinaryWriter::writeChar(char value)
225{
226 m_buffer[0] = value;
227 m_stream->write(m_buffer, 1);
228}
229
233inline void BinaryWriter::writeByte(std::uint8_t value)
234{
235 m_buffer[0] = *reinterpret_cast<char *>(&value);
236 m_stream->write(m_buffer, 1);
237}
238
242inline void BinaryWriter::writeBool(bool value)
243{
244 writeByte(value ? 1 : 0);
245}
246
250inline void BinaryWriter::writeInt16BE(std::int16_t value)
251{
252 BE::getBytes(value, m_buffer);
253 m_stream->write(m_buffer, sizeof(std::int16_t));
254}
255
259inline void BinaryWriter::writeUInt16BE(std::uint16_t value)
260{
261 BE::getBytes(value, m_buffer);
262 m_stream->write(m_buffer, sizeof(std::uint16_t));
263}
264
269inline void BinaryWriter::writeInt24BE(std::int32_t value)
270{
271 BE::getBytes(value, m_buffer);
272 m_stream->write(m_buffer + 1, 3);
273}
274
279inline void BinaryWriter::writeUInt24BE(std::uint32_t value)
280{
281 // discard most significant byte
282 BE::getBytes(value, m_buffer);
283 m_stream->write(m_buffer + 1, 3);
284}
285
289inline void BinaryWriter::writeInt32BE(std::int32_t value)
290{
291 BE::getBytes(value, m_buffer);
292 m_stream->write(m_buffer, sizeof(std::int32_t));
293}
294
298inline void BinaryWriter::writeUInt32BE(std::uint32_t value)
299{
300 BE::getBytes(value, m_buffer);
301 m_stream->write(m_buffer, sizeof(std::uint32_t));
302}
303
308inline void BinaryWriter::writeInt40BE(std::int64_t value)
309{
310 BE::getBytes(value, m_buffer);
311 m_stream->write(m_buffer + 3, 5);
312}
313
318inline void BinaryWriter::writeUInt40BE(std::uint64_t value)
319{
320 BE::getBytes(value, m_buffer);
321 m_stream->write(m_buffer + 3, 5);
322}
323
328inline void BinaryWriter::writeInt56BE(std::int64_t value)
329{
330 BE::getBytes(value, m_buffer);
331 m_stream->write(m_buffer + 1, 7);
332}
333
338inline void BinaryWriter::writeUInt56BE(std::uint64_t value)
339{
340 BE::getBytes(value, m_buffer);
341 m_stream->write(m_buffer + 1, 7);
342}
343
347inline void BinaryWriter::writeInt64BE(std::int64_t value)
348{
349 BE::getBytes(value, m_buffer);
350 m_stream->write(m_buffer, sizeof(std::int64_t));
351}
352
356inline void BinaryWriter::writeUInt64BE(std::uint64_t value)
357{
358 BE::getBytes(value, m_buffer);
359 m_stream->write(m_buffer, sizeof(std::uint64_t));
360}
361
366inline void BinaryWriter::writeVariableLengthUIntBE(std::uint64_t value)
367{
368 writeVariableLengthInteger(value, static_cast<void (*)(std::uint64_t, char *)>(&BE::getBytes));
369}
370
374inline void BinaryWriter::writeFloat32BE(float value)
375{
376 BE::getBytes(value, m_buffer);
377 m_stream->write(m_buffer, sizeof(float));
378}
379
383inline void BinaryWriter::writeFloat64BE(double value)
384{
385 BE::getBytes(value, m_buffer);
386 m_stream->write(m_buffer, sizeof(double));
387}
388
392inline void BinaryWriter::writeInt16LE(std::int16_t value)
393{
394 LE::getBytes(value, m_buffer);
395 m_stream->write(m_buffer, sizeof(std::int16_t));
396}
397
401inline void BinaryWriter::writeUInt16LE(std::uint16_t value)
402{
403 LE::getBytes(value, m_buffer);
404 m_stream->write(m_buffer, sizeof(std::uint16_t));
405}
406
411inline void BinaryWriter::writeInt24LE(std::int32_t value)
412{
413 // discard most significant byte
414 LE::getBytes(value, m_buffer);
415 m_stream->write(m_buffer, 3);
416}
417
422inline void BinaryWriter::writeUInt24LE(std::uint32_t value)
423{
424 // discard most significant byte
425 LE::getBytes(value, m_buffer);
426 m_stream->write(m_buffer, 3);
427}
428
432inline void BinaryWriter::writeInt32LE(std::int32_t value)
433{
434 LE::getBytes(value, m_buffer);
435 m_stream->write(m_buffer, sizeof(std::int32_t));
436}
437
441inline void BinaryWriter::writeUInt32LE(std::uint32_t value)
442{
443 LE::getBytes(value, m_buffer);
444 m_stream->write(m_buffer, sizeof(std::uint32_t));
445}
446
451inline void BinaryWriter::writeInt40LE(std::int64_t value)
452{
453 LE::getBytes(value, m_buffer);
454 m_stream->write(m_buffer, 5);
455}
456
461inline void BinaryWriter::writeUInt40LE(std::uint64_t value)
462{
463 LE::getBytes(value, m_buffer);
464 m_stream->write(m_buffer, 5);
465}
466
471inline void BinaryWriter::writeInt56LE(std::int64_t value)
472{
473 LE::getBytes(value, m_buffer);
474 m_stream->write(m_buffer, 7);
475}
476
481inline void BinaryWriter::writeUInt56LE(std::uint64_t value)
482{
483 LE::getBytes(value, m_buffer);
484 m_stream->write(m_buffer, 7);
485}
486
490inline void BinaryWriter::writeInt64LE(std::int64_t value)
491{
492 LE::getBytes(value, m_buffer);
493 m_stream->write(m_buffer, sizeof(std::int64_t));
494}
495
499inline void BinaryWriter::writeUInt64LE(std::uint64_t value)
500{
501 LE::getBytes(value, m_buffer);
502 m_stream->write(m_buffer, sizeof(std::uint64_t));
503}
504
509inline void BinaryWriter::writeVariableLengthUIntLE(std::uint64_t value)
510{
511 writeVariableLengthInteger(value, static_cast<void (*)(std::uint64_t, char *)>(&LE::getBytes));
512}
513
517inline void BinaryWriter::writeFloat32LE(float value)
518{
519 LE::getBytes(value, m_buffer);
520 m_stream->write(m_buffer, sizeof(float));
521}
522
526inline void BinaryWriter::writeFloat64LE(double value)
527{
528 LE::getBytes(value, m_buffer);
529 m_stream->write(m_buffer, sizeof(double));
530}
531
535inline void BinaryWriter::writeString(const std::string &value)
536{
537 m_stream->write(value.data(), static_cast<std::streamsize>(value.size()));
538}
539
543inline void BinaryWriter::writeTerminatedString(const std::string &value)
544{
545 m_stream->write(value.data(), static_cast<std::streamsize>(value.size() + 1));
546}
547
555inline void BinaryWriter::writeLengthPrefixedString(const std::string &value)
556{
557 writeVariableLengthUIntBE(value.size());
558 m_stream->write(value.data(), static_cast<std::streamsize>(value.size()));
559}
560
568inline void BinaryWriter::writeLengthPrefixedCString(const char *value, std::size_t size)
569{
571 m_stream->write(value, static_cast<std::streamsize>(size));
572}
573
579inline void BinaryWriter::writeSynchsafeUInt32BE(std::uint32_t valueToConvertAndWrite)
580{
581 writeUInt32BE(toSynchsafeInt(valueToConvertAndWrite));
582}
583
587inline void BinaryWriter::writeFixed8BE(float valueToConvertAndWrite)
588{
589 writeUInt16BE(toFixed8(valueToConvertAndWrite));
590}
591
595inline void BinaryWriter::writeFixed16BE(float valueToConvertAndWrite)
596{
597 writeUInt32BE(toFixed16(valueToConvertAndWrite));
598}
599
605inline void BinaryWriter::writeSynchsafeUInt32LE(std::uint32_t valueToConvertAndWrite)
606{
607 writeUInt32LE(toSynchsafeInt(valueToConvertAndWrite));
608}
609
613inline void BinaryWriter::writeFixed8LE(float valueToConvertAndWrite)
614{
615 writeUInt16LE(toFixed8(valueToConvertAndWrite));
616}
617
621inline void BinaryWriter::writeFixed16LE(float valueToConvertAndWrite)
622{
623 writeUInt32LE(toFixed16(valueToConvertAndWrite));
624}
625
629inline void BinaryWriter::write(char oneChar)
630{
631 writeChar(oneChar);
632}
633
637inline void BinaryWriter::write(std::uint8_t oneByte)
638{
639 writeByte(oneByte);
640}
641
645inline void BinaryWriter::write(bool oneBool)
646{
647 writeBool(oneBool);
648}
649
655inline void BinaryWriter::write(const std::string &lengthPrefixedString)
656{
657 writeLengthPrefixedString(lengthPrefixedString);
658}
659
665inline void BinaryWriter::write(std::string_view lengthPrefixedString)
666{
667 writeLengthPrefixedCString(lengthPrefixedString.data(), lengthPrefixedString.size());
668}
669
675inline void BinaryWriter::write(const char *lengthPrefixedString)
676{
677 writeLengthPrefixedCString(lengthPrefixedString, std::strlen(lengthPrefixedString));
678}
679
683inline void BinaryWriter::write(std::int16_t one16BitInt)
684{
685 writeInt16BE(one16BitInt);
686}
687
691inline void BinaryWriter::write(std::uint16_t one16BitUint)
692{
693 writeUInt16BE(one16BitUint);
694}
695
699inline void BinaryWriter::write(std::int32_t one32BitInt)
700{
701 writeInt32BE(one32BitInt);
702}
703
707inline void BinaryWriter::write(std::uint32_t one32BitUint)
708{
709 writeUInt32BE(one32BitUint);
710}
711
715inline void BinaryWriter::write(std::int64_t one64BitInt)
716{
717 writeInt64BE(one64BitInt);
718}
719
723inline void BinaryWriter::write(std::uint64_t one64BitUint)
724{
725 writeUInt64BE(one64BitUint);
726}
727
731inline void BinaryWriter::write(float one32BitFloat)
732{
733 writeFloat32BE(one32BitFloat);
734}
735
739inline void BinaryWriter::write(double one64BitFloat)
740{
741 writeFloat64BE(one64BitFloat);
742}
743} // namespace CppUtilities
744
745#endif // IO_UTILITIES_BINARYWRITER_H
Writes primitive data types to a std::ostream.
BinaryWriter & operator=(const BinaryWriter &rhs)=delete
void writeVariableLengthUIntBE(std::uint64_t value)
Writes an up to 8 byte long big endian unsigned integer to the current stream and advances the curren...
void writeFloat32LE(float value)
Writes a 32-bit little endian floating point value to the current stream and advances the current pos...
void writeUInt40BE(std::uint64_t value)
Writes a 40-bit big endian unsigned integer to the current stream and advances the current position o...
void writeUInt64LE(std::uint64_t value)
Writes a 64-bit little endian unsigned integer to the current stream and advances the current positio...
void writeFixed16BE(float valueToConvertAndWrite)
Writes the 16.16 fixed point big endian representation for the specified 32-bit floating point value ...
void writeInt40LE(std::int64_t value)
Writes a 40-bit big endian signed integer to the current stream and advances the current position of ...
void writeUInt40LE(std::uint64_t value)
Writes a 40-bit big endian unsigned integer to the current stream and advances the current position o...
void writeInt64BE(std::int64_t value)
Writes a 64-bit big endian signed integer to the current stream and advances the current position of ...
void writeInt32LE(std::int32_t value)
Writes a 32-bit little endian signed integer to the current stream and advances the current position ...
bool hasOwnership() const
Returns whether the writer takes ownership over the assigned stream.
void writeUInt24LE(std::uint32_t value)
Writes a 24-bit little endian unsigned integer to the current stream and advances the current positio...
void writeFloat32BE(float value)
Writes a 32-bit big endian floating point value to the current stream and advances the current positi...
void writeFixed16LE(float valueToConvertAndWrite)
Writes the 16.16 fixed point little endian representation for the specified 32-bit floating point val...
void giveOwnership()
The writer will take ownership over the assigned stream.
bool fail() const
Returns an indication whether the fail bit of the assigned stream is set.
void writeInt24BE(std::int32_t value)
Writes a 24-bit big endian signed integer to the current stream and advances the current position of ...
void writeFixed8LE(float valueToConvertAndWrite)
Writes the 8.8 fixed point little endian representation for the specified 32-bit floating point value...
void writeUInt56BE(std::uint64_t value)
Writes a 56-bit big endian unsigned integer to the current stream and advances the current position o...
void writeUInt32BE(std::uint32_t value)
Writes a 32-bit big endian unsigned integer to the current stream and advances the current position o...
void writeFloat64BE(double value)
Writes a 64-bit big endian floating point value to the current stream and advances the current positi...
void writeFixed8BE(float valueToConvertAndWrite)
Writes the 8.8 fixed point big endian representation for the specified 32-bit floating point value to...
void writeFloat64LE(double value)
Writes a 64-bit little endian floating point value to the current stream and advances the current pos...
void writeString(const std::string &value)
Writes a string to the current stream and advances the current position of the stream by the length o...
void detatchOwnership()
The writer will not take ownership over the assigned stream.
void writeUInt56LE(std::uint64_t value)
Writes a 56-bit big endian unsigned integer to the current stream and advances the current position o...
void writeInt56LE(std::int64_t value)
Writes a 56-bit big endian signed integer to the current stream and advances the current position of ...
const std::ostream * stream() const
Returns a pointer to the stream the writer will write to when calling one of the write-methods.
void writeUInt16BE(std::uint16_t value)
Writes a 16-bit big endian unsigned integer to the current stream and advances the current position o...
void writeUInt64BE(std::uint64_t value)
Writes a 64-bit big endian unsigned integer to the current stream and advances the current position o...
void flush()
Calls the flush() method of the assigned stream.
void writeVariableLengthUIntLE(std::uint64_t value)
Writes an up to 8 byte long little endian unsigned integer to the current stream and advances the cur...
void writeInt56BE(std::int64_t value)
Writes a 56-bit big endian signed integer to the current stream and advances the current position of ...
void writeInt16LE(std::int16_t value)
Writes a 16-bit little endian signed integer to the current stream and advances the current position ...
void writeUInt32LE(std::uint32_t value)
Writes a 32-bit little endian unsigned integer to the current stream and advances the current positio...
BinaryWriter(std::ostream *stream, bool giveOwnership=false)
Constructs a new BinaryWriter.
void writeUInt16LE(std::uint16_t value)
Writes a 16-bit little endian unsigned integer to the current stream and advances the current positio...
void writeInt16BE(std::int16_t value)
Writes a 16-bit big endian signed integer to the current stream and advances the current position of ...
void writeChar(char value)
Writes a single character to the current stream and advances the current position of the stream by on...
void writeSynchsafeUInt32LE(std::uint32_t valueToConvertAndWrite)
Writes a 32-bit little endian synchsafe integer to the current stream and advances the current positi...
void writeByte(std::uint8_t value)
Writes a single byte to the current stream and advances the current position of the stream by one byt...
void writeLengthPrefixedString(const std::string &value)
Writes the length of a string and the string itself to the current stream.
void writeInt24LE(std::int32_t value)
Writes a 24-bit little endian signed integer to the current stream and advances the current position ...
void writeUInt24BE(std::uint32_t value)
Writes a 24-bit big endian unsigned integer to the current stream and advances the current position o...
~BinaryWriter()
Destroys the BinaryWriter.
void write(const char *buffer, std::streamsize length)
Writes a character array to the current stream and advances the current position of the stream by the...
void writeLengthPrefixedCString(const char *value, std::size_t size)
Writes the length of a string and the string itself to the current stream.
void writeTerminatedString(const std::string &value)
Writes a terminated string to the current stream and advances the current position of the stream by t...
void writeInt64LE(std::int64_t value)
Writes a 64-bit little endian signed integer to the current stream and advances the current position ...
void writeSynchsafeUInt32BE(std::uint32_t valueToConvertAndWrite)
Writes a 32-bit big endian synchsafe integer to the current stream and advances the current position ...
void writeInt32BE(std::int32_t value)
Writes a 32-bit big endian signed integer to the current stream and advances the current position of ...
void writeInt40BE(std::int64_t value)
Writes a 40-bit big endian signed integer to the current stream and advances the current position of ...
void writeBool(bool value)
Writes a boolean value to the current stream and advances the current position of the stream by one b...
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
Definition global.h:14
CPP_UTILITIES_EXPORT void getBytes(T value, char *outputbuffer)
Stores the specified (unsigned) integer value in a char array.
CPP_UTILITIES_EXPORT void getBytes(T value, char *outputbuffer)
Stores the specified (unsigned) integer value in a char array.
Contains all utilities provides by the c++utilities library.
CPP_UTILITIES_EXPORT constexpr std::uint32_t toFixed16(float float32value)
Returns the 16.16 fixed point representation converted from the specified 32-bit floating point numbe...
CPP_UTILITIES_EXPORT constexpr std::uint16_t toFixed8(float float32value)
Returns the 8.8 fixed point representation converted from the specified 32-bit floating point number.
CPP_UTILITIES_EXPORT constexpr std::uint32_t toSynchsafeInt(std::uint32_t normalInt)
Returns a 32-bit synchsafe integer converted from a normal 32-bit integer.