1 |
|
|
#include <limits> |
2 |
|
|
#include <array> |
3 |
|
|
|
4 |
|
|
#include "zserio/BitStreamReader.h" |
5 |
|
|
#include "zserio/CppRuntimeException.h" |
6 |
|
|
#include "zserio/FloatUtil.h" |
7 |
|
|
#include "zserio/RuntimeArch.h" |
8 |
|
|
|
9 |
|
|
namespace zserio |
10 |
|
|
{ |
11 |
|
|
|
12 |
|
|
namespace |
13 |
|
|
{ |
14 |
|
|
// max size calculated to prevent overflows in internal comparisons |
15 |
|
|
const size_t MAX_BUFFER_SIZE = std::numeric_limits<size_t>::max() / 8 - 4; |
16 |
|
|
|
17 |
|
|
using BitPosType = BitStreamReader::BitPosType; |
18 |
|
|
using ReaderContext = BitStreamReader::ReaderContext; |
19 |
|
|
|
20 |
|
|
#ifdef ZSERIO_RUNTIME_64BIT |
21 |
|
|
using BaseType = uint64_t; |
22 |
|
|
using BaseSignedType = int64_t; |
23 |
|
|
#else |
24 |
|
|
using BaseType = uint32_t; |
25 |
|
|
using BaseSignedType = int32_t; |
26 |
|
|
#endif |
27 |
|
|
|
28 |
|
|
#ifdef ZSERIO_RUNTIME_64BIT |
29 |
|
|
const std::array<BaseType, 65> MASK_TABLE = |
30 |
|
|
{ |
31 |
|
|
UINT64_C(0x00), |
32 |
|
|
UINT64_C(0x0001), UINT64_C(0x0003), UINT64_C(0x0007), UINT64_C(0x000f), |
33 |
|
|
UINT64_C(0x001f), UINT64_C(0x003f), UINT64_C(0x007f), UINT64_C(0x00ff), |
34 |
|
|
UINT64_C(0x01ff), UINT64_C(0x03ff), UINT64_C(0x07ff), UINT64_C(0x0fff), |
35 |
|
|
UINT64_C(0x1fff), UINT64_C(0x3fff), UINT64_C(0x7fff), UINT64_C(0xffff), |
36 |
|
|
UINT64_C(0x0001ffff), UINT64_C(0x0003ffff), UINT64_C(0x0007ffff), UINT64_C(0x000fffff), |
37 |
|
|
UINT64_C(0x001fffff), UINT64_C(0x003fffff), UINT64_C(0x007fffff), UINT64_C(0x00ffffff), |
38 |
|
|
UINT64_C(0x01ffffff), UINT64_C(0x03ffffff), UINT64_C(0x07ffffff), UINT64_C(0x0fffffff), |
39 |
|
|
UINT64_C(0x1fffffff), UINT64_C(0x3fffffff), UINT64_C(0x7fffffff), UINT64_C(0xffffffff), |
40 |
|
|
|
41 |
|
|
UINT64_C(0x00000001ffffffff), UINT64_C(0x00000003ffffffff), |
42 |
|
|
UINT64_C(0x00000007ffffffff), UINT64_C(0x0000000fffffffff), |
43 |
|
|
UINT64_C(0x0000001fffffffff), UINT64_C(0x0000003fffffffff), |
44 |
|
|
UINT64_C(0x0000007fffffffff), UINT64_C(0x000000ffffffffff), |
45 |
|
|
UINT64_C(0x000001ffffffffff), UINT64_C(0x000003ffffffffff), |
46 |
|
|
UINT64_C(0x000007ffffffffff), UINT64_C(0x00000fffffffffff), |
47 |
|
|
UINT64_C(0x00001fffffffffff), UINT64_C(0x00003fffffffffff), |
48 |
|
|
UINT64_C(0x00007fffffffffff), UINT64_C(0x0000ffffffffffff), |
49 |
|
|
UINT64_C(0x0001ffffffffffff), UINT64_C(0x0003ffffffffffff), |
50 |
|
|
UINT64_C(0x0007ffffffffffff), UINT64_C(0x000fffffffffffff), |
51 |
|
|
UINT64_C(0x001fffffffffffff), UINT64_C(0x003fffffffffffff), |
52 |
|
|
UINT64_C(0x007fffffffffffff), UINT64_C(0x00ffffffffffffff), |
53 |
|
|
UINT64_C(0x01ffffffffffffff), UINT64_C(0x03ffffffffffffff), |
54 |
|
|
UINT64_C(0x07ffffffffffffff), UINT64_C(0x0fffffffffffffff), |
55 |
|
|
UINT64_C(0x1fffffffffffffff), UINT64_C(0x3fffffffffffffff), |
56 |
|
|
UINT64_C(0x7fffffffffffffff), UINT64_C(0xffffffffffffffff) |
57 |
|
|
}; |
58 |
|
|
#else |
59 |
|
|
const std::array<BaseType, 33> MASK_TABLE = |
60 |
|
|
{ |
61 |
|
|
UINT32_C(0x00), |
62 |
|
|
UINT32_C(0x0001), UINT32_C(0x0003), UINT32_C(0x0007), UINT32_C(0x000f), |
63 |
|
|
UINT32_C(0x001f), UINT32_C(0x003f), UINT32_C(0x007f), UINT32_C(0x00ff), |
64 |
|
|
UINT32_C(0x01ff), UINT32_C(0x03ff), UINT32_C(0x07ff), UINT32_C(0x0fff), |
65 |
|
|
UINT32_C(0x1fff), UINT32_C(0x3fff), UINT32_C(0x7fff), UINT32_C(0xffff), |
66 |
|
|
UINT32_C(0x0001ffff), UINT32_C(0x0003ffff), UINT32_C(0x0007ffff), UINT32_C(0x000fffff), |
67 |
|
|
UINT32_C(0x001fffff), UINT32_C(0x003fffff), UINT32_C(0x007fffff), UINT32_C(0x00ffffff), |
68 |
|
|
UINT32_C(0x01ffffff), UINT32_C(0x03ffffff), UINT32_C(0x07ffffff), UINT32_C(0x0fffffff), |
69 |
|
|
UINT32_C(0x1fffffff), UINT32_C(0x3fffffff), UINT32_C(0x7fffffff), UINT32_C(0xffffffff) |
70 |
|
|
}; |
71 |
|
|
#endif |
72 |
|
|
|
73 |
|
|
const uint8_t VARINT_SIGN_1 = UINT8_C(0x80); |
74 |
|
|
const uint8_t VARINT_BYTE_1 = UINT8_C(0x3f); |
75 |
|
|
const uint8_t VARINT_BYTE_N = UINT8_C(0x7f); |
76 |
|
|
const uint8_t VARINT_HAS_NEXT_1 = UINT8_C(0x40); |
77 |
|
|
const uint8_t VARINT_HAS_NEXT_N = UINT8_C(0x80); |
78 |
|
|
|
79 |
|
|
const uint8_t VARUINT_BYTE = UINT8_C(0x7f); |
80 |
|
|
const uint8_t VARUINT_HAS_NEXT = UINT8_C(0x80); |
81 |
|
|
|
82 |
|
|
const uint32_t VARSIZE_MAX_VALUE = (UINT32_C(1) << 31U) - 1; |
83 |
|
|
|
84 |
|
|
#ifdef ZSERIO_RUNTIME_64BIT |
85 |
|
8662 |
inline BaseType parse64(Span<const uint8_t>::const_iterator bufferIt) |
86 |
|
|
{ |
87 |
|
17324 |
return static_cast<BaseType>(*bufferIt) << 56U | |
88 |
|
17324 |
static_cast<BaseType>(*(bufferIt + 1)) << 48U | |
89 |
|
17324 |
static_cast<BaseType>(*(bufferIt + 2)) << 40U | |
90 |
|
17324 |
static_cast<BaseType>(*(bufferIt + 3)) << 32U | |
91 |
|
17324 |
static_cast<BaseType>(*(bufferIt + 4)) << 24U | |
92 |
|
17324 |
static_cast<BaseType>(*(bufferIt + 5)) << 16U | |
93 |
|
17324 |
static_cast<BaseType>(*(bufferIt + 6)) << 8U | |
94 |
|
17324 |
static_cast<BaseType>(*(bufferIt + 7)); |
95 |
|
|
} |
96 |
|
|
|
97 |
|
350 |
inline BaseType parse56(Span<const uint8_t>::const_iterator bufferIt) |
98 |
|
|
{ |
99 |
|
700 |
return static_cast<BaseType>(*bufferIt) << 48U | |
100 |
|
700 |
static_cast<BaseType>(*(bufferIt + 1)) << 40U | |
101 |
|
700 |
static_cast<BaseType>(*(bufferIt + 2)) << 32U | |
102 |
|
700 |
static_cast<BaseType>(*(bufferIt + 3)) << 24U | |
103 |
|
700 |
static_cast<BaseType>(*(bufferIt + 4)) << 16U | |
104 |
|
700 |
static_cast<BaseType>(*(bufferIt + 5)) << 8U | |
105 |
|
700 |
static_cast<BaseType>(*(bufferIt + 6)); |
106 |
|
|
} |
107 |
|
|
|
108 |
|
325 |
inline BaseType parse48(Span<const uint8_t>::const_iterator bufferIt) |
109 |
|
|
{ |
110 |
|
650 |
return static_cast<BaseType>(*bufferIt) << 40U | |
111 |
|
650 |
static_cast<BaseType>(*(bufferIt + 1)) << 32U | |
112 |
|
650 |
static_cast<BaseType>(*(bufferIt + 2)) << 24U | |
113 |
|
650 |
static_cast<BaseType>(*(bufferIt + 3)) << 16U | |
114 |
|
650 |
static_cast<BaseType>(*(bufferIt + 4)) << 8U | |
115 |
|
650 |
static_cast<BaseType>(*(bufferIt + 5)); |
116 |
|
|
} |
117 |
|
|
|
118 |
|
459 |
inline BaseType parse40(Span<const uint8_t>::const_iterator bufferIt) |
119 |
|
|
{ |
120 |
|
918 |
return static_cast<BaseType>(*bufferIt) << 32U | |
121 |
|
918 |
static_cast<BaseType>(*(bufferIt + 1)) << 24U | |
122 |
|
918 |
static_cast<BaseType>(*(bufferIt + 2)) << 16U | |
123 |
|
918 |
static_cast<BaseType>(*(bufferIt + 3)) << 8U | |
124 |
|
918 |
static_cast<BaseType>(*(bufferIt + 4)); |
125 |
|
|
} |
126 |
|
|
#endif |
127 |
|
488 |
inline BaseType parse32(Span<const uint8_t>::const_iterator bufferIt) |
128 |
|
|
{ |
129 |
|
976 |
return static_cast<BaseType>(*bufferIt) << 24U | |
130 |
|
976 |
static_cast<BaseType>(*(bufferIt + 1)) << 16U | |
131 |
|
976 |
static_cast<BaseType>(*(bufferIt + 2)) << 8U | |
132 |
|
976 |
static_cast<BaseType>(*(bufferIt + 3)); |
133 |
|
|
} |
134 |
|
|
|
135 |
|
356 |
inline BaseType parse24(Span<const uint8_t>::const_iterator bufferIt) |
136 |
|
|
{ |
137 |
|
712 |
return static_cast<BaseType>(*bufferIt) << 16U | |
138 |
|
712 |
static_cast<BaseType>(*(bufferIt + 1)) << 8U | |
139 |
|
712 |
static_cast<BaseType>(*(bufferIt + 2)); |
140 |
|
|
} |
141 |
|
|
|
142 |
|
798 |
inline BaseType parse16(Span<const uint8_t>::const_iterator bufferIt) |
143 |
|
|
{ |
144 |
|
1596 |
return static_cast<BaseType>(*bufferIt) << 8U | |
145 |
|
1596 |
static_cast<BaseType>(*(bufferIt + 1)); |
146 |
|
|
} |
147 |
|
|
|
148 |
|
1006 |
inline BaseType parse8(Span<const uint8_t>::const_iterator bufferIt) |
149 |
|
|
{ |
150 |
|
1006 |
return static_cast<BaseType>(*bufferIt); |
151 |
|
|
} |
152 |
|
|
|
153 |
|
|
/** Optimization which increases chances to inline checkNumBits and checkNumBits64. */ |
154 |
|
8 |
inline void throwNumBitsIsNotValid(uint8_t numBits) |
155 |
|
|
{ |
156 |
✓✗✓✗
|
16 |
throw CppRuntimeException("BitStreamReader: ReadBits #") << numBits << |
157 |
✓✗ |
24 |
" is not valid, reading from stream failed!"; |
158 |
|
|
} |
159 |
|
|
|
160 |
|
|
/** Checks numBits validity for 32-bit reads. */ |
161 |
|
7838 |
inline void checkNumBits(uint8_t numBits) |
162 |
|
|
{ |
163 |
✓✓ |
7838 |
if (numBits > 32) |
164 |
|
4 |
throwNumBitsIsNotValid(numBits); |
165 |
|
7834 |
} |
166 |
|
|
|
167 |
|
|
/** Checks numBits validity for 64-bit reads. */ |
168 |
|
5589 |
inline void checkNumBits64(uint8_t numBits) |
169 |
|
|
{ |
170 |
✓✓ |
5589 |
if (numBits > 64) |
171 |
|
4 |
throwNumBitsIsNotValid(numBits); |
172 |
|
5585 |
} |
173 |
|
|
|
174 |
|
|
/** Optimization which increases chances to inline loadCacheNext. */ |
175 |
|
72 |
inline void throwEof() |
176 |
|
|
{ |
177 |
✓✗ |
72 |
throw CppRuntimeException("BitStreamReader: Reached eof(), reading from stream failed!"); |
178 |
|
|
} |
179 |
|
|
|
180 |
|
|
/** Loads next 32/64 bits to 32/64 bit-cache. */ |
181 |
|
12516 |
inline void loadCacheNext(ReaderContext& ctx, uint8_t numBits) |
182 |
|
|
{ |
183 |
|
|
static const uint8_t cacheBitSize = sizeof(BaseType) * 8; |
184 |
|
|
|
185 |
|
|
// ctx.bitIndex is always byte aligned and ctx.cacheNumBits is always zero in this call |
186 |
|
12516 |
const size_t byteIndex = ctx.bitIndex >> 3U; |
187 |
✓✓ |
12516 |
if (ctx.bufferBitSize >= ctx.bitIndex + cacheBitSize) |
188 |
|
|
{ |
189 |
|
|
ctx.cache = |
190 |
|
|
#ifdef ZSERIO_RUNTIME_64BIT |
191 |
|
8399 |
parse64(ctx.buffer.begin() + byteIndex); |
192 |
|
|
#else |
193 |
|
|
parse32(ctx.buffer.begin() + byteIndex); |
194 |
|
|
#endif |
195 |
|
8399 |
ctx.cacheNumBits = cacheBitSize; |
196 |
|
|
} |
197 |
|
|
else |
198 |
|
|
{ |
199 |
✓✓ |
4117 |
if (ctx.bitIndex + numBits > ctx.bufferBitSize) |
200 |
|
72 |
throwEof(); |
201 |
|
|
|
202 |
|
4045 |
ctx.cacheNumBits = static_cast<uint8_t>(ctx.bufferBitSize - ctx.bitIndex); |
203 |
|
|
|
204 |
|
|
// buffer must be always available in full bytes, even if some last bits are not used |
205 |
|
4045 |
const uint8_t alignedNumBits = (ctx.cacheNumBits + 7U) & ~0x7U; |
206 |
|
|
|
207 |
✓✓✓✓ ✓✓✓✓
|
4045 |
switch (alignedNumBits) |
208 |
|
|
{ |
209 |
|
|
#ifdef ZSERIO_RUNTIME_64BIT |
210 |
|
|
case 64: |
211 |
|
263 |
ctx.cache = parse64(ctx.buffer.begin() + byteIndex); |
212 |
|
263 |
break; |
213 |
|
|
case 56: |
214 |
|
350 |
ctx.cache = parse56(ctx.buffer.begin() + byteIndex); |
215 |
|
350 |
break; |
216 |
|
|
case 48: |
217 |
|
325 |
ctx.cache = parse48(ctx.buffer.begin() + byteIndex); |
218 |
|
325 |
break; |
219 |
|
|
case 40: |
220 |
|
459 |
ctx.cache = parse40(ctx.buffer.begin() + byteIndex); |
221 |
|
459 |
break; |
222 |
|
|
#endif |
223 |
|
|
case 32: |
224 |
|
488 |
ctx.cache = parse32(ctx.buffer.begin() + byteIndex); |
225 |
|
488 |
break; |
226 |
|
|
case 24: |
227 |
|
356 |
ctx.cache = parse24(ctx.buffer.begin() + byteIndex); |
228 |
|
356 |
break; |
229 |
|
|
case 16: |
230 |
|
798 |
ctx.cache = parse16(ctx.buffer.begin() + byteIndex); |
231 |
|
798 |
break; |
232 |
|
|
default: // 8 |
233 |
|
1006 |
ctx.cache = parse8(ctx.buffer.begin() + byteIndex); |
234 |
|
1006 |
break; |
235 |
|
|
} |
236 |
|
|
|
237 |
|
4045 |
ctx.cache >>= static_cast<uint8_t>(alignedNumBits - ctx.cacheNumBits); |
238 |
|
|
} |
239 |
|
12444 |
} |
240 |
|
|
|
241 |
|
|
/** Unchecked implementation of readBits. */ |
242 |
|
63482 |
inline BaseType readBitsImpl(ReaderContext& ctx, uint8_t numBits) |
243 |
|
|
{ |
244 |
|
63482 |
BaseType value = 0; |
245 |
✓✓ |
63482 |
if (ctx.cacheNumBits < numBits) |
246 |
|
|
{ |
247 |
|
|
// read all remaining cache bits |
248 |
|
12516 |
value = ctx.cache & MASK_TABLE[ctx.cacheNumBits]; |
249 |
|
12516 |
ctx.bitIndex += ctx.cacheNumBits; |
250 |
|
12516 |
numBits -= ctx.cacheNumBits; |
251 |
|
|
|
252 |
|
|
// load next piece of buffer into cache |
253 |
|
12516 |
loadCacheNext(ctx, numBits); |
254 |
|
|
|
255 |
|
|
// add the remaining bits to the result |
256 |
|
|
// if numBits is sizeof(BaseType) * 8 here, value is already 0 (see MASK_TABLE[0]) |
257 |
✓✓ |
12444 |
if (numBits < sizeof(BaseType) * 8) |
258 |
|
12385 |
value <<= numBits; |
259 |
|
|
} |
260 |
|
63410 |
value |= ((ctx.cache >> static_cast<uint8_t>(ctx.cacheNumBits - numBits)) & MASK_TABLE[numBits]); |
261 |
|
63410 |
ctx.cacheNumBits -= numBits; |
262 |
|
63410 |
ctx.bitIndex += numBits; |
263 |
|
|
|
264 |
|
63410 |
return value; |
265 |
|
|
} |
266 |
|
|
|
267 |
|
|
/** Unchecked version of readSignedBits. */ |
268 |
|
3428 |
inline BaseSignedType readSignedBitsImpl(ReaderContext& ctx, uint8_t numBits) |
269 |
|
|
{ |
270 |
|
|
static const uint8_t typeSize = sizeof(BaseSignedType) * 8; |
271 |
|
3428 |
BaseType value = readBitsImpl(ctx, numBits); |
272 |
|
|
|
273 |
|
|
// Skip the signed overflow correction if numBits == typeSize. |
274 |
|
|
// In that case, the value that comes out the readBits function |
275 |
|
|
// is already correct. |
276 |
✓✓✓✓ ✓✓ |
6341 |
if (numBits != 0 && numBits < typeSize && |
277 |
|
2913 |
(value >= (static_cast<BaseType>(1) << static_cast<uint8_t>(numBits - 1)))) |
278 |
|
|
{ |
279 |
|
682 |
value -= static_cast<BaseType>(1) << numBits; |
280 |
|
|
} |
281 |
|
|
|
282 |
|
3428 |
return static_cast<BaseSignedType>(value); |
283 |
|
|
} |
284 |
|
|
|
285 |
|
|
#ifndef ZSERIO_RUNTIME_64BIT |
286 |
|
|
/** Unchecked implementation of readBits64. Always reads > 32bit! */ |
287 |
|
|
inline uint64_t readBits64Impl(ReaderContext& ctx, uint8_t numBits) |
288 |
|
|
{ |
289 |
|
|
// read the first 32 bits |
290 |
|
|
numBits -= 32; |
291 |
|
|
uint64_t value = readBitsImpl(ctx, 32); |
292 |
|
|
|
293 |
|
|
// add the remaining bits |
294 |
|
|
value <<= numBits; |
295 |
|
|
value |= readBitsImpl(ctx, numBits); |
296 |
|
|
|
297 |
|
|
return value; |
298 |
|
|
} |
299 |
|
|
#endif |
300 |
|
|
} // namespace |
301 |
|
|
|
302 |
|
4245 |
BitStreamReader::ReaderContext::ReaderContext(Span<const uint8_t> readBuffer, size_t readBufferBitSize) |
303 |
|
|
: buffer(readBuffer), |
304 |
|
|
bufferBitSize(readBufferBitSize), |
305 |
|
|
cache(0), |
306 |
|
|
cacheNumBits(0), |
307 |
|
4245 |
bitIndex(0) |
308 |
|
|
{ |
309 |
✓✓ |
4245 |
if (buffer.size() > MAX_BUFFER_SIZE) |
310 |
|
|
{ |
311 |
✓✗✓✗
|
2 |
throw CppRuntimeException("BitStreamReader: Buffer size exceeded limit '") << MAX_BUFFER_SIZE << |
312 |
✓✗ |
3 |
"' bytes!"; |
313 |
|
|
} |
314 |
|
4244 |
} |
315 |
|
|
|
316 |
|
15 |
BitStreamReader::BitStreamReader(const uint8_t* buffer, size_t bufferByteSize) : |
317 |
✓✓ |
16 |
BitStreamReader(Span<const uint8_t>(buffer, bufferByteSize)) |
318 |
|
14 |
{} |
319 |
|
|
|
320 |
|
28 |
BitStreamReader::BitStreamReader(Span<const uint8_t> buffer) : |
321 |
|
28 |
m_context(buffer, buffer.size() * 8) |
322 |
|
27 |
{} |
323 |
|
|
|
324 |
|
392 |
BitStreamReader::BitStreamReader(Span<const uint8_t> buffer, size_t bufferBitSize) : |
325 |
|
392 |
m_context(buffer, bufferBitSize) |
326 |
|
|
{ |
327 |
✓✓ |
392 |
if (buffer.size() < (bufferBitSize + 7) / 8) |
328 |
|
|
{ |
329 |
✓✗✓✗
|
2 |
throw CppRuntimeException("BitStreamReader: Wrong buffer bit size ('") << buffer.size() << |
330 |
✓✗✓✗ ✓✗ |
3 |
"' < '" << (bufferBitSize + 7) / 8 << "')!"; |
331 |
|
|
} |
332 |
|
391 |
} |
333 |
|
|
|
334 |
|
3825 |
BitStreamReader::BitStreamReader(const uint8_t* buffer, size_t bufferBitSize, BitsTag) : |
335 |
✓✗ |
3825 |
m_context(Span<const uint8_t>(buffer, (bufferBitSize + 7) / 8), bufferBitSize) |
336 |
|
3825 |
{} |
337 |
|
|
|
338 |
|
6335 |
uint32_t BitStreamReader::readBits(uint8_t numBits) |
339 |
|
|
{ |
340 |
|
6335 |
checkNumBits(numBits); |
341 |
|
|
|
342 |
|
6333 |
return static_cast<uint32_t>(readBitsImpl(m_context, numBits)); |
343 |
|
|
} |
344 |
|
|
|
345 |
|
3660 |
uint64_t BitStreamReader::readBits64(uint8_t numBits) |
346 |
|
|
{ |
347 |
|
3660 |
checkNumBits64(numBits); |
348 |
|
|
|
349 |
|
|
#ifdef ZSERIO_RUNTIME_64BIT |
350 |
|
3658 |
return readBitsImpl(m_context, numBits); |
351 |
|
|
#else |
352 |
|
|
if (numBits <= 32) |
353 |
|
|
return readBitsImpl(m_context, numBits); |
354 |
|
|
|
355 |
|
|
return readBits64Impl(m_context, numBits); |
356 |
|
|
#endif |
357 |
|
|
} |
358 |
|
|
|
359 |
|
1929 |
int64_t BitStreamReader::readSignedBits64(uint8_t numBits) |
360 |
|
|
{ |
361 |
|
1929 |
checkNumBits64(numBits); |
362 |
|
|
|
363 |
|
|
#ifdef ZSERIO_RUNTIME_64BIT |
364 |
|
1927 |
return readSignedBitsImpl(m_context, numBits); |
365 |
|
|
#else |
366 |
|
|
if (numBits <= 32) |
367 |
|
|
return readSignedBitsImpl(m_context, numBits); |
368 |
|
|
|
369 |
|
|
int64_t value = static_cast<int64_t>(readBits64Impl(m_context, numBits)); |
370 |
|
|
|
371 |
|
|
// Skip the signed overflow correction if numBits == 64. |
372 |
|
|
// In that case, the value that comes out the readBits function |
373 |
|
|
// is already correct. |
374 |
|
|
const bool needsSignExtension = |
375 |
|
|
numBits < 64 && (static_cast<uint64_t>(value) >= (UINT64_C(1) << (numBits - 1))); |
376 |
|
|
if (needsSignExtension) |
377 |
|
|
value -= UINT64_C(1) << numBits; |
378 |
|
|
|
379 |
|
|
return value; |
380 |
|
|
#endif |
381 |
|
|
} |
382 |
|
|
|
383 |
|
1503 |
int32_t BitStreamReader::readSignedBits(uint8_t numBits) |
384 |
|
|
{ |
385 |
|
1503 |
checkNumBits(numBits); |
386 |
|
|
|
387 |
|
1501 |
return static_cast<int32_t>(readSignedBitsImpl(m_context, numBits)); |
388 |
|
|
} |
389 |
|
|
|
390 |
|
2344 |
int64_t BitStreamReader::readVarInt64() |
391 |
|
|
{ |
392 |
|
2344 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
393 |
|
2344 |
const bool sign = (byte & VARINT_SIGN_1) != 0; |
394 |
|
2344 |
uint64_t result = byte & VARINT_BYTE_1; |
395 |
✓✓ |
2344 |
if ((byte & VARINT_HAS_NEXT_1) == 0) |
396 |
✓✓ |
347 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
397 |
|
|
|
398 |
|
1997 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
399 |
|
1997 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
400 |
✓✓ |
1997 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
401 |
✓✓ |
284 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
402 |
|
|
|
403 |
|
1713 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 3 |
404 |
|
1713 |
result = static_cast<uint64_t>(result) << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
405 |
✓✓ |
1713 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
406 |
✓✓ |
284 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
407 |
|
|
|
408 |
|
1429 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 4 |
409 |
|
1429 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
410 |
✓✓ |
1429 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
411 |
✓✓ |
293 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
412 |
|
|
|
413 |
|
1136 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 5 |
414 |
|
1136 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
415 |
✓✓ |
1136 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
416 |
✓✓ |
284 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
417 |
|
|
|
418 |
|
852 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 6 |
419 |
|
852 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
420 |
✓✓ |
852 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
421 |
✓✓ |
284 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
422 |
|
|
|
423 |
|
568 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 7 |
424 |
|
568 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
425 |
✓✓ |
568 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
426 |
✓✓ |
284 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
427 |
|
|
|
428 |
|
284 |
result = result << 8U | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 8 |
429 |
✓✓ |
284 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
430 |
|
|
} |
431 |
|
|
|
432 |
|
664 |
int32_t BitStreamReader::readVarInt32() |
433 |
|
|
{ |
434 |
|
664 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
435 |
|
664 |
const bool sign = (byte & VARINT_SIGN_1) != 0; |
436 |
|
664 |
uint32_t result = byte & VARINT_BYTE_1; |
437 |
✓✓ |
664 |
if ((byte & VARINT_HAS_NEXT_1) == 0) |
438 |
✓✓ |
187 |
return sign ? -static_cast<int32_t>(result) : static_cast<int32_t>(result); |
439 |
|
|
|
440 |
|
477 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
441 |
|
477 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
442 |
✓✓ |
477 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
443 |
✓✓ |
156 |
return sign ? -static_cast<int32_t>(result) : static_cast<int32_t>(result); |
444 |
|
|
|
445 |
|
321 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 3 |
446 |
|
321 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
447 |
✓✓ |
321 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
448 |
✓✓ |
165 |
return sign ? -static_cast<int32_t>(result) : static_cast<int32_t>(result); |
449 |
|
|
|
450 |
|
156 |
result = result << 8U | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 4 |
451 |
✓✓ |
156 |
return sign ? -static_cast<int32_t>(result) : static_cast<int32_t>(result); |
452 |
|
|
} |
453 |
|
|
|
454 |
|
208 |
int16_t BitStreamReader::readVarInt16() |
455 |
|
|
{ |
456 |
|
208 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
457 |
|
208 |
const bool sign = (byte & VARINT_SIGN_1) != 0; |
458 |
|
208 |
uint16_t result = byte & VARINT_BYTE_1; |
459 |
✓✓ |
208 |
if ((byte & VARINT_HAS_NEXT_1) == 0) |
460 |
✓✓ |
115 |
return sign ? static_cast<int16_t>(-result) : static_cast<int16_t>(result); |
461 |
|
|
|
462 |
|
93 |
result = static_cast<uint16_t>(result << 8U) | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
463 |
✓✓ |
93 |
return sign ? static_cast<int16_t>(-result) : static_cast<int16_t>(result); |
464 |
|
|
} |
465 |
|
|
|
466 |
|
1942 |
uint64_t BitStreamReader::readVarUInt64() |
467 |
|
|
{ |
468 |
|
1942 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
469 |
|
1942 |
uint64_t result = byte & VARUINT_BYTE; |
470 |
✓✓ |
1942 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
471 |
|
445 |
return result; |
472 |
|
|
|
473 |
|
1497 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
474 |
|
1497 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
475 |
✓✓ |
1497 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
476 |
|
192 |
return result; |
477 |
|
|
|
478 |
|
1305 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 3 |
479 |
|
1305 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
480 |
✓✓ |
1305 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
481 |
|
322 |
return result; |
482 |
|
|
|
483 |
|
983 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 4 |
484 |
|
983 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
485 |
✓✓ |
983 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
486 |
|
222 |
return result; |
487 |
|
|
|
488 |
|
761 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 5 |
489 |
|
761 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
490 |
✓✓ |
761 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
491 |
|
191 |
return result; |
492 |
|
|
|
493 |
|
570 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 6 |
494 |
|
570 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
495 |
✓✓ |
570 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
496 |
|
190 |
return result; |
497 |
|
|
|
498 |
|
380 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 7 |
499 |
|
380 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
500 |
✓✓ |
380 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
501 |
|
190 |
return result; |
502 |
|
|
|
503 |
|
190 |
result = result << 8U | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 8 |
504 |
|
190 |
return result; |
505 |
|
|
} |
506 |
|
|
|
507 |
|
478 |
uint32_t BitStreamReader::readVarUInt32() |
508 |
|
|
{ |
509 |
|
478 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
510 |
|
478 |
uint32_t result = byte & VARUINT_BYTE; |
511 |
✓✓ |
478 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
512 |
|
125 |
return result; |
513 |
|
|
|
514 |
|
353 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
515 |
|
353 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
516 |
✓✓ |
353 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
517 |
|
96 |
return result; |
518 |
|
|
|
519 |
|
257 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 3 |
520 |
|
257 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
521 |
✓✓ |
257 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
522 |
|
162 |
return result; |
523 |
|
|
|
524 |
|
95 |
result = result << 8U | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 4 |
525 |
|
95 |
return result; |
526 |
|
|
} |
527 |
|
|
|
528 |
|
178 |
uint16_t BitStreamReader::readVarUInt16() |
529 |
|
|
{ |
530 |
|
178 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
531 |
|
178 |
uint16_t result = byte & VARUINT_BYTE; |
532 |
✓✓ |
178 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
533 |
|
100 |
return result; |
534 |
|
|
|
535 |
|
78 |
result = static_cast<uint16_t>(result << 8U) | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
536 |
|
78 |
return result; |
537 |
|
|
} |
538 |
|
|
|
539 |
|
3107 |
int64_t BitStreamReader::readVarInt() |
540 |
|
|
{ |
541 |
|
3107 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
542 |
|
3107 |
const bool sign = (byte & VARINT_SIGN_1) != 0; |
543 |
|
3107 |
uint64_t result = byte & VARINT_BYTE_1; |
544 |
✓✓ |
3107 |
if ((byte & VARINT_HAS_NEXT_1) == 0) |
545 |
✓✓✓✓
|
570 |
return sign ? (result == 0 ? INT64_MIN : -static_cast<int64_t>(result)) : static_cast<int64_t>(result); |
546 |
|
|
|
547 |
|
2537 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
548 |
|
2537 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
549 |
✓✓ |
2537 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
550 |
✓✓ |
316 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
551 |
|
|
|
552 |
|
2221 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 3 |
553 |
|
2221 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
554 |
✓✓ |
2221 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
555 |
✓✓ |
316 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
556 |
|
|
|
557 |
|
1905 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 4 |
558 |
|
1905 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
559 |
✓✓ |
1905 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
560 |
✓✓ |
324 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
561 |
|
|
|
562 |
|
1581 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 5 |
563 |
|
1581 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
564 |
✓✓ |
1581 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
565 |
✓✓ |
316 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
566 |
|
|
|
567 |
|
1265 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 6 |
568 |
|
1265 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
569 |
✓✓ |
1265 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
570 |
✓✓ |
316 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
571 |
|
|
|
572 |
|
949 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 7 |
573 |
|
949 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
574 |
✓✓ |
949 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
575 |
✓✓ |
316 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
576 |
|
|
|
577 |
|
633 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 8 |
578 |
|
633 |
result = result << 7U | static_cast<uint8_t>(byte & VARINT_BYTE_N); |
579 |
✓✓ |
633 |
if ((byte & VARINT_HAS_NEXT_N) == 0) |
580 |
✓✓ |
316 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
581 |
|
|
|
582 |
|
317 |
result = result << 8U | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 9 |
583 |
✓✓ |
317 |
return sign ? -static_cast<int64_t>(result) : static_cast<int64_t>(result); |
584 |
|
|
} |
585 |
|
|
|
586 |
|
1558 |
uint64_t BitStreamReader::readVarUInt() |
587 |
|
|
{ |
588 |
|
1558 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
589 |
|
1558 |
uint64_t result = byte & VARUINT_BYTE; |
590 |
✓✓ |
1558 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
591 |
|
285 |
return result; |
592 |
|
|
|
593 |
|
1273 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
594 |
|
1273 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
595 |
✓✓ |
1273 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
596 |
|
160 |
return result; |
597 |
|
|
|
598 |
|
1113 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 3 |
599 |
|
1113 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
600 |
✓✓ |
1113 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
601 |
|
164 |
return result; |
602 |
|
|
|
603 |
|
949 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 4 |
604 |
|
949 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
605 |
✓✓ |
949 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
606 |
|
158 |
return result; |
607 |
|
|
|
608 |
|
791 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 5 |
609 |
|
791 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
610 |
✓✓ |
791 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
611 |
|
158 |
return result; |
612 |
|
|
|
613 |
|
633 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 6 |
614 |
|
633 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
615 |
✓✓ |
633 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
616 |
|
158 |
return result; |
617 |
|
|
|
618 |
|
475 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 7 |
619 |
|
475 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
620 |
✓✓ |
475 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
621 |
|
158 |
return result; |
622 |
|
|
|
623 |
|
317 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 8 |
624 |
|
317 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
625 |
✓✓ |
317 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
626 |
|
158 |
return result; |
627 |
|
|
|
628 |
|
159 |
result = result << 8U | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 9 |
629 |
|
159 |
return result; |
630 |
|
|
} |
631 |
|
|
|
632 |
|
2659 |
uint32_t BitStreamReader::readVarSize() |
633 |
|
|
{ |
634 |
✓✗ |
2659 |
uint8_t byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 1 |
635 |
|
2659 |
uint32_t result = byte & VARUINT_BYTE; |
636 |
✓✓ |
2659 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
637 |
|
2082 |
return result; |
638 |
|
|
|
639 |
✓✗ |
577 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 2 |
640 |
|
577 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
641 |
✓✓ |
577 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
642 |
|
128 |
return result; |
643 |
|
|
|
644 |
✓✗ |
449 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 3 |
645 |
|
449 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
646 |
✓✓ |
449 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
647 |
|
194 |
return result; |
648 |
|
|
|
649 |
✓✗ |
255 |
byte = static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 4 |
650 |
|
255 |
result = result << 7U | static_cast<uint8_t>(byte & VARUINT_BYTE); |
651 |
✓✓ |
255 |
if ((byte & VARUINT_HAS_NEXT) == 0) |
652 |
|
126 |
return result; |
653 |
|
|
|
654 |
✓✗ |
129 |
result = result << 8U | static_cast<uint8_t>(readBitsImpl(m_context, 8)); // byte 5 |
655 |
✓✓ |
129 |
if (result > VARSIZE_MAX_VALUE) |
656 |
✓✗✓✗
|
4 |
throw CppRuntimeException("BitStreamReader: Read value '") << result << |
657 |
✓✗ |
6 |
"' is out of range for varsize type!"; |
658 |
|
|
|
659 |
|
127 |
return result; |
660 |
|
|
} |
661 |
|
|
|
662 |
|
215 |
float BitStreamReader::readFloat16() |
663 |
|
|
{ |
664 |
|
215 |
const uint16_t halfPrecisionFloatValue = static_cast<uint16_t>(readBitsImpl(m_context, 16)); |
665 |
|
|
|
666 |
|
215 |
return convertUInt16ToFloat(halfPrecisionFloatValue); |
667 |
|
|
} |
668 |
|
|
|
669 |
|
313 |
float BitStreamReader::readFloat32() |
670 |
|
|
{ |
671 |
|
313 |
const uint32_t singlePrecisionFloatValue = static_cast<uint32_t>(readBitsImpl(m_context, 32)); |
672 |
|
|
|
673 |
|
313 |
return convertUInt32ToFloat(singlePrecisionFloatValue); |
674 |
|
|
} |
675 |
|
|
|
676 |
|
493 |
double BitStreamReader::readFloat64() |
677 |
|
|
{ |
678 |
|
|
#ifdef ZSERIO_RUNTIME_64BIT |
679 |
|
493 |
const uint64_t doublePrecisionFloatValue = static_cast<uint64_t>(readBitsImpl(m_context, 64)); |
680 |
|
|
#else |
681 |
|
|
const uint64_t doublePrecisionFloatValue = readBits64Impl(m_context, 64); |
682 |
|
|
#endif |
683 |
|
|
|
684 |
|
493 |
return convertUInt64ToDouble(doublePrecisionFloatValue); |
685 |
|
|
} |
686 |
|
|
|
687 |
|
907 |
bool BitStreamReader::readBool() |
688 |
|
|
{ |
689 |
|
907 |
return readBitsImpl(m_context, 1) != 0; |
690 |
|
|
} |
691 |
|
|
|
692 |
|
189 |
void BitStreamReader::setBitPosition(BitPosType position) |
693 |
|
|
{ |
694 |
✓✓ |
189 |
if (position > m_context.bufferBitSize) |
695 |
✓✗ |
1 |
throw CppRuntimeException("BitStreamReader: Reached eof(), setting of bit position failed!"); |
696 |
|
|
|
697 |
|
188 |
m_context.bitIndex = (position / 8) * 8; // set to byte aligned position |
698 |
|
188 |
m_context.cacheNumBits = 0; // invalidate cache |
699 |
|
188 |
const uint8_t skip = static_cast<uint8_t>(position - m_context.bitIndex); |
700 |
✓✓ |
188 |
if (skip != 0) |
701 |
|
1 |
readBits(skip); |
702 |
|
188 |
} |
703 |
|
|
|
704 |
|
4732 |
void BitStreamReader::alignTo(size_t alignment) |
705 |
|
|
{ |
706 |
|
4732 |
const BitPosType offset = getBitPosition() % alignment; |
707 |
✓✓ |
4732 |
if (offset != 0) |
708 |
|
|
{ |
709 |
|
2455 |
const uint8_t skip = static_cast<uint8_t>(alignment - offset); |
710 |
|
2455 |
readBits64(skip); |
711 |
|
|
} |
712 |
|
4732 |
} |
713 |
|
|
|
714 |
|
974 |
uint8_t BitStreamReader::readByte() |
715 |
|
|
{ |
716 |
|
974 |
return static_cast<uint8_t>(readBitsImpl(m_context, 8)); |
717 |
|
|
} |
718 |
|
|
|
719 |
|
|
} // namespace zserio |