Zserio C++17 runtime library 1.3.0
Built for Zserio 2.20.0
Loading...
Searching...
No Matches
BitStreamReader.h
Go to the documentation of this file.
1#ifndef ZSERIO_BIT_STREAM_READER_H_INC
2#define ZSERIO_BIT_STREAM_READER_H_INC
3
4#include <algorithm>
5#include <cstddef>
6#include <type_traits>
7
8#include "zserio/BitBuffer.h"
9#include "zserio/Bytes.h"
10#include "zserio/RebindAlloc.h"
11#include "zserio/String.h"
12#include "zserio/Types.h"
13
14namespace zserio
15{
16
21{
22public:
23 static constexpr size_t MAX_INITIAL_ARRAY_ALLOCATION = 128 * 1024;
24
36 explicit ArrayPreallocation(size_t alloc) :
37 allocation(alloc)
38 {}
42 operator size_t() const
43 {
44 return allocation;
45 }
46
47private:
48 size_t allocation;
49};
50
55{
56public:
59
101
109 explicit BitStreamReader(
110 const uint8_t* buffer, size_t bufferByteSize, ArrayPreallocation maxArrayPrealloc = {});
111
119
127 explicit BitStreamReader(
128 Span<const uint8_t> buffer, size_t bufferBitSize, ArrayPreallocation maxArrayPrealloc = {});
129
137 explicit BitStreamReader(
138 const uint8_t* buffer, size_t bufferBitSize, BitsTag, ArrayPreallocation maxArrayPrealloc = {});
139
146 template <typename ALLOC>
150
154 ~BitStreamReader() = default;
155
163 uint32_t readUnsignedBits32(uint8_t numBits = 32);
164
172 uint64_t readUnsignedBits64(uint8_t numBits = 64);
173
181 int32_t readSignedBits32(uint8_t numBits = 32);
182
190 int64_t readSignedBits64(uint8_t numBits = 64);
191
197 Bool readBool();
198
205
212
219
226
233
240
247
254
261
268
275
282
290 template <typename ALLOC = std::allocator<uint8_t>>
292 {
293 const size_t len = static_cast<size_t>(readVarSize());
295 if (beginBitPosition + 8ULL * len > getBufferBitSize())
296 {
297 throw CppRuntimeException("BitStreamReader: Byte array size exceeds available buffer!");
298 }
299 if ((beginBitPosition & 0x07U) != 0)
300 {
301 // we are not aligned to byte
303 value.reserve(len);
304 for (size_t i = 0; i < len; ++i)
305 {
306 value.push_back(readByte());
307 }
308 return value;
309 }
310 else
311 {
312 // we are aligned to byte
316 }
317 }
318
326 template <typename ALLOC = std::allocator<char>>
328 {
329 const size_t len = static_cast<size_t>(readVarSize());
331 if (beginBitPosition + 8ULL * len > getBufferBitSize())
332 {
333 throw CppRuntimeException("BitStreamReader: Byte array size exceeds available buffer!");
334 }
335 if ((beginBitPosition & 0x07U) != 0)
336 {
337 // we are not aligned to byte
339 value.reserve(len);
340 for (size_t i = 0; i < len; ++i)
341 {
342 const char readCharacter = std::char_traits<char>::to_char_type(
343 static_cast<std::char_traits<char>::int_type>(readByte()));
344 value.push_back(readCharacter);
345 }
346 return value;
347 }
348 else
349 {
350 // we are aligned to byte
354 }
355 }
356
364 template <typename ALLOC = std::allocator<uint8_t>>
366 {
367 const size_t bitSize = static_cast<size_t>(readVarSize());
369 if (beginBitPosition + static_cast<uint64_t>(bitSize) > getBufferBitSize())
370 {
371 throw CppRuntimeException("BitStreamReader: Byte array size exceeds available buffer!");
372 }
373 const size_t numBytesToRead = bitSize / 8;
374 const uint8_t numRestBits = static_cast<uint8_t>(bitSize - numBytesToRead * 8);
376 Span<uint8_t> buffer = bitBuffer.getData();
377 const Span<uint8_t>::iterator itEnd = buffer.begin() + numBytesToRead;
378 if ((beginBitPosition & 0x07U) != 0)
379 {
380 // we are not aligned to byte
381 for (Span<uint8_t>::iterator it = buffer.begin(); it != itEnd; ++it)
382 {
383 *it = static_cast<uint8_t>(readUnsignedBits32(8));
384 }
385 }
386 else
387 {
388 // we are aligned to byte
391 (void)std::copy(sourceIt, sourceIt + numBytesToRead, buffer.begin());
392 }
393
394 if (numRestBits > 0)
395 {
396 *itEnd = static_cast<uint8_t>(readUnsignedBits32(numRestBits) << (8U - numRestBits));
397 }
398
399 return bitBuffer;
400 }
401
408 {
409 return m_context.bitIndex;
410 }
411
418
424 void alignTo(size_t alignment);
425
431 size_t getBufferBitSize() const
432 {
433 return m_context.bufferBitSize;
434 }
435
442 {
443 return m_context.maxArrayPreallocation;
444 }
445
446private:
447 uint8_t readByte();
448
449 ReaderContext m_context;
450};
451
452namespace detail
453{
454
455inline void read(BitStreamReader& reader, Bool& value)
456{
457 value = reader.readBool();
458}
459
460template <BitSize BIT_SIZE, bool IS_SIGNED>
461void read(BitStreamReader& reader, FixedIntWrapper<BIT_SIZE, IS_SIGNED>& value)
462{
463 using ValueType = typename FixedIntWrapper<BIT_SIZE, IS_SIGNED>::ValueType;
464 // TODO[Mi-L@]: implement on the reader to get rid of the numBits check
465 if constexpr (sizeof(ValueType) <= 4)
466 {
467 if constexpr (std::is_signed_v<ValueType>)
468 {
469 value = static_cast<ValueType>(reader.readSignedBits32(BIT_SIZE));
470 }
471 else
472 {
473 value = static_cast<ValueType>(reader.readUnsignedBits32(BIT_SIZE));
474 }
475 }
476 else
477 {
478 if constexpr (std::is_signed_v<ValueType>)
479 {
480 value = static_cast<ValueType>(reader.readSignedBits64(BIT_SIZE));
481 }
482 else
483 {
484 value = static_cast<ValueType>(reader.readUnsignedBits64(BIT_SIZE));
485 }
486 }
487}
488
489template <typename T>
490void read(BitStreamReader& reader, DynIntWrapper<T>& value, uint8_t numBits)
491{
492 if constexpr (sizeof(T) <= 4)
493 {
494 if constexpr (std::is_signed_v<T>)
495 {
496 value = static_cast<T>(reader.readSignedBits32(numBits));
497 }
498 else
499 {
500 value = static_cast<T>(reader.readUnsignedBits32(numBits));
501 }
502 }
503 else
504 {
505 if constexpr (std::is_signed_v<T>)
506 {
507 value = static_cast<T>(reader.readSignedBits64(numBits));
508 }
509 else
510 {
511 value = static_cast<T>(reader.readUnsignedBits64(numBits));
512 }
513 }
514}
515
516inline void read(BitStreamReader& reader, VarInt16& value)
517{
518 value = reader.readVarInt16();
519}
520
521inline void read(BitStreamReader& reader, VarInt32& value)
522{
523 value = reader.readVarInt32();
524}
525
526inline void read(BitStreamReader& reader, VarInt64& value)
527{
528 value = reader.readVarInt64();
529}
530
531inline void read(BitStreamReader& reader, VarInt& value)
532{
533 value = reader.readVarInt();
534}
535
536inline void read(BitStreamReader& reader, VarUInt16& value)
537{
538 value = reader.readVarUInt16();
539}
540
541inline void read(BitStreamReader& reader, VarUInt32& value)
542{
543 value = reader.readVarUInt32();
544}
545
546inline void read(BitStreamReader& reader, VarUInt64& value)
547{
548 value = reader.readVarUInt64();
549}
550
551inline void read(BitStreamReader& reader, VarUInt& value)
552{
553 value = reader.readVarUInt();
554}
555
556inline void read(BitStreamReader& reader, VarSize& value)
557{
558 value = reader.readVarSize();
559}
560
561inline void read(BitStreamReader& reader, Float16& value)
562{
563 value = reader.readFloat16();
564}
565
566inline void read(BitStreamReader& reader, Float32& value)
567{
568 value = reader.readFloat32();
569}
570
571inline void read(BitStreamReader& reader, Float64& value)
572{
573 value = reader.readFloat64();
574}
575
576template <typename ALLOC>
577inline void read(BitStreamReader& reader, BasicBytes<ALLOC>& value)
578{
579 value = reader.readBytes(value.get_allocator());
580}
581
582template <typename ALLOC>
583inline void read(BitStreamReader& reader, zserio::BasicString<ALLOC>& value)
584{
585 value = reader.readString(value.get_allocator());
586}
587
588template <typename ALLOC>
589inline void read(BitStreamReader& reader, BasicBitBuffer<ALLOC>& value)
590{
591 value = reader.readBitBuffer(value.get_allocator());
592}
593
594} // namespace detail
595
596} // namespace zserio
597
598#endif // ifndef ZSERIO_BIT_STREAM_READER_H_INC
static constexpr size_t MAX_INITIAL_ARRAY_ALLOCATION
void setBitPosition(BitPosType position)
void alignTo(size_t alignment)
uint32_t readUnsignedBits32(uint8_t numBits=32)
size_t getMaxArrayPreallocation() const
BasicBytes< ALLOC > readBytes(const ALLOC &alloc=ALLOC())
uint64_t readUnsignedBits64(uint8_t numBits=64)
BasicString< ALLOC > readString(const ALLOC &alloc=ALLOC())
BitStreamReader(const BasicBitBuffer< ALLOC > &bitBuffer, ArrayPreallocation maxArrayPrealloc={})
size_t getBufferBitSize() const
BasicBitBuffer< RebindAlloc< ALLOC, uint8_t > > readBitBuffer(const ALLOC &allocator=ALLOC())
int64_t readSignedBits64(uint8_t numBits=64)
int32_t readSignedBits32(uint8_t numBits=32)
BitStreamReader(const uint8_t *buffer, size_t bufferByteSize, ArrayPreallocation maxArrayPrealloc={})
BitPosType getBitPosition() const
pointer iterator
Definition Span.h:68
const_pointer const_iterator
Definition Span.h:69
constexpr iterator begin() const noexcept
Definition Span.h:200
detail::BoolWrapper Bool
Definition Types.h:732
detail::VarIntWrapper< uint64_t, detail::VarIntType::VAR > VarUInt
Definition Types.h:888
detail::FloatWrapper< float, detail::FloatType::FLOAT16 > Float16
Definition Types.h:892
detail::FloatWrapper< float, detail::FloatType::FLOAT32 > Float32
Definition Types.h:893
detail::VarIntWrapper< int32_t, detail::VarIntType::VAR32 > VarInt32
Definition Types.h:881
detail::VarIntWrapper< uint16_t, detail::VarIntType::VAR16 > VarUInt16
Definition Types.h:885
detail::VarIntWrapper< uint64_t, detail::VarIntType::VAR64 > VarUInt64
Definition Types.h:887
detail::VarIntWrapper< int16_t, detail::VarIntType::VAR16 > VarInt16
Definition Types.h:880
detail::FloatWrapper< double, detail::FloatType::FLOAT64 > Float64
Definition Types.h:894
detail::VarIntWrapper< uint32_t, detail::VarIntType::VAR32 > VarUInt32
Definition Types.h:886
detail::VarIntWrapper< int64_t, detail::VarIntType::VAR > VarInt
Definition Types.h:883
detail::VarIntWrapper< int64_t, detail::VarIntType::VAR64 > VarInt64
Definition Types.h:882
detail::VarIntWrapper< uint32_t, detail::VarIntType::VARSIZE > VarSize
Definition Types.h:890
ReaderContext(const ReaderContext &&)=delete
ReaderContext & operator=(const ReaderContext &&)=delete
ReaderContext(const ReaderContext &)=delete
ReaderContext & operator=(const ReaderContext &)=delete