Ocean
Loading...
Searching...
No Matches
Bitstream.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_IO_BITSTREAM_H
9#define META_OCEAN_IO_BITSTREAM_H
10
11#include "ocean/io/IO.h"
12
13#include <istream>
14#include <ostream>
15
16namespace Ocean
17{
18
19namespace IO
20{
21
22/**
23 * This class implements an input bitstream.
24 * The implementation of the input bitstream is not thread-safe, thus ensure that the internal input stream object is not used within several threads concurrently.<br>
25 * The following data types are supported:
26 * <pre>
27 * Data type: Number of bytes: Description:
28 * bool 1
29 * char 1
30 * wchar_t 4 Depending on the platform wchar_t has 1, 2 or 4 bytes thus this stream object stores 4 bytes per wchar_t object (see also std::wstring)
31 * unsigned char 1
32 * short 2
33 * unsigned short 2
34 * int 4
35 * unsigned int 4
36 * float 4
37 * double 8
38 * long long 8
39 * unsigned long long 8
40 * std::string 4 + 1 * size Four bytes for the size of the string and 1 byte for each character
41 * std::wstring 4 + 4 * size Four bytes for the size of the string and 4 bytes for each character
42 * </pre>
43 * The following data types are not supported as they have individual size on individual platforms and thus must not be used:
44 * <pre>
45 * Data type: Description:
46 * size_t size_t has 4 bytes on 32 bit platforms and 8 bytes on 64 bit platforms
47 * </pre>
48 * @ingroup io
49 */
50class OCEAN_IO_EXPORT InputBitstream
51{
52 public:
53
54 /**
55 * Creates a new bitstream object.
56 * @param stream The input stream object that is encapsulated by this object
57 */
58 explicit InputBitstream(std::istream& stream);
59
60 /**
61 * Reads a value from the bitstream and moves the internal position inside the bitstream accordingly.
62 * If the read process fails, the new position of the bitstream may be arbitrary.<br>
63 * Beware: It's recommended to provide the template argument explicitly to avoid type ambiguities.<br>
64 * @param value The resulting value that is read
65 * @return True, if the value could be read successfully
66 * @tparam T The data type that is read, ensure that only supported data types are applied
67 * @see readDefault().
68 */
69 template <typename T>
70 bool read(T& value);
71
72 /**
73 * Reads a value from the bitstream and moves the internal position inside the bitstream accordingly.
74 * If the read process fails, the new position of the bitstream may be arbitrary.<br>
75 * This function does not provide a success value but returns a given default value if the read process fails.<br>
76 * Beware: It's recommended to provide the template argument explicitly to avoid type ambiguities.<br>
77 * @param defaultValue The default value that is returned if the read process fails
78 * @return The resulting value that has been read
79 * @tparam T The data type that is read, ensure that only supported data types are applied
80 * @see read().
81 */
82 template <typename T>
83 T readDefault(const T& defaultValue);
84
85 /**
86 * Reads a defined memory block from the stream into a given buffer and moves the internal position inside the bitstream accordingly.
87 * If the read process fails, the new position of the bitstream may be arbitrary.
88 * @param data The buffer that will receive the memory block, ensure that this buffer is large enough, may be nullptr if size is 0
89 * @param size The number of bytes that will be read into the memory block, with range [0, infinity)
90 * @return True, if succeeded
91 */
92 bool read(void* data, const size_t size);
93
94 /**
95 * Reads a value from the bitstream but does not move the internal position inside the bitstream.
96 * Beware: It's recommended to provide the template argument explicitly to avoid type ambiguities.<br>
97 * @param value The resulting value that is looked-up
98 * @return True, if the value could be looked-up successfully
99 * @tparam T The data type that is read, ensure that only supported data types are applied
100 */
101 template <typename T>
102 bool look(T& value);
103
104 /**
105 * Returns the current position inside the bitstream, in bytes counting from the beginning of the stream.
106 * @return The current stream position in bytes, -1 if the current position cannot be determined
107 */
108 uint64_t position() const;
109
110 /**
111 * Returns the current size of the bitstream, in bytes.
112 * @return The current stream size in bytes, -1 if the current size cannot be determined
113 */
114 uint64_t size() const;
115
116 /**
117 * Sets the current position inside the bitstream explicitly.
118 * @param position The new position inside the bitstream, in bytes counting from the beginning of the stream; with range [0, size()]
119 * @return True, if succeeded
120 */
121 bool setPosition(const uint64_t position);
122
123 /**
124 * Skips a specified number of bytes in the bitstream by moving the position forward.
125 * @param bytes The number of bytes to skip, with range [0, infinity)
126 * @return True, if succeeded
127 */
128 bool skip(const uint64_t bytes);
129
130 /**
131 * Returns whether the previous read attempt failed because the end of the stream has been reached.
132 * @return True, if the end of the stream has been reached (after the a read attempt has failed)
133 * @see reset().
134 */
135 bool isEndOfFile() const;
136
137 /**
138 * Resets the stream after the stream has reached the end of the stream.
139 * The position will be set to the beginning of the stream.
140 * @return True, if succeeded
141 * @see isEndOfFile().
142 */
143 bool reset();
144
145 /**
146 * Returns whether this bitstream object is valid and can be used.
147 * @return True, if so
148 */
149 explicit inline operator bool() const;
150
151 protected:
152
153 /// The internal input stream object that this object encapsulates.
154 std::istream& inputStream_;
155};
156
157/**
158 * This class implements a scoped input bitstream that allows to read content from a bitstream while the stream position is restored if this object is disposed.
159 * The implementation of this scoped input bitstream object is not thread-safe.
160 * @see InputBitstream
161 * @ingroup io
162 */
164{
165 public:
166
167 /**
168 * Creates a new scoped input bitstream object from a given input bitstream object and stores the current stream position of the given stream object.
169 * @param stream The input bitstream object that is encapsulated by this object
170 */
171 inline ScopedInputBitstream(InputBitstream& stream);
172
173 /**
174 * Destructs this scoped object and restores the stream position of the original input bitstream object.
175 */
176 inline ~ScopedInputBitstream();
177
178 protected:
179
180 /**
181 * Deleted copy constructor.
182 */
184
185 /**
186 * Deleted move constructor.
187 */
189
190 /**
191 * Deleted copy operator.
192 * @return Reference to this object
193 */
195
196 /**
197 * Deleted move operator.
198 * @return Reference to this object
199 */
201
202 protected:
203
204 /// The original stream position of the original bitstream object.
205 uint64_t streamStartPosition_ = uint64_t(-1);
206};
207
208/**
209 * This class implements an output bitstream.
210 * The implementation of the output bitstream is not thread-safe, thus ensure that the internal output stream object is not used within several threads concurrently.<br>
211 * The bitstream supports specific data types, see InputBitstream for detailed information.
212 * @ingroup io
213 */
214class OCEAN_IO_EXPORT OutputBitstream
215{
216 public:
217
218 /**
219 * Creates a new output bitstream object.
220 * @param stream The output stream object that is encapsulated by this object
221 */
222 explicit OutputBitstream(std::ostream& stream);
223
224 /**
225 * Writes a data object to the stream and moves the internal position inside the bitstream accordingly.
226 * If the write process fails, the new position of the bitstream may be arbitrary.<br>
227 * Beware: It's recommended to provide the template argument explicitly to avoid type ambiguities.<br>
228 * @param value The value that will be written
229 * @return True, if the value could be written successfully
230 * @tparam T the data type that is written, ensure that only supported data types are applied
231 */
232 template <typename T>
233 bool write(const T& value);
234
235 /**
236 * Writes a defined memory block from a given buffer into the stream and moves the internal position inside the bitstream accordingly.
237 * If the write process fails, the new position of the bitstream may be arbitrary.
238 * @param data The buffer that will be written, may be nullptr if size is 0
239 * @param size The number of bytes that will be written, with range [0, infinity)
240 * @return True, if succeeded
241 */
242 bool write(const void* data, const size_t size);
243
244 /**
245 * Returns the current size of the bitstream, in bytes.
246 * @return The current stream size in bytes, -1 if the current size cannot be determined
247 */
248 uint64_t size() const;
249
250 /**
251 * Returns whether this bitstream object is valid and can be used.
252 * @return True, if so
253 */
254 explicit inline operator bool() const;
255
256 protected:
257
258 /// The internal output stream object that this object encapsulates.
259 std::ostream& outputStream_;
260};
261
262/**
263 * This class implements a tag that allows to identify specific objects in an input/output stream.
264 * A tag is a 64-bit identifier that identifies one unique object type.
265 * @ingroup io
266 */
267class OCEAN_IO_EXPORT Tag
268{
269 protected:
270
271#ifdef OCEAN_DEBUG
272
273 /**
274 * This class implements a tag manager that allows to ensure that tags are not defined twice.
275 */
277 {
278 protected:
279
280 /**
281 * Definition of a set holding tag values.
282 */
283 using TagSet = std::unordered_set<unsigned long long>;
284
285 public:
286
287 /**
288 * Registers a new tag value.
289 * @param tag The tag value that will be registered
290 * @return True, if the tag value hasn't been registered before
291 */
292 static inline bool registerTag(const unsigned long long tag);
293
294 protected:
295
296 /// The set of registered tag values.
298 };
299
300#endif // OCEAN_DEBUG
301
302 public:
303
304 /**
305 * Creates a new invalid tag object.
306 */
307 inline Tag();
308
309 /**
310 * Creates a new tag object by a given eight character string.
311 * Use this constructor only for the definition of a tag.
312 * @param tagString A string with exactly eight characters which are used to define the unique tag value
313 */
314 inline explicit Tag(const char tagString[8]);
315
316 /**
317 * Returns whether two tag objects are identical.
318 * @param tag The second tag to be compared
319 * @return True, if so
320 */
321 inline bool operator==(const Tag& tag) const;
322
323 /**
324 * Returns whether two tag objects are not identical.
325 * @param tag The second tag to be compared
326 * @return True, if so
327 */
328 inline bool operator!=(const Tag& tag) const;
329
330 /**
331 * Returns the unique 64 bit tag value of this tag object.
332 * @return The tag value
333 */
334 inline unsigned long long value() const;
335
336 /**
337 * Returns the unique 64 bit tag value of this tag object.
338 * @return The tag value
339 */
340 inline unsigned long long& value();
341
342 /**
343 * Writes a tag to a bitstream.
344 * @param bitstream The bitstream to which the tag is written
345 * @param tag The tag to be written
346 * @return True, if succeeded
347 */
348 static bool writeTag(OutputBitstream& bitstream, const Tag& tag);
349
350 /**
351 * Reads a tag from a bitstream.
352 * The position in the bitstream is moved forward after the tag has been read.<br>
353 * @param bitstream The bitstream from which the tag is read
354 * @param tag The resulting bitstream
355 * @return True, if succeeded
356 */
357 static bool readTag(InputBitstream& bitstream, Tag& tag);
358
359 /**
360 * Reads (only a look) a tag from a bitstream.
361 * The position in the bitstream is not modified.<br>
362 * @param bitstream The bitstream from which the tag is read
363 * @param tag The resulting bitstream
364 * @return True, if succeeded
365 */
366 static bool lookTag(InputBitstream& bitstream, Tag& tag);
367
368 /**
369 * Reads a tag from a bitstream and checks whether the tag is identical with an expectedTag tag.<br>
370 * The position in the bitstream is moved forward after the tag has been read.<br>
371 * @param bitstream The bitstream from which the tag is read
372 * @param expectedTag The expected tag that should match the tag that has been read
373 * @return True, if received tag and the expected tag are identical
374 */
375 static bool readAndCheckTag(InputBitstream& bitstream, const Tag& expectedTag);
376
377 /**
378 * Reads (only a look) a tag from a bitstream and checks whether the tag is identical with an expectedTag tag.<br>
379 * The position in the bitstream is not modified.<br>
380 * @param bitstream The bitstream from which the tag is read
381 * @param expectedTag The expected tag that should match the tag that has been read
382 * @return True, if received tag and the expected tag are identical
383 */
384 static bool lookAndCheckTag(InputBitstream& bitstream, const Tag& expectedTag);
385
386 /**
387 * Converts a string with exactly eight characters to a unique tag value.
388 * @param tagString The string with eight characters to be converted
389 * @return The resulting tag value
390 */
391 static constexpr unsigned long long string2tag(const char tagString[8]);
392
393 protected:
394
395 /// The tag value of this tag object.
396 unsigned long long tagValue_;
397};
398
404
406{
407 if (streamStartPosition_ != uint64_t(-1))
408 {
410 }
411}
412
413inline InputBitstream::operator bool() const
414{
415 return inputStream_.good();
416}
417
418inline OutputBitstream::operator bool() const
419{
420 return outputStream_.good();
421}
422
423inline Tag::Tag() :
424 tagValue_(0ull)
425{
426 // nothing to do here
427}
428
429inline Tag::Tag(const char tagString[8]) :
430 tagValue_(string2tag(tagString))
431{
432 ocean_assert(TagManager::registerTag(tagValue_));
433}
434
435inline bool Tag::operator==(const Tag& tag) const
436{
437 return tagValue_ == tag.tagValue_;
438}
439
440inline bool Tag::operator!=(const Tag& tag) const
441{
442 return !(*this == tag);
443}
444
445inline unsigned long long Tag::value() const
446{
447 return tagValue_;
448}
449
450inline unsigned long long& Tag::value()
451{
452 return tagValue_;
453}
454
455constexpr unsigned long long Tag::string2tag(const char tagString[8])
456{
457 ocean_assert(tagString[0] != 0 && tagString[1] != 0 && tagString[2] != 0 && tagString[3] != 0
458 && tagString[4] != 0 && tagString[5] != 0 && tagString[6] != 0 && tagString[7] != 0);
459
460 return ((unsigned long long)tagString[0] << 0ull)
461 | ((unsigned long long)tagString[1] << 8ull)
462 | ((unsigned long long)tagString[2] << 16ull)
463 | ((unsigned long long)tagString[3] << 24ull)
464 | ((unsigned long long)tagString[4] << 32ull)
465 | ((unsigned long long)tagString[5] << 40ull)
466 | ((unsigned long long)tagString[6] << 48ull)
467 | ((unsigned long long)tagString[7] << 56ull);
468}
469
470#ifdef OCEAN_DEBUG
471
472inline bool Tag::TagManager::registerTag(const unsigned long long tag)
473{
474 static TagManager manager;
475
476 const bool newTag = manager.tagsSet_.find(tag) == manager.tagsSet_.end();
477 manager.tagsSet_.insert(tag);
478
479 return newTag;
480}
481
482#endif // OCEAN_DEBUG
483
484}
485
486}
487
488#endif // META_OCEAN_IO_BITSTREAM_H
This class implements an input bitstream.
Definition Bitstream.h:51
T readDefault(const T &defaultValue)
Reads a value from the bitstream and moves the internal position inside the bitstream accordingly.
uint64_t size() const
Returns the current size of the bitstream, in bytes.
bool read(T &value)
Reads a value from the bitstream and moves the internal position inside the bitstream accordingly.
uint64_t position() const
Returns the current position inside the bitstream, in bytes counting from the beginning of the stream...
bool reset()
Resets the stream after the stream has reached the end of the stream.
bool read(void *data, const size_t size)
Reads a defined memory block from the stream into a given buffer and moves the internal position insi...
bool isEndOfFile() const
Returns whether the previous read attempt failed because the end of the stream has been reached.
InputBitstream(std::istream &stream)
Creates a new bitstream object.
std::istream & inputStream_
The internal input stream object that this object encapsulates.
Definition Bitstream.h:154
bool skip(const uint64_t bytes)
Skips a specified number of bytes in the bitstream by moving the position forward.
bool look(T &value)
Reads a value from the bitstream but does not move the internal position inside the bitstream.
bool setPosition(const uint64_t position)
Sets the current position inside the bitstream explicitly.
This class implements an output bitstream.
Definition Bitstream.h:215
uint64_t size() const
Returns the current size of the bitstream, in bytes.
OutputBitstream(std::ostream &stream)
Creates a new output bitstream object.
bool write(const void *data, const size_t size)
Writes a defined memory block from a given buffer into the stream and moves the internal position ins...
std::ostream & outputStream_
The internal output stream object that this object encapsulates.
Definition Bitstream.h:259
bool write(const T &value)
Writes a data object to the stream and moves the internal position inside the bitstream accordingly.
This class implements a scoped input bitstream that allows to read content from a bitstream while the...
Definition Bitstream.h:164
~ScopedInputBitstream()
Destructs this scoped object and restores the stream position of the original input bitstream object.
Definition Bitstream.h:405
ScopedInputBitstream & operator=(ScopedInputBitstream &&)=delete
Deleted move operator.
uint64_t streamStartPosition_
The original stream position of the original bitstream object.
Definition Bitstream.h:205
ScopedInputBitstream & operator=(const ScopedInputBitstream &)=delete
Deleted copy operator.
ScopedInputBitstream(ScopedInputBitstream &&)=delete
Deleted move constructor.
ScopedInputBitstream(const ScopedInputBitstream &)=delete
Deleted copy constructor.
ScopedInputBitstream(InputBitstream &stream)
Creates a new scoped input bitstream object from a given input bitstream object and stores the curren...
Definition Bitstream.h:399
This class implements a tag manager that allows to ensure that tags are not defined twice.
Definition Bitstream.h:277
std::unordered_set< unsigned long long > TagSet
Definition of a set holding tag values.
Definition Bitstream.h:283
static bool registerTag(const unsigned long long tag)
Registers a new tag value.
Definition Bitstream.h:472
TagSet tagsSet_
The set of registered tag values.
Definition Bitstream.h:297
This class implements a tag that allows to identify specific objects in an input/output stream.
Definition Bitstream.h:268
static bool writeTag(OutputBitstream &bitstream, const Tag &tag)
Writes a tag to a bitstream.
static constexpr unsigned long long string2tag(const char tagString[8])
Converts a string with exactly eight characters to a unique tag value.
Definition Bitstream.h:455
static bool lookTag(InputBitstream &bitstream, Tag &tag)
Reads (only a look) a tag from a bitstream.
static bool lookAndCheckTag(InputBitstream &bitstream, const Tag &expectedTag)
Reads (only a look) a tag from a bitstream and checks whether the tag is identical with an expectedTa...
static bool readAndCheckTag(InputBitstream &bitstream, const Tag &expectedTag)
Reads a tag from a bitstream and checks whether the tag is identical with an expectedTag tag.
bool operator==(const Tag &tag) const
Returns whether two tag objects are identical.
Definition Bitstream.h:435
unsigned long long value() const
Returns the unique 64 bit tag value of this tag object.
Definition Bitstream.h:445
bool operator!=(const Tag &tag) const
Returns whether two tag objects are not identical.
Definition Bitstream.h:440
Tag()
Creates a new invalid tag object.
Definition Bitstream.h:423
static bool readTag(InputBitstream &bitstream, Tag &tag)
Reads a tag from a bitstream.
unsigned long long tagValue_
The tag value of this tag object.
Definition Bitstream.h:396
The namespace covering the entire Ocean framework.
Definition Accessor.h:15