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 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 unsigned long long 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 unsigned long long 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 unsigned long long position);
122
123 /**
124 * Returns whether this bitstream object is valid and can be used.
125 * @return True, if so
126 */
127 explicit inline operator bool() const;
128
129 protected:
130
131 /// The internal input stream object that this object encapsulates.
132 std::istream& inputStream;
133};
134
135/**
136 * 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.
137 * The implementation of this scoped input bitstream object is not thread-safe.
138 * @see InputBitstream
139 * @ingroup io
140 */
142{
143 public:
144
145 /**
146 * Creates a new scoped input bitstream object from a given input bitstream object and stores the current stream position of the given stream object.
147 */
148 inline ScopedInputBitstream(InputBitstream& stream);
149
150 /**
151 * Destructs this scoped object and restores the stream position of the original input bitstream object.
152 */
153 inline ~ScopedInputBitstream();
154
155 protected:
156
157 /// The original stream position of the original bitstream object.
158 unsigned long long streamStartPosition_;
159};
160
161/**
162 * This class implements an output bitstream.
163 * 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>
164 * The bitstream support specific data type, see InputBitstream for detailed information.
165 * @ingroup io
166 */
167class OCEAN_IO_EXPORT OutputBitstream
168{
169 public:
170
171 /**
172 * Creates a new output bitstream object.
173 * @param stream The output stream object that is encapsulated by this object
174 */
175 OutputBitstream(std::ostream& stream);
176
177 /**
178 * Writes a data object to the stream and moves the internal position inside the bitstream accordingly.
179 * If the write process fails, the new position of the bitstream may be arbitrary.<br>
180 * Beware: It's recommended to provide the template argument explicitly to avoid type ambiguities.<br>
181 * @param value The value that will be written
182 * @return True, if the value could be written successfully
183 * @tparam T the data type that is written, ensure that only supported data types are applied
184 */
185 template <typename T>
186 bool write(const T& value);
187
188 /**
189 * Writes a defined memory block from a given buffer into the stream and moves the internal position inside the bitstream accordingly.
190 * If the write process fails, the new position of the bitstream may be arbitrary.
191 * @param data The buffer that will be written, may be nullptr if size is 0
192 * @param size The number of bytes that will be written, with range [0, infinity
193 * @return True, if succeeded
194 */
195 bool write(const void* data, const size_t size);
196
197 /**
198 * Returns the current size of the bitstream, in bytes.
199 * @return The current stream size in bytes, -1 if the current size cannot be determined
200 */
201 unsigned long long size() const;
202
203 /**
204 * Returns whether this bitstream object is valid and can be used.
205 * @return True, if so
206 */
207 explicit inline operator bool() const;
208
209 protected:
210
211 /// The internal output stream object that this object encapsulates.
212 std::ostream& outputStream;
213};
214
215/**
216 * This class implements a tag that allows to identify specific objects in an input/output stream.
217 * A tag is an 64bit identifier that identifies one unique object type.<br>
218 * @ingroup io
219 */
220class OCEAN_IO_EXPORT Tag
221{
222 protected:
223
224#ifdef OCEAN_DEBUG
225
226 /**
227 * This class implements a tag manager that allows to ensure that tags are not defined twice.
228 */
230 {
231 protected:
232
233 /**
234 * Definition of a set holding tag values.
235 */
236 typedef std::set<unsigned long long> TagSet;
237
238 public:
239
240 /**
241 * Registers a new tag value.
242 * @param tag The tag value that will be registered
243 * @return True, if the tag value hasn't been registered before
244 */
245 static inline bool registerTag(const unsigned long long tag);
246
247 protected:
248
249 /// The set of registered tag values.
251 };
252
253#endif // OCEAN_DEBUG
254
255 public:
256
257 /**
258 * Creates a new invalid tag object.
259 */
260 inline Tag();
261
262 /**
263 * Creates a new tag object by a given eight character string.
264 * Use this constructor only for the definition of a tag.
265 * @param tagString A string with exactly eight characters which are used to define the unique tag value
266 */
267 inline explicit Tag(const char tagString[8]);
268
269 /**
270 * Returns whether two tag objects are identical.
271 * @param tag The second tag to be compared
272 * @return True, if so
273 */
274 inline bool operator==(const Tag& tag) const;
275
276 /**
277 * Returns whether two tag objects are not identical.
278 * @param tag The second tag to be compared
279 * @return True, if so
280 */
281 inline bool operator!=(const Tag& tag) const;
282
283 /**
284 * Returns the unique 64 bit tag value of this tag object.
285 * @return The tag value
286 */
287 inline unsigned long long value() const;
288
289 /**
290 * Returns the unique 64 bit tag value of this tag object.
291 * @return The tag value
292 */
293 inline unsigned long long& value();
294
295 /**
296 * Writes a tag to a bitstream.
297 * @param bitstream The bitstream to which the tag is written
298 * @param tag The tag to be written
299 * @return True, if succeeded
300 */
301 static bool writeTag(OutputBitstream& bitstream, const Tag& tag);
302
303 /**
304 * Reads a tag from a bitstream.
305 * The position in the bitstream is moved forward after the tag has been read.<br>
306 * @param bitstream The bitstream from which the tag is read
307 * @param tag The resulting bitstream
308 * @return True, if succeeded
309 */
310 static bool readTag(InputBitstream& bitstream, Tag& tag);
311
312 /**
313 * Reads (only a look) a tag from a bitstream.
314 * The position in the bitstream is not modified.<br>
315 * @param bitstream The bitstream from which the tag is read
316 * @param tag The resulting bitstream
317 * @return True, if succeeded
318 */
319 static bool lookTag(InputBitstream& bitstream, Tag& tag);
320
321 /**
322 * Reads a tag from a bitstream and checks whether the tag is identical with an expectedTag tag.<br>
323 * The position in the bitstream is moved forward after the tag has been read.<br>
324 * @param bitstream The bitstream from which the tag is read
325 * @param expectedTag The expected tag that should match the tag that has been read
326 * @return True, if received tag and the expected tag are identical
327 */
328 static bool readAndCheckTag(InputBitstream& bitstream, const Tag& expectedTag);
329
330 /**
331 * Reads (only a look) a tag from a bitstream and checks whether the tag is identical with an expectedTag tag.<br>
332 * The position in the bitstream is not modified.<br>
333 * @param bitstream The bitstream from which the tag is read
334 * @param expectedTag The expected tag that should match the tag that has been read
335 * @return True, if received tag and the expected tag are identical
336 */
337 static bool lookAndCheckTag(InputBitstream& bitstream, const Tag& expectedTag);
338
339 /**
340 * Converts a string with exactly eight characters to a unique tag value.
341 * @param tagString The string with eight characters to be converted
342 * @return The resulting tag value
343 */
344 static constexpr unsigned long long string2tag(const char tagString[8]);
345
346 protected:
347
348 /// The tag value of this tag object.
349 unsigned long long tagValue_;
350};
351
353 InputBitstream(stream),
354 streamStartPosition_((unsigned long long)(-1))
355{
357}
358
360{
361 if (streamStartPosition_ != (unsigned long long)(-1))
362 {
364 }
365}
366
367inline InputBitstream::operator bool() const
368{
369 return inputStream.good();
370}
371
372inline OutputBitstream::operator bool() const
373{
374 return outputStream.good();
375}
376
377inline Tag::Tag() :
378 tagValue_(0ull)
379{
380 // nothing to do here
381}
382
383inline Tag::Tag(const char tagString[8]) :
384 tagValue_(string2tag(tagString))
385{
386 ocean_assert(TagManager::registerTag(tagValue_));
387}
388
389inline bool Tag::operator==(const Tag& tag) const
390{
391 return tagValue_ == tag.tagValue_;
392}
393
394inline bool Tag::operator!=(const Tag& tag) const
395{
396 return !(*this == tag);
397}
398
399inline unsigned long long Tag::value() const
400{
401 return tagValue_;
402}
403
404inline unsigned long long& Tag::value()
405{
406 return tagValue_;
407}
408
409constexpr unsigned long long Tag::string2tag(const char tagString[8])
410{
411 ocean_assert(tagString[0] != 0 && tagString[1] != 0 && tagString[2] != 0 && tagString[3] != 0
412 && tagString[4] != 0 && tagString[5] != 0 && tagString[6] != 0 && tagString[7] != 0);
413
414 return ((unsigned long long)tagString[0] << 0ull)
415 | ((unsigned long long)tagString[1] << 8ull)
416 | ((unsigned long long)tagString[2] << 16ull)
417 | ((unsigned long long)tagString[3] << 24ull)
418 | ((unsigned long long)tagString[4] << 32ull)
419 | ((unsigned long long)tagString[5] << 40ull)
420 | ((unsigned long long)tagString[6] << 48ull)
421 | ((unsigned long long)tagString[7] << 56ull);
422}
423
424#ifdef OCEAN_DEBUG
425
426inline bool Tag::TagManager::registerTag(const unsigned long long tag)
427{
428 static TagManager manager;
429
430 const bool newTag = manager.tagsSet.find(tag) == manager.tagsSet.end();
431 manager.tagsSet.insert(tag);
432
433 return newTag;
434}
435
436#endif // OCEAN_DEBUG
437
438}
439
440}
441
442#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.
std::istream & inputStream
The internal input stream object that this object encapsulates.
Definition Bitstream.h:132
bool read(T &value)
Reads a value from the bitstream and moves the internal position inside the bitstream accordingly.
unsigned long long position() const
Returns the current position inside the bitstream, in bytes counting from the beginning 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...
unsigned long long size() const
Returns the current size of the bitstream, in bytes.
InputBitstream(std::istream &stream)
Creates a new bitstream object.
bool look(T &value)
Reads a value from the bitstream but does not move the internal position inside the bitstream.
bool setPosition(const unsigned long long position)
Sets the current position inside the bitstream explicitly.
This class implements an output bitstream.
Definition Bitstream.h:168
unsigned long long 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...
bool write(const T &value)
Writes a data object to the stream and moves the internal position inside the bitstream accordingly.
std::ostream & outputStream
The internal output stream object that this object encapsulates.
Definition Bitstream.h:212
This class implements a scoped input bitstream that allows to read content from a bitstream while the...
Definition Bitstream.h:142
~ScopedInputBitstream()
Destructs this scoped object and restores the stream position of the original input bitstream object.
Definition Bitstream.h:359
unsigned long long streamStartPosition_
The original stream position of the original bitstream object.
Definition Bitstream.h:158
ScopedInputBitstream(InputBitstream &stream)
Creates a new scoped input bitstream object from a given input bitstream object and stores the curren...
Definition Bitstream.h:352
This class implements a tag manager that allows to ensure that tags are not defined twice.
Definition Bitstream.h:230
std::set< unsigned long long > TagSet
Definition of a set holding tag values.
Definition Bitstream.h:236
TagSet tagsSet
The set of registered tag values.
Definition Bitstream.h:250
static bool registerTag(const unsigned long long tag)
Registers a new tag value.
Definition Bitstream.h:426
This class implements a tag that allows to identify specific objects in an input/output stream.
Definition Bitstream.h:221
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:409
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:389
unsigned long long value() const
Returns the unique 64 bit tag value of this tag object.
Definition Bitstream.h:399
bool operator!=(const Tag &tag) const
Returns whether two tag objects are not identical.
Definition Bitstream.h:394
Tag()
Creates a new invalid tag object.
Definition Bitstream.h:377
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:349
The namespace covering the entire Ocean framework.
Definition Accessor.h:15