Zserio C++17 runtime library 1.3.0
Built for Zserio 2.20.0
Loading...
Searching...
No Matches
BitStreamReader.cpp
Go to the documentation of this file.
1#include <array>
2#include <limits>
3
6#include "zserio/FloatUtil.h"
8
9namespace zserio
10{
11
12namespace
13{
14
15// max size calculated to prevent "bitIndex + numBits" overflows
16const size_t MAX_BUFFER_SIZE = std::numeric_limits<size_t>::max() / 8 - sizeof(size_t);
17
18using BitPosType = BitStreamReader::BitPosType;
19using ReaderContext = BitStreamReader::ReaderContext;
20
21#ifdef ZSERIO_RUNTIME_64BIT
22using BaseType = uint64_t;
23using BaseSignedType = int64_t;
24#else
25using BaseType = uint32_t;
26using BaseSignedType = int32_t;
27#endif
28
29#ifdef ZSERIO_RUNTIME_64BIT
30const std::array<BaseType, 65> MASK_TABLE = {
31 UINT64_C(0x00),
32 UINT64_C(0x0001),
33 UINT64_C(0x0003),
34 UINT64_C(0x0007),
35 UINT64_C(0x000f),
36 UINT64_C(0x001f),
37 UINT64_C(0x003f),
38 UINT64_C(0x007f),
39 UINT64_C(0x00ff),
40 UINT64_C(0x01ff),
41 UINT64_C(0x03ff),
42 UINT64_C(0x07ff),
43 UINT64_C(0x0fff),
44 UINT64_C(0x1fff),
45 UINT64_C(0x3fff),
46 UINT64_C(0x7fff),
47 UINT64_C(0xffff),
48 UINT64_C(0x0001ffff),
49 UINT64_C(0x0003ffff),
50 UINT64_C(0x0007ffff),
51 UINT64_C(0x000fffff),
52 UINT64_C(0x001fffff),
53 UINT64_C(0x003fffff),
54 UINT64_C(0x007fffff),
55 UINT64_C(0x00ffffff),
56 UINT64_C(0x01ffffff),
57 UINT64_C(0x03ffffff),
58 UINT64_C(0x07ffffff),
59 UINT64_C(0x0fffffff),
60 UINT64_C(0x1fffffff),
61 UINT64_C(0x3fffffff),
62 UINT64_C(0x7fffffff),
63 UINT64_C(0xffffffff),
64
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),
97};
98#else
99const std::array<BaseType, 33> MASK_TABLE = {
100 UINT32_C(0x00),
101 UINT32_C(0x0001),
102 UINT32_C(0x0003),
103 UINT32_C(0x0007),
104 UINT32_C(0x000f),
105 UINT32_C(0x001f),
106 UINT32_C(0x003f),
107 UINT32_C(0x007f),
108 UINT32_C(0x00ff),
109 UINT32_C(0x01ff),
110 UINT32_C(0x03ff),
111 UINT32_C(0x07ff),
112 UINT32_C(0x0fff),
113 UINT32_C(0x1fff),
114 UINT32_C(0x3fff),
115 UINT32_C(0x7fff),
116 UINT32_C(0xffff),
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),
133};
134#endif
135
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);
141
142const uint8_t VARUINT_BYTE = UINT8_C(0x7f);
143const uint8_t VARUINT_HAS_NEXT = UINT8_C(0x80);
144
145const uint32_t VARSIZE_MAX_VALUE = (UINT32_C(1) << 31U) - 1;
146
147#ifdef ZSERIO_RUNTIME_64BIT
148inline BaseType parse64(Span<const uint8_t>::const_iterator bufferIt)
149{
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));
154}
155
156inline BaseType parse56(Span<const uint8_t>::const_iterator bufferIt)
157{
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));
162}
163
164inline BaseType parse48(Span<const uint8_t>::const_iterator bufferIt)
165{
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));
169}
170
171inline BaseType parse40(Span<const uint8_t>::const_iterator bufferIt)
172{
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));
176}
177#endif
178inline BaseType parse32(Span<const uint8_t>::const_iterator bufferIt)
179{
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));
182}
183
184inline BaseType parse24(Span<const uint8_t>::const_iterator bufferIt)
185{
186 return static_cast<BaseType>(*bufferIt) << 16U | static_cast<BaseType>(*(bufferIt + 1)) << 8U |
187 static_cast<BaseType>(*(bufferIt + 2));
188}
189
190inline BaseType parse16(Span<const uint8_t>::const_iterator bufferIt)
191{
192 return static_cast<BaseType>(*bufferIt) << 8U | static_cast<BaseType>(*(bufferIt + 1));
193}
194
195inline BaseType parse8(Span<const uint8_t>::const_iterator bufferIt)
196{
197 return static_cast<BaseType>(*bufferIt);
198}
199
201inline void throwNumBitsIsNotValid(uint8_t numBits)
202{
203 throw CppRuntimeException("BitStreamReader: ReadBits #")
204 << numBits << " is not valid, reading from stream failed!";
205}
206
208inline void checkNumBits(uint8_t numBits)
209{
210 if (numBits == 0 || numBits > 32)
211 {
212 throwNumBitsIsNotValid(numBits);
213 }
214}
215
217inline void checkNumBits64(uint8_t numBits)
218{
219 if (numBits == 0 || numBits > 64)
220 {
221 throwNumBitsIsNotValid(numBits);
222 }
223}
224
226inline void throwEof()
227{
228 throw CppRuntimeException("BitStreamReader: Reached eof(), reading from stream failed!");
229}
230
232inline void loadCacheNext(ReaderContext& ctx, uint8_t numBits)
233{
234 static const uint8_t cacheBitSize = sizeof(BaseType) * 8;
235
236 // ctx.bitIndex is always byte aligned and ctx.cacheNumBits is always zero in this call
237 const size_t byteIndex = ctx.bitIndex >> 3U;
238 if (ctx.bufferBitSize >= ctx.bitIndex + cacheBitSize)
239 {
240 ctx.cache =
241#ifdef ZSERIO_RUNTIME_64BIT
242 parse64(ctx.buffer.begin() + byteIndex);
243#else
244 parse32(ctx.buffer.begin() + byteIndex);
245#endif
246 ctx.cacheNumBits = cacheBitSize;
247 }
248 else
249 {
250 if (ctx.bitIndex + numBits > ctx.bufferBitSize)
251 {
252 throwEof();
253 }
254
255 ctx.cacheNumBits = static_cast<uint8_t>(ctx.bufferBitSize - ctx.bitIndex);
256
257 // buffer must be always available in full bytes, even if some last bits are not used
258 const uint8_t alignedNumBits = static_cast<uint8_t>((ctx.cacheNumBits + 7U) & ~0x7U);
259
260 switch (alignedNumBits)
261 {
262#ifdef ZSERIO_RUNTIME_64BIT
263 case 64:
264 ctx.cache = parse64(ctx.buffer.begin() + byteIndex);
265 break;
266 case 56:
267 ctx.cache = parse56(ctx.buffer.begin() + byteIndex);
268 break;
269 case 48:
270 ctx.cache = parse48(ctx.buffer.begin() + byteIndex);
271 break;
272 case 40:
273 ctx.cache = parse40(ctx.buffer.begin() + byteIndex);
274 break;
275#endif
276 case 32:
277 ctx.cache = parse32(ctx.buffer.begin() + byteIndex);
278 break;
279 case 24:
280 ctx.cache = parse24(ctx.buffer.begin() + byteIndex);
281 break;
282 case 16:
283 ctx.cache = parse16(ctx.buffer.begin() + byteIndex);
284 break;
285 default: // 8
286 ctx.cache = parse8(ctx.buffer.begin() + byteIndex);
287 break;
288 }
289
290 ctx.cache >>= static_cast<uint8_t>(alignedNumBits - ctx.cacheNumBits);
291 }
292}
293
295inline BaseType readUnsignedBitsImpl(ReaderContext& ctx, uint8_t numBits)
296{
297 BaseType value = 0;
298 if (ctx.cacheNumBits < numBits)
299 {
300 // read all remaining cache bits
301 value = ctx.cache & MASK_TABLE[ctx.cacheNumBits];
302 ctx.bitIndex += ctx.cacheNumBits;
303 numBits = static_cast<uint8_t>(numBits - ctx.cacheNumBits);
304
305 // load next piece of buffer into cache
306 loadCacheNext(ctx, numBits);
307
308 // add the remaining bits to the result
309 // if numBits is sizeof(BaseType) * 8 here, value is already 0 (see MASK_TABLE[0])
310 if (numBits < sizeof(BaseType) * 8)
311 {
312 value <<= numBits;
313 }
314 }
315 value |= ((ctx.cache >> static_cast<uint8_t>(ctx.cacheNumBits - numBits)) & MASK_TABLE[numBits]);
316 ctx.cacheNumBits = static_cast<uint8_t>(ctx.cacheNumBits - numBits);
317 ctx.bitIndex += numBits;
318
319 return value;
320}
321
323inline BaseSignedType readSignedBitsImpl(ReaderContext& ctx, uint8_t numBits)
324{
325 static const uint8_t typeSize = sizeof(BaseSignedType) * 8;
326 BaseType value = readUnsignedBitsImpl(ctx, numBits);
327
328 // Skip the signed overflow correction if numBits == typeSize.
329 // In that case, the value that comes out the readBits function
330 // is already correct.
331 if (numBits != 0 && numBits < typeSize &&
332 (value >= (static_cast<BaseType>(1) << static_cast<uint8_t>(numBits - 1))))
333 {
334 value -= static_cast<BaseType>(1) << numBits;
335 }
336
337 return static_cast<BaseSignedType>(value);
338}
339
340#ifndef ZSERIO_RUNTIME_64BIT
342inline uint64_t readUnsignedBits64Impl(ReaderContext& ctx, uint8_t numBits)
343{
344 // read the first 32 bits
345 numBits = static_cast<uint8_t>(numBits - 32);
346 uint64_t value = readUnsignedBitsImpl(ctx, 32);
347
348 // add the remaining bits
349 value <<= numBits;
350 value |= readUnsignedBitsImpl(ctx, numBits);
351
352 return value;
353}
354#endif
355
356} // namespace
357
360 buffer(readBuffer),
361 bufferBitSize(readBufferBitSize),
362 cache(0),
363 cacheNumBits(0),
364 maxArrayPreallocation(maxArrayPrealloc),
365 bitIndex(0)
366{
368 {
369 throw CppRuntimeException("BitStreamReader: Buffer size exceeded limit '")
370 << MAX_BUFFER_SIZE << "' bytes!";
371 }
372}
373
378
382
384 Span<const uint8_t> buffer, size_t bufferBitSize, ArrayPreallocation maxArrayPrealloc) :
385 m_context(buffer, bufferBitSize, maxArrayPrealloc)
386{
387 if (buffer.size() < (bufferBitSize + 7) / 8)
388 {
389 throw CppRuntimeException("BitStreamReader: Wrong buffer bit size ('")
390 << buffer.size() << "' < '" << (bufferBitSize + 7) / 8 << "')!";
391 }
392}
393
395 const uint8_t* buffer, size_t bufferBitSize, BitsTag, ArrayPreallocation maxArrayPrealloc) :
396 m_context(Span<const uint8_t>(buffer, (bufferBitSize + 7) / 8), bufferBitSize, maxArrayPrealloc)
397{}
398
400{
401 checkNumBits(numBits);
402
403 return static_cast<uint32_t>(readUnsignedBitsImpl(m_context, numBits));
404}
405
407{
408 checkNumBits64(numBits);
409
410#ifdef ZSERIO_RUNTIME_64BIT
411 return readUnsignedBitsImpl(m_context, numBits);
412#else
413 if (numBits <= 32)
414 {
415 return readUnsignedBitsImpl(m_context, numBits);
416 }
417
418 return readUnsignedBits64Impl(m_context, numBits);
419#endif
420}
421
423{
424 checkNumBits64(numBits);
425
426#ifdef ZSERIO_RUNTIME_64BIT
427 return readSignedBitsImpl(m_context, numBits);
428#else
429 if (numBits <= 32)
430 {
431 return readSignedBitsImpl(m_context, numBits);
432 }
433
434 int64_t value = static_cast<int64_t>(readUnsignedBits64Impl(m_context, numBits));
435
436 // Skip the signed overflow correction if numBits == 64.
437 // In that case, the value that comes out the readBits function
438 // is already correct.
439 const bool needsSignExtension =
440 numBits < 64 && (static_cast<uint64_t>(value) >= (UINT64_C(1) << (numBits - 1U)));
442 {
443 value = static_cast<int64_t>(static_cast<uint64_t>(value) - (UINT64_C(1) << numBits));
444 }
445
446 return value;
447#endif
448}
449
451{
452 checkNumBits(numBits);
453
454 return static_cast<int32_t>(readSignedBitsImpl(m_context, numBits));
455}
456
458{
459 return readUnsignedBitsImpl(m_context, 1) != 0;
460}
461
463{
464 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
465 const bool sign = (byte & VARINT_SIGN_1) != 0;
467 if ((byte & VARINT_HAS_NEXT_1) == 0)
468 {
469 return sign ? static_cast<int16_t>(-result) : static_cast<int16_t>(result);
470 }
471
472 result = static_cast<uint16_t>(result << 8U);
473 result = static_cast<uint16_t>(result | readUnsignedBitsImpl(m_context, 8)); // byte 2
474 return sign ? static_cast<int16_t>(-result) : static_cast<int16_t>(result);
475}
476
478{
479 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
480 const bool sign = (byte & VARINT_SIGN_1) != 0;
482 if ((byte & VARINT_HAS_NEXT_1) == 0)
483 {
484 return sign ? -static_cast<int32_t>(result) : static_cast<int32_t>(result);
485 }
486
487 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 2
489 if ((byte & VARINT_HAS_NEXT_N) == 0)
490 {
491 return sign ? -static_cast<int32_t>(result) : static_cast<int32_t>(result);
492 }
493
494 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 3
496 if ((byte & VARINT_HAS_NEXT_N) == 0)
497 {
498 return sign ? -static_cast<int32_t>(result) : static_cast<int32_t>(result);
499 }
500
502 return sign ? -static_cast<int32_t>(result) : static_cast<int32_t>(result);
503}
504
506{
507 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
508 const bool sign = (byte & VARINT_SIGN_1) != 0;
510 if ((byte & VARINT_HAS_NEXT_1) == 0)
511 {
512 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
513 }
514
515 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 2
517 if ((byte & VARINT_HAS_NEXT_N) == 0)
518 {
519 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
520 }
521
522 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 3
523 result = static_cast<uint64_t>(result) << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N);
524 if ((byte & VARINT_HAS_NEXT_N) == 0)
525 {
526 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
527 }
528
529 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 4
531 if ((byte & VARINT_HAS_NEXT_N) == 0)
532 {
533 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
534 }
535
536 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 5
538 if ((byte & VARINT_HAS_NEXT_N) == 0)
539 {
540 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
541 }
542
543 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 6
545 if ((byte & VARINT_HAS_NEXT_N) == 0)
546 {
547 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
548 }
549
550 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 7
552 if ((byte & VARINT_HAS_NEXT_N) == 0)
553 {
554 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
555 }
556
558 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
559}
560
562{
563 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
564 const bool sign = (byte & VARINT_SIGN_1) != 0;
566 if ((byte & VARINT_HAS_NEXT_1) == 0)
567 {
568 return sign ? (result == 0 ? INT64_MIN : -static_cast<int64_t>(result)) : static_cast<int64_t>(result);
569 }
570
571 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 2
573 if ((byte & VARINT_HAS_NEXT_N) == 0)
574 {
575 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
576 }
577
578 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 3
580 if ((byte & VARINT_HAS_NEXT_N) == 0)
581 {
582 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
583 }
584
585 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 4
587 if ((byte & VARINT_HAS_NEXT_N) == 0)
588 {
589 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
590 }
591
592 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 5
594 if ((byte & VARINT_HAS_NEXT_N) == 0)
595 {
596 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
597 }
598
599 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 6
601 if ((byte & VARINT_HAS_NEXT_N) == 0)
602 {
603 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
604 }
605
606 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 7
608 if ((byte & VARINT_HAS_NEXT_N) == 0)
609 {
610 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
611 }
612
613 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 8
615 if ((byte & VARINT_HAS_NEXT_N) == 0)
616 {
617 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
618 }
619
621 return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result);
622}
623
625{
626 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
628 if ((byte & VARUINT_HAS_NEXT) == 0)
629 {
630 return result;
631 }
632
633 result = static_cast<uint16_t>(result << 8U);
634 result = static_cast<uint16_t>(result | readUnsignedBitsImpl(m_context, 8)); // byte 2
635 return result;
636}
637
639{
640 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
642 if ((byte & VARUINT_HAS_NEXT) == 0)
643 {
644 return result;
645 }
646
647 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 2
649 if ((byte & VARUINT_HAS_NEXT) == 0)
650 {
651 return result;
652 }
653
654 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 3
656 if ((byte & VARUINT_HAS_NEXT) == 0)
657 {
658 return result;
659 }
660
662 return result;
663}
664
666{
667 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
669 if ((byte & VARUINT_HAS_NEXT) == 0)
670 {
671 return result;
672 }
673
674 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 2
676 if ((byte & VARUINT_HAS_NEXT) == 0)
677 {
678 return result;
679 }
680
681 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 3
683 if ((byte & VARUINT_HAS_NEXT) == 0)
684 {
685 return result;
686 }
687
688 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 4
690 if ((byte & VARUINT_HAS_NEXT) == 0)
691 {
692 return result;
693 }
694
695 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 5
697 if ((byte & VARUINT_HAS_NEXT) == 0)
698 {
699 return result;
700 }
701
702 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 6
704 if ((byte & VARUINT_HAS_NEXT) == 0)
705 {
706 return result;
707 }
708
709 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 7
711 if ((byte & VARUINT_HAS_NEXT) == 0)
712 {
713 return result;
714 }
715
717 return result;
718}
719
721{
722 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
724 if ((byte & VARUINT_HAS_NEXT) == 0)
725 {
726 return result;
727 }
728
729 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 2
731 if ((byte & VARUINT_HAS_NEXT) == 0)
732 {
733 return result;
734 }
735
736 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 3
738 if ((byte & VARUINT_HAS_NEXT) == 0)
739 {
740 return result;
741 }
742
743 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 4
745 if ((byte & VARUINT_HAS_NEXT) == 0)
746 {
747 return result;
748 }
749
750 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 5
752 if ((byte & VARUINT_HAS_NEXT) == 0)
753 {
754 return result;
755 }
756
757 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 6
759 if ((byte & VARUINT_HAS_NEXT) == 0)
760 {
761 return result;
762 }
763
764 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 7
766 if ((byte & VARUINT_HAS_NEXT) == 0)
767 {
768 return result;
769 }
770
771 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 8
773 if ((byte & VARUINT_HAS_NEXT) == 0)
774 {
775 return result;
776 }
777
779 return result;
780}
781
783{
784 uint8_t byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 1
786 if ((byte & VARUINT_HAS_NEXT) == 0)
787 {
788 return result;
789 }
790
791 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 2
793 if ((byte & VARUINT_HAS_NEXT) == 0)
794 {
795 return result;
796 }
797
798 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 3
800 if ((byte & VARUINT_HAS_NEXT) == 0)
801 {
802 return result;
803 }
804
805 byte = static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8)); // byte 4
807 if ((byte & VARUINT_HAS_NEXT) == 0)
808 {
809 return result;
810 }
811
814 {
815 throw CppRuntimeException("BitStreamReader: Read value '")
816 << result << "' is out of range for varsize type!";
817 }
818
819 return result;
820}
821
828
835
837{
838#ifdef ZSERIO_RUNTIME_64BIT
839 const uint64_t doublePrecisionFloatValue = static_cast<uint64_t>(readUnsignedBitsImpl(m_context, 64));
840#else
842#endif
843
845}
846
848{
849 if (position > m_context.bufferBitSize)
850 {
851 throw CppRuntimeException("BitStreamReader: Reached eof(), setting of bit position failed!");
852 }
853
854 m_context.bitIndex = (position / 8) * 8; // set to byte aligned position
855 m_context.cacheNumBits = 0; // invalidate cache
856 const uint8_t skip = static_cast<uint8_t>(position - m_context.bitIndex);
857 if (skip != 0)
858 {
860 }
861}
862
863void BitStreamReader::alignTo(size_t alignment)
864{
865 const BitPosType offset = getBitPosition() % alignment;
866 if (offset != 0)
867 {
868 const uint8_t skip = static_cast<uint8_t>(alignment - offset);
870 }
871}
872
873uint8_t BitStreamReader::readByte()
874{
875 return static_cast<uint8_t>(readUnsignedBitsImpl(m_context, 8));
876}
877
878} // namespace zserio
void setBitPosition(BitPosType position)
void alignTo(size_t alignment)
uint32_t readUnsignedBits32(uint8_t numBits=32)
uint64_t readUnsignedBits64(uint8_t numBits=64)
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
Definition Span.h:281
uint8_t numBits(uint64_t numValues)
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
float convertUInt32ToFloat(uint32_t float32Value)
detail::VarIntWrapper< uint16_t, detail::VarIntType::VAR16 > VarUInt16
Definition Types.h:885
double convertUInt64ToDouble(uint64_t float64Value)
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
float convertUInt16ToFloat(uint16_t float16Value)
Definition FloatUtil.cpp:32
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(Span< const uint8_t > readBuffer, size_t readBufferBitSize, size_t maxArrayPrealloc)