16const size_t MAX_BUFFER_SIZE = std::numeric_limits<size_t>::max() / 8 -
sizeof(size_t);
19using ReaderContext = BitStreamReader::ReaderContext;
21#ifdef ZSERIO_RUNTIME_64BIT
22using BaseType = uint64_t;
23using BaseSignedType = int64_t;
25using BaseType = uint32_t;
26using BaseSignedType = int32_t;
29#ifdef ZSERIO_RUNTIME_64BIT
30const std::array<BaseType, 65> MASK_TABLE = {
65 UINT64_C(0x00000001ffffffff),
66 UINT64_C(0x00000003ffffffff),
67 UINT64_C(0x00000007ffffffff),
68 UINT64_C(0x0000000fffffffff),
69 UINT64_C(0x0000001fffffffff),
70 UINT64_C(0x0000003fffffffff),
71 UINT64_C(0x0000007fffffffff),
72 UINT64_C(0x000000ffffffffff),
73 UINT64_C(0x000001ffffffffff),
74 UINT64_C(0x000003ffffffffff),
75 UINT64_C(0x000007ffffffffff),
76 UINT64_C(0x00000fffffffffff),
77 UINT64_C(0x00001fffffffffff),
78 UINT64_C(0x00003fffffffffff),
79 UINT64_C(0x00007fffffffffff),
80 UINT64_C(0x0000ffffffffffff),
81 UINT64_C(0x0001ffffffffffff),
82 UINT64_C(0x0003ffffffffffff),
83 UINT64_C(0x0007ffffffffffff),
84 UINT64_C(0x000fffffffffffff),
85 UINT64_C(0x001fffffffffffff),
86 UINT64_C(0x003fffffffffffff),
87 UINT64_C(0x007fffffffffffff),
88 UINT64_C(0x00ffffffffffffff),
89 UINT64_C(0x01ffffffffffffff),
90 UINT64_C(0x03ffffffffffffff),
91 UINT64_C(0x07ffffffffffffff),
92 UINT64_C(0x0fffffffffffffff),
93 UINT64_C(0x1fffffffffffffff),
94 UINT64_C(0x3fffffffffffffff),
95 UINT64_C(0x7fffffffffffffff),
96 UINT64_C(0xffffffffffffffff),
99const std::array<BaseType, 33> MASK_TABLE = {
117 UINT32_C(0x0001ffff),
118 UINT32_C(0x0003ffff),
119 UINT32_C(0x0007ffff),
120 UINT32_C(0x000fffff),
121 UINT32_C(0x001fffff),
122 UINT32_C(0x003fffff),
123 UINT32_C(0x007fffff),
124 UINT32_C(0x00ffffff),
125 UINT32_C(0x01ffffff),
126 UINT32_C(0x03ffffff),
127 UINT32_C(0x07ffffff),
128 UINT32_C(0x0fffffff),
129 UINT32_C(0x1fffffff),
130 UINT32_C(0x3fffffff),
131 UINT32_C(0x7fffffff),
132 UINT32_C(0xffffffff),
136const uint8_t VARINT_SIGN_1 = UINT8_C(0x80);
137const uint8_t VARINT_BYTE_1 = UINT8_C(0x3f);
138const uint8_t VARINT_BYTE_N = UINT8_C(0x7f);
139const uint8_t VARINT_HAS_NEXT_1 = UINT8_C(0x40);
140const uint8_t VARINT_HAS_NEXT_N = UINT8_C(0x80);
142const uint8_t VARUINT_BYTE = UINT8_C(0x7f);
143const uint8_t VARUINT_HAS_NEXT = UINT8_C(0x80);
145const uint32_t VARSIZE_MAX_VALUE = (UINT32_C(1) << 31U) - 1;
147#ifdef ZSERIO_RUNTIME_64BIT
148inline BaseType parse64(Span<const uint8_t>::const_iterator bufferIt)
150 return static_cast<BaseType
>(*bufferIt) << 56U |
static_cast<BaseType
>(*(bufferIt + 1)) << 48U |
151 static_cast<BaseType
>(*(bufferIt + 2)) << 40U |
static_cast<BaseType
>(*(bufferIt + 3)) << 32U |
152 static_cast<BaseType
>(*(bufferIt + 4)) << 24U |
static_cast<BaseType
>(*(bufferIt + 5)) << 16U |
153 static_cast<BaseType
>(*(bufferIt + 6)) << 8U |
static_cast<BaseType
>(*(bufferIt + 7));
156inline BaseType parse56(Span<const uint8_t>::const_iterator bufferIt)
158 return static_cast<BaseType
>(*bufferIt) << 48U |
static_cast<BaseType
>(*(bufferIt + 1)) << 40U |
159 static_cast<BaseType
>(*(bufferIt + 2)) << 32U |
static_cast<BaseType
>(*(bufferIt + 3)) << 24U |
160 static_cast<BaseType
>(*(bufferIt + 4)) << 16U |
static_cast<BaseType
>(*(bufferIt + 5)) << 8U |
161 static_cast<BaseType
>(*(bufferIt + 6));
164inline BaseType parse48(Span<const uint8_t>::const_iterator bufferIt)
166 return static_cast<BaseType
>(*bufferIt) << 40U |
static_cast<BaseType
>(*(bufferIt + 1)) << 32U |
167 static_cast<BaseType
>(*(bufferIt + 2)) << 24U |
static_cast<BaseType
>(*(bufferIt + 3)) << 16U |
168 static_cast<BaseType
>(*(bufferIt + 4)) << 8U |
static_cast<BaseType
>(*(bufferIt + 5));
171inline BaseType parse40(Span<const uint8_t>::const_iterator bufferIt)
173 return static_cast<BaseType
>(*bufferIt) << 32U |
static_cast<BaseType
>(*(bufferIt + 1)) << 24U |
174 static_cast<BaseType
>(*(bufferIt + 2)) << 16U |
static_cast<BaseType
>(*(bufferIt + 3)) << 8U |
175 static_cast<BaseType
>(*(bufferIt + 4));
178inline BaseType parse32(Span<const uint8_t>::const_iterator bufferIt)
180 return static_cast<BaseType
>(*bufferIt) << 24U |
static_cast<BaseType
>(*(bufferIt + 1)) << 16U |
181 static_cast<BaseType
>(*(bufferIt + 2)) << 8U |
static_cast<BaseType
>(*(bufferIt + 3));
184inline BaseType parse24(Span<const uint8_t>::const_iterator bufferIt)
186 return static_cast<BaseType
>(*bufferIt) << 16U |
static_cast<BaseType
>(*(bufferIt + 1)) << 8U |
187 static_cast<BaseType
>(*(bufferIt + 2));
190inline BaseType parse16(Span<const uint8_t>::const_iterator bufferIt)
192 return static_cast<BaseType
>(*bufferIt) << 8U |
static_cast<BaseType
>(*(bufferIt + 1));
195inline BaseType parse8(Span<const uint8_t>::const_iterator bufferIt)
197 return static_cast<BaseType
>(*bufferIt);
201inline void throwNumBitsIsNotValid(uint8_t numBits)
203 throw CppRuntimeException(
"BitStreamReader: ReadBits #")
204 <<
numBits <<
" is not valid, reading from stream failed!";
208inline void checkNumBits(uint8_t numBits)
210 if (numBits == 0 || numBits > 32)
212 throwNumBitsIsNotValid(numBits);
217inline void checkNumBits64(uint8_t numBits)
219 if (numBits == 0 || numBits > 64)
221 throwNumBitsIsNotValid(numBits);
226inline void throwEof()
228 throw CppRuntimeException(
"BitStreamReader: Reached eof(), reading from stream failed!");
232inline void loadCacheNext(ReaderContext& ctx, uint8_t numBits)
234 static const uint8_t cacheBitSize =
sizeof(BaseType) * 8;
237 const size_t byteIndex = ctx.bitIndex >> 3U;
238 if (ctx.bufferBitSize >= ctx.bitIndex + cacheBitSize)
241#ifdef ZSERIO_RUNTIME_64BIT
242 parse64(ctx.buffer.begin() + byteIndex);
244 parse32(ctx.buffer.begin() + byteIndex);
246 ctx.cacheNumBits = cacheBitSize;
250 if (ctx.bitIndex + numBits > ctx.bufferBitSize)
255 ctx.cacheNumBits =
static_cast<uint8_t
>(ctx.bufferBitSize - ctx.bitIndex);
258 const uint8_t alignedNumBits =
static_cast<uint8_t
>((ctx.cacheNumBits + 7U) & ~0x7U);
260 switch (alignedNumBits)
262#ifdef ZSERIO_RUNTIME_64BIT
264 ctx.cache = parse64(ctx.buffer.begin() + byteIndex);
267 ctx.cache = parse56(ctx.buffer.begin() + byteIndex);
270 ctx.cache = parse48(ctx.buffer.begin() + byteIndex);
273 ctx.cache = parse40(ctx.buffer.begin() + byteIndex);
277 ctx.cache = parse32(ctx.buffer.begin() + byteIndex);
280 ctx.cache = parse24(ctx.buffer.begin() + byteIndex);
283 ctx.cache = parse16(ctx.buffer.begin() + byteIndex);
286 ctx.cache = parse8(ctx.buffer.begin() + byteIndex);
290 ctx.cache >>=
static_cast<uint8_t
>(alignedNumBits - ctx.cacheNumBits);
295inline BaseType readUnsignedBitsImpl(ReaderContext& ctx, uint8_t numBits)
298 if (ctx.cacheNumBits < numBits)
301 value = ctx.cache & MASK_TABLE[ctx.cacheNumBits];
302 ctx.bitIndex += ctx.cacheNumBits;
306 loadCacheNext(ctx, numBits);
310 if (numBits <
sizeof(BaseType) * 8)
315 value |= ((ctx.cache >>
static_cast<uint8_t
>(ctx.cacheNumBits -
numBits)) & MASK_TABLE[
numBits]);
316 ctx.cacheNumBits =
static_cast<uint8_t
>(ctx.cacheNumBits -
numBits);
323inline BaseSignedType readSignedBitsImpl(ReaderContext& ctx, uint8_t numBits)
325 static const uint8_t typeSize =
sizeof(BaseSignedType) * 8;
326 BaseType value = readUnsignedBitsImpl(ctx, numBits);
331 if (numBits != 0 && numBits < typeSize &&
332 (value >= (
static_cast<BaseType
>(1) <<
static_cast<uint8_t
>(numBits - 1))))
334 value -=
static_cast<BaseType
>(1) << numBits;
337 return static_cast<BaseSignedType
>(value);
340#ifndef ZSERIO_RUNTIME_64BIT
342inline uint64_t readUnsignedBits64Impl(ReaderContext& ctx, uint8_t numBits)
346 uint64_t value = readUnsignedBitsImpl(ctx, 32);
350 value |= readUnsignedBitsImpl(ctx, numBits);
387 if (buffer.size() < (bufferBitSize + 7) / 8)
390 << buffer.size() <<
"' < '" << (bufferBitSize + 7) / 8 <<
"')!";
401 checkNumBits(numBits);
410#ifdef ZSERIO_RUNTIME_64BIT
426#ifdef ZSERIO_RUNTIME_64BIT
452 checkNumBits(numBits);
816 <<
result <<
"' is out of range for varsize type!";
838#ifdef ZSERIO_RUNTIME_64BIT
851 throw CppRuntimeException(
"BitStreamReader: Reached eof(), setting of bit position failed!");
873uint8_t BitStreamReader::readByte()
void setBitPosition(BitPosType position)
void alignTo(size_t alignment)
uint32_t readUnsignedBits32(uint8_t numBits=32)
VarUInt16 readVarUInt16()
uint64_t readUnsignedBits64(uint8_t numBits=64)
VarUInt32 readVarUInt32()
VarUInt64 readVarUInt64()
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
constexpr size_type size() const noexcept
uint8_t numBits(uint64_t numValues)
detail::VarIntWrapper< uint64_t, detail::VarIntType::VAR > VarUInt
detail::FloatWrapper< float, detail::FloatType::FLOAT16 > Float16
detail::FloatWrapper< float, detail::FloatType::FLOAT32 > Float32
detail::VarIntWrapper< int32_t, detail::VarIntType::VAR32 > VarInt32
float convertUInt32ToFloat(uint32_t float32Value)
detail::VarIntWrapper< uint16_t, detail::VarIntType::VAR16 > VarUInt16
double convertUInt64ToDouble(uint64_t float64Value)
detail::VarIntWrapper< uint64_t, detail::VarIntType::VAR64 > VarUInt64
detail::VarIntWrapper< int16_t, detail::VarIntType::VAR16 > VarInt16
detail::FloatWrapper< double, detail::FloatType::FLOAT64 > Float64
detail::VarIntWrapper< uint32_t, detail::VarIntType::VAR32 > VarUInt32
float convertUInt16ToFloat(uint16_t float16Value)
detail::VarIntWrapper< int64_t, detail::VarIntType::VAR > VarInt
detail::VarIntWrapper< int64_t, detail::VarIntType::VAR64 > VarInt64
detail::VarIntWrapper< uint32_t, detail::VarIntType::VARSIZE > VarSize
ReaderContext(Span< const uint8_t > readBuffer, size_t readBufferBitSize, size_t maxArrayPrealloc)
Span< const uint8_t > buffer
const BitPosType bufferBitSize