Coverage Report

Created: 2024-04-30 09:35

src/zserio/BitStreamWriter.cpp
Line
Count
Source
1
#include <algorithm>
2
#include <array>
3
#include <cstring>
4
#include <fstream>
5
6
#include "zserio/BitSizeOfCalculator.h"
7
#include "zserio/BitStreamWriter.h"
8
#include "zserio/CppRuntimeException.h"
9
#include "zserio/FloatUtil.h"
10
11
namespace zserio
12
{
13
14
static const std::array<uint32_t, 33> MAX_U32_VALUES = {
15
        0x00U,
16
        0x0001U,
17
        0x0003U,
18
        0x0007U,
19
        0x000fU,
20
        0x001fU,
21
        0x003fU,
22
        0x007fU,
23
        0x00ffU,
24
        0x01ffU,
25
        0x03ffU,
26
        0x07ffU,
27
        0x0fffU,
28
        0x1fffU,
29
        0x3fffU,
30
        0x7fffU,
31
        0xffffU,
32
        0x0001ffffU,
33
        0x0003ffffU,
34
        0x0007ffffU,
35
        0x000fffffU,
36
        0x001fffffU,
37
        0x003fffffU,
38
        0x007fffffU,
39
        0x00ffffffU,
40
        0x01ffffffU,
41
        0x03ffffffU,
42
        0x07ffffffU,
43
        0x0fffffffU,
44
        0x1fffffffU,
45
        0x3fffffffU,
46
        0x7fffffffU,
47
        0xffffffffU,
48
};
49
50
static const std::array<int32_t, 33> MIN_I32_VALUES = {
51
        0,
52
        -0x0001,
53
        -0x0002,
54
        -0x0004,
55
        -0x0008,
56
        -0x0010,
57
        -0x0020,
58
        -0x0040,
59
        -0x0080,
60
        -0x0100,
61
        -0x0200,
62
        -0x0400,
63
        -0x0800,
64
        -0x1000,
65
        -0x2000,
66
        -0x4000,
67
        -0x8000,
68
        -0x00010000,
69
        -0x00020000,
70
        -0x00040000,
71
        -0x00080000,
72
        -0x00100000,
73
        -0x00200000,
74
        -0x00400000,
75
        -0x00800000,
76
        -0x01000000,
77
        -0x02000000,
78
        -0x04000000,
79
        -0x08000000,
80
        -0x10000000,
81
        -0x20000000,
82
        -0x40000000,
83
        INT32_MIN,
84
};
85
86
static const std::array<int32_t, 33> MAX_I32_VALUES = {
87
        0x00,
88
        0x0000,
89
        0x0001,
90
        0x0003,
91
        0x0007,
92
        0x000f,
93
        0x001f,
94
        0x003f,
95
        0x007f,
96
        0x00ff,
97
        0x01ff,
98
        0x03ff,
99
        0x07ff,
100
        0x0fff,
101
        0x1fff,
102
        0x3fff,
103
        0x7fff,
104
        0x0000ffff,
105
        0x0001ffff,
106
        0x0003ffff,
107
        0x0007ffff,
108
        0x000fffff,
109
        0x001fffff,
110
        0x003fffff,
111
        0x007fffff,
112
        0x00ffffff,
113
        0x01ffffff,
114
        0x03ffffff,
115
        0x07ffffff,
116
        0x0fffffff,
117
        0x1fffffff,
118
        0x3fffffff,
119
        0x7fffffff,
120
};
121
122
static const std::array<uint64_t, 65> MAX_U64_VALUES = {
123
        0x00ULL,
124
        0x0001ULL,
125
        0x0003ULL,
126
        0x0007ULL,
127
        0x000fULL,
128
        0x001fULL,
129
        0x003fULL,
130
        0x007fULL,
131
        0x00ffULL,
132
        0x01ffULL,
133
        0x03ffULL,
134
        0x07ffULL,
135
        0x0fffULL,
136
        0x1fffULL,
137
        0x3fffULL,
138
        0x7fffULL,
139
        0xffffULL,
140
        0x0001ffffULL,
141
        0x0003ffffULL,
142
        0x0007ffffULL,
143
        0x000fffffULL,
144
        0x001fffffULL,
145
        0x003fffffULL,
146
        0x007fffffULL,
147
        0x00ffffffULL,
148
        0x01ffffffULL,
149
        0x03ffffffULL,
150
        0x07ffffffULL,
151
        0x0fffffffULL,
152
        0x1fffffffULL,
153
        0x3fffffffULL,
154
        0x7fffffffULL,
155
        0xffffffffULL,
156
        0x0001ffffffffULL,
157
        0x0003ffffffffULL,
158
        0x0007ffffffffULL,
159
        0x000fffffffffULL,
160
        0x001fffffffffULL,
161
        0x003fffffffffULL,
162
        0x007fffffffffULL,
163
        0x00ffffffffffULL,
164
        0x01ffffffffffULL,
165
        0x03ffffffffffULL,
166
        0x07ffffffffffULL,
167
        0x0fffffffffffULL,
168
        0x1fffffffffffULL,
169
        0x3fffffffffffULL,
170
        0x7fffffffffffULL,
171
        0xffffffffffffULL,
172
        0x0001ffffffffffffULL,
173
        0x0003ffffffffffffULL,
174
        0x0007ffffffffffffULL,
175
        0x000fffffffffffffULL,
176
        0x001fffffffffffffULL,
177
        0x003fffffffffffffULL,
178
        0x007fffffffffffffULL,
179
        0x00ffffffffffffffULL,
180
        0x01ffffffffffffffULL,
181
        0x03ffffffffffffffULL,
182
        0x07ffffffffffffffULL,
183
        0x0fffffffffffffffULL,
184
        0x1fffffffffffffffULL,
185
        0x3fffffffffffffffULL,
186
        0x7fffffffffffffffULL,
187
        0xffffffffffffffffULL,
188
};
189
190
static const std::array<int64_t, 65> MIN_I64_VALUES = {
191
        0LL,
192
        -0x0001LL,
193
        -0x0002LL,
194
        -0x0004LL,
195
        -0x0008LL,
196
        -0x0010LL,
197
        -0x0020LL,
198
        -0x0040LL,
199
        -0x0080LL,
200
        -0x0100LL,
201
        -0x0200LL,
202
        -0x0400LL,
203
        -0x0800LL,
204
        -0x1000LL,
205
        -0x2000LL,
206
        -0x4000LL,
207
        -0x8000LL,
208
        -0x00010000LL,
209
        -0x00020000LL,
210
        -0x00040000LL,
211
        -0x00080000LL,
212
        -0x00100000LL,
213
        -0x00200000LL,
214
        -0x00400000LL,
215
        -0x00800000LL,
216
        -0x01000000LL,
217
        -0x02000000LL,
218
        -0x04000000LL,
219
        -0x08000000LL,
220
        -0x10000000LL,
221
        -0x20000000LL,
222
        -0x40000000LL,
223
        -0x80000000LL,
224
        -0x000100000000LL,
225
        -0x000200000000LL,
226
        -0x000400000000LL,
227
        -0x000800000000LL,
228
        -0x001000000000LL,
229
        -0x002000000000LL,
230
        -0x004000000000LL,
231
        -0x008000000000LL,
232
        -0x010000000000LL,
233
        -0x020000000000LL,
234
        -0x040000000000LL,
235
        -0x080000000000LL,
236
        -0x100000000000LL,
237
        -0x200000000000LL,
238
        -0x400000000000LL,
239
        -0x800000000000LL,
240
        -0x0001000000000000LL,
241
        -0x0002000000000000LL,
242
        -0x0004000000000000LL,
243
        -0x0008000000000000LL,
244
        -0x0010000000000000LL,
245
        -0x0020000000000000LL,
246
        -0x0040000000000000LL,
247
        -0x0080000000000000LL,
248
        -0x0100000000000000LL,
249
        -0x0200000000000000LL,
250
        -0x0400000000000000LL,
251
        -0x0800000000000000LL,
252
        -0x1000000000000000LL,
253
        -0x2000000000000000LL,
254
        -0x4000000000000000LL,
255
        INT64_MIN,
256
};
257
258
static const std::array<int64_t, 65> MAX_I64_VALUES = {
259
        0x00LL,
260
        0x0000LL,
261
        0x0001LL,
262
        0x0003LL,
263
        0x0007LL,
264
        0x000fLL,
265
        0x001fLL,
266
        0x003fLL,
267
        0x007fLL,
268
        0x00ffLL,
269
        0x01ffLL,
270
        0x03ffLL,
271
        0x07ffLL,
272
        0x0fffLL,
273
        0x1fffLL,
274
        0x3fffLL,
275
        0x7fffLL,
276
        0x0000ffffLL,
277
        0x0001ffffLL,
278
        0x0003ffffLL,
279
        0x0007ffffLL,
280
        0x000fffffLL,
281
        0x001fffffLL,
282
        0x003fffffLL,
283
        0x007fffffLL,
284
        0x00ffffffLL,
285
        0x01ffffffLL,
286
        0x03ffffffLL,
287
        0x07ffffffLL,
288
        0x0fffffffLL,
289
        0x1fffffffLL,
290
        0x3fffffffLL,
291
        0x7fffffffLL,
292
        0x0000ffffffffLL,
293
        0x0001ffffffffLL,
294
        0x0003ffffffffLL,
295
        0x0007ffffffffLL,
296
        0x000fffffffffLL,
297
        0x001fffffffffLL,
298
        0x003fffffffffLL,
299
        0x007fffffffffLL,
300
        0x00ffffffffffLL,
301
        0x01ffffffffffLL,
302
        0x03ffffffffffLL,
303
        0x07ffffffffffLL,
304
        0x0fffffffffffLL,
305
        0x1fffffffffffLL,
306
        0x3fffffffffffLL,
307
        0x7fffffffffffLL,
308
        0x0000ffffffffffffLL,
309
        0x0001ffffffffffffLL,
310
        0x0003ffffffffffffLL,
311
        0x0007ffffffffffffLL,
312
        0x000fffffffffffffLL,
313
        0x001fffffffffffffLL,
314
        0x003fffffffffffffLL,
315
        0x007fffffffffffffLL,
316
        0x00ffffffffffffffLL,
317
        0x01ffffffffffffffLL,
318
        0x03ffffffffffffffLL,
319
        0x07ffffffffffffffLL,
320
        0x0fffffffffffffffLL,
321
        0x1fffffffffffffffLL,
322
        0x3fffffffffffffffLL,
323
        0x7fffffffffffffffLL,
324
};
325
326
BitStreamWriter::BitStreamWriter(uint8_t* buffer, size_t bufferBitSize, BitsTag) :
327
        m_buffer(buffer, (bufferBitSize + 7) / 8),
328
        m_bitIndex(0),
329
        m_bufferBitSize(bufferBitSize)
330
1
{}
331
332
BitStreamWriter::BitStreamWriter(uint8_t* buffer, size_t bufferByteSize) :
333
        BitStreamWriter(Span<uint8_t>(buffer, bufferByteSize))
334
3.40k
{}
335
336
BitStreamWriter::BitStreamWriter(Span<uint8_t> buffer) :
337
        m_buffer(buffer),
338
        m_bitIndex(0),
339
        m_bufferBitSize(buffer.size() * 8)
340
3.41k
{}
341
342
BitStreamWriter::BitStreamWriter(Span<uint8_t> buffer, size_t bufferBitSize) :
343
        m_buffer(buffer),
344
        m_bitIndex(0),
345
        m_bufferBitSize(bufferBitSize)
346
471
{
347
471
    if (buffer.size() < (bufferBitSize + 7) / 8)
348
1
    {
349
1
        throw CppRuntimeException("BitStreamWriter: Wrong buffer bit size ('")
350
1
                << buffer.size() << "' < '" << (bufferBitSize + 7) / 8 << "')!";
351
1
    }
352
471
}
353
354
void BitStreamWriter::writeBits(uint32_t data, uint8_t numBits)
355
8.85k
{
356
8.85k
    if (numBits > sizeof(uint32_t) * 8 || 
data > MAX_U32_VALUES[numBits]8.85k
)
357
34
    {
358
34
        throw CppRuntimeException("BitStreamWriter: Writing of ")
359
34
                << numBits << "-bits value '" << data << "' failed!";
360
34
    }
361
362
8.81k
    writeUnsignedBits(data, numBits);
363
8.81k
}
364
365
void BitStreamWriter::writeBits64(uint64_t data, uint8_t numBits)
366
4.35k
{
367
4.35k
    if (numBits > sizeof(uint64_t) * 8 || 
data > MAX_U64_VALUES[numBits]4.35k
)
368
66
    {
369
66
        throw CppRuntimeException("BitStreamWriter: Writing of ")
370
66
                << numBits << "-bits value '" << data << "' failed!";
371
66
    }
372
373
4.28k
    writeUnsignedBits64(data, numBits);
374
4.28k
}
375
376
void BitStreamWriter::writeSignedBits(int32_t data, uint8_t numBits)
377
1.62k
{
378
1.62k
    if (numBits > sizeof(int32_t) * 8 || 
data < MIN_I32_VALUES[numBits]1.62k
||
data > MAX_I32_VALUES[numBits]1.59k
)
379
65
    {
380
65
        throw CppRuntimeException("BitStreamWriter: Writing of ")
381
65
                << numBits << "-bits value '" << data << "' failed!";
382
65
    }
383
384
1.56k
    writeUnsignedBits(static_cast<uint32_t>(data) & MAX_U32_VALUES[numBits], numBits);
385
1.56k
}
386
387
void BitStreamWriter::writeSignedBits64(int64_t data, uint8_t numBits)
388
2.18k
{
389
2.18k
    if (numBits > sizeof(int64_t) * 8 || 
data < MIN_I64_VALUES[numBits]2.18k
||
data > MAX_I64_VALUES[numBits]2.12k
)
390
129
    {
391
129
        throw CppRuntimeException("BitStreamWriter: Writing of ")
392
129
                << numBits << "-bits value '" << data << "' failed!";
393
129
    }
394
395
2.05k
    writeUnsignedBits64(static_cast<uint64_t>(data) & MAX_U64_VALUES[numBits], numBits);
396
2.05k
}
397
398
void BitStreamWriter::writeVarInt64(int64_t data)
399
4.42k
{
400
4.42k
    writeSignedVarNum(data, 8, zserio::bitSizeOfVarInt64(data) / 8);
401
4.42k
}
402
403
void BitStreamWriter::writeVarInt32(int32_t data)
404
1.19k
{
405
1.19k
    writeSignedVarNum(data, 4, zserio::bitSizeOfVarInt32(data) / 8);
406
1.19k
}
407
408
void BitStreamWriter::writeVarInt16(int16_t data)
409
344
{
410
344
    writeSignedVarNum(data, 2, zserio::bitSizeOfVarInt16(data) / 8);
411
344
}
412
413
void BitStreamWriter::writeVarUInt64(uint64_t data)
414
3.14k
{
415
3.14k
    writeUnsignedVarNum(data, 8, zserio::bitSizeOfVarUInt64(data) / 8);
416
3.14k
}
417
418
void BitStreamWriter::writeVarUInt32(uint32_t data)
419
820
{
420
820
    writeUnsignedVarNum(data, 4, zserio::bitSizeOfVarUInt32(data) / 8);
421
820
}
422
423
void BitStreamWriter::writeVarUInt16(uint16_t data)
424
284
{
425
284
    writeUnsignedVarNum(data, 2, zserio::bitSizeOfVarUInt16(data) / 8);
426
284
}
427
428
void BitStreamWriter::writeVarInt(int64_t data)
429
5.50k
{
430
5.50k
    if (data == INT64_MIN)
431
159
        writeBits(0x80, 8); // INT64_MIN is encoded as -0
432
5.34k
    else
433
5.34k
        writeSignedVarNum(data, 9, zserio::bitSizeOfVarInt(data) / 8);
434
5.50k
}
435
436
void BitStreamWriter::writeVarUInt(uint64_t data)
437
2.75k
{
438
2.75k
    writeUnsignedVarNum(data, 9, zserio::bitSizeOfVarUInt(data) / 8);
439
2.75k
}
440
441
void BitStreamWriter::writeVarSize(uint32_t data)
442
3.11k
{
443
3.11k
    writeUnsignedVarNum(data, 5, zserio::bitSizeOfVarSize(data) / 8);
444
3.11k
}
445
446
void BitStreamWriter::writeFloat16(float data)
447
305
{
448
305
    const uint16_t halfPrecisionFloat = convertFloatToUInt16(data);
449
305
    writeUnsignedBits(halfPrecisionFloat, 16);
450
305
}
451
452
void BitStreamWriter::writeFloat32(float data)
453
499
{
454
499
    const uint32_t singlePrecisionFloat = convertFloatToUInt32(data);
455
499
    writeUnsignedBits(singlePrecisionFloat, 32);
456
499
}
457
458
void BitStreamWriter::writeFloat64(double data)
459
859
{
460
859
    const uint64_t doublePrecisionFloat = convertDoubleToUInt64(data);
461
859
    writeUnsignedBits64(doublePrecisionFloat, 64);
462
859
}
463
464
void BitStreamWriter::writeBytes(Span<const uint8_t> data)
465
99
{
466
99
    const size_t len = data.size();
467
99
    writeVarSize(convertSizeToUInt32(len));
468
469
99
    const BitPosType beginBitPosition = getBitPosition();
470
99
    if ((beginBitPosition & 0x07U) != 0)
471
52
    {
472
        // we are not aligned to byte
473
180
        for (size_t i = 0; i < len; 
++i128
)
474
128
            writeBits(data[i], 8);
475
52
    }
476
47
    else
477
47
    {
478
        // we are aligned to bytes
479
47
        setBitPosition(beginBitPosition + len * 8);
480
47
        if (hasWriteBuffer())
481
45
            std::copy(data.begin(), data.end(), m_buffer.begin() + beginBitPosition / 8);
482
47
    }
483
99
}
484
485
void BitStreamWriter::writeString(StringView data)
486
161
{
487
161
    const size_t len = data.size();
488
161
    writeVarSize(convertSizeToUInt32(len));
489
490
161
    const BitPosType beginBitPosition = getBitPosition();
491
161
    if ((beginBitPosition & 0x07U) != 0)
492
78
    {
493
        // we are not aligned to byte
494
1.54k
        for (size_t i = 0; i < len; 
++i1.47k
)
495
1.47k
            writeBits(static_cast<uint8_t>(data[i]), 8);
496
78
    }
497
83
    else
498
83
    {
499
        // we are aligned to bytes
500
83
        setBitPosition(beginBitPosition + len * 8);
501
83
        if (hasWriteBuffer())
502
80
            std::copy(data.begin(), data.begin() + len, m_buffer.data() + beginBitPosition / 8);
503
83
    }
504
161
}
505
506
void BitStreamWriter::writeBool(bool data)
507
909
{
508
909
    writeBits((data ? 
1391
:
0518
), 1);
509
909
}
510
511
void BitStreamWriter::setBitPosition(BitPosType position)
512
704
{
513
704
    if (hasWriteBuffer())
514
695
        checkCapacity(position);
515
516
704
    m_bitIndex = position;
517
704
}
518
519
void BitStreamWriter::alignTo(size_t alignment)
520
4.73k
{
521
4.73k
    const BitPosType offset = getBitPosition() % alignment;
522
4.73k
    if (offset != 0)
523
2.46k
    {
524
2.46k
        const uint8_t skip = static_cast<uint8_t>(alignment - offset);
525
2.46k
        writeBits64(0, skip);
526
2.46k
    }
527
4.73k
}
528
529
const uint8_t* BitStreamWriter::getWriteBuffer() const
530
515
{
531
515
    return m_buffer.data();
532
515
}
533
534
Span<const uint8_t> BitStreamWriter::getBuffer() const
535
18
{
536
18
    return m_buffer;
537
18
}
538
539
void BitStreamWriter::writeUnsignedBits(uint32_t data, uint8_t numBits)
540
103k
{
541
103k
    if (!hasWriteBuffer())
542
37.3k
    {
543
37.3k
        m_bitIndex += numBits;
544
37.3k
        return;
545
37.3k
    }
546
547
66.4k
    checkCapacity(m_bitIndex + numBits);
548
549
66.4k
    uint8_t restNumBits = numBits;
550
66.4k
    const uint8_t bitsUsed = m_bitIndex & 0x07U;
551
66.4k
    uint8_t bitsFree = static_cast<uint8_t>(8 - bitsUsed);
552
66.4k
    size_t byteIndex = m_bitIndex / 8;
553
554
66.4k
    if (restNumBits > bitsFree)
555
46.3k
    {
556
        // first part
557
46.3k
        const uint8_t shiftNum = static_cast<uint8_t>(restNumBits - bitsFree);
558
46.3k
        const uint8_t maskedByte = static_cast<uint8_t>(m_buffer[byteIndex] & ~(0xFFU >> bitsUsed));
559
46.3k
        m_buffer[byteIndex++] = static_cast<uint8_t>(maskedByte | (data >> shiftNum));
560
46.3k
        restNumBits = static_cast<uint8_t>(restNumBits - bitsFree);
561
562
        // middle parts
563
64.3k
        while (restNumBits >= 8)
564
18.0k
        {
565
18.0k
            restNumBits = static_cast<uint8_t>(restNumBits - 8);
566
18.0k
            m_buffer[byteIndex++] = static_cast<uint8_t>((data >> restNumBits) & MAX_U32_VALUES[8]);
567
18.0k
        }
568
569
        // reset bits free
570
46.3k
        bitsFree = 8;
571
46.3k
    }
572
573
    // last part
574
66.4k
    if (restNumBits > 0)
575
64.2k
    {
576
64.2k
        const uint8_t shiftNum = static_cast<uint8_t>(bitsFree - restNumBits);
577
64.2k
        const uint32_t mask = MAX_U32_VALUES[restNumBits];
578
64.2k
        const uint8_t maskedByte =
579
64.2k
                m_buffer[byteIndex] & static_cast<uint8_t>(~static_cast<uint8_t>(mask << shiftNum));
580
64.2k
        m_buffer[byteIndex] = static_cast<uint8_t>(maskedByte | ((data & mask) << shiftNum));
581
64.2k
    }
582
583
66.4k
    m_bitIndex += numBits;
584
66.4k
}
585
586
inline void BitStreamWriter::writeUnsignedBits64(uint64_t data, uint8_t numBits)
587
7.20k
{
588
7.20k
    if (numBits <= 32)
589
4.04k
    {
590
4.04k
        writeUnsignedBits(static_cast<uint32_t>(data), numBits);
591
4.04k
    }
592
3.16k
    else
593
3.16k
    {
594
3.16k
        writeUnsignedBits(static_cast<uint32_t>(data >> 32U), static_cast<uint8_t>(numBits - 32));
595
3.16k
        writeUnsignedBits(static_cast<uint32_t>(data), 32);
596
3.16k
    }
597
7.20k
}
598
599
inline void BitStreamWriter::writeSignedVarNum(int64_t value, size_t maxVarBytes, size_t numVarBytes)
600
11.3k
{
601
11.3k
    const uint64_t absValue = static_cast<uint64_t>(value < 0 ? 
-value3.92k
:
value7.37k
);
602
11.3k
    writeVarNum(absValue, true, value < 0, maxVarBytes, numVarBytes);
603
11.3k
}
604
605
inline void BitStreamWriter::writeUnsignedVarNum(uint64_t value, size_t maxVarBytes, size_t numVarBytes)
606
10.1k
{
607
10.1k
    writeVarNum(value, false, false, maxVarBytes, numVarBytes);
608
10.1k
}
609
610
inline void BitStreamWriter::writeVarNum(
611
        uint64_t value, bool hasSign, bool isNegative, size_t maxVarBytes, size_t numVarBytes)
612
21.4k
{
613
21.4k
    static const std::array<uint64_t, 8> bitMasks = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
614
21.4k
    const bool hasMaxByteRange = (numVarBytes == maxVarBytes);
615
616
103k
    for (size_t i = 0; i < numVarBytes; 
i++81.9k
)
617
81.9k
    {
618
81.9k
        uint8_t byte = 0x00;
619
81.9k
        uint8_t numBits = 8;
620
81.9k
        const bool hasNextByte = (i < numVarBytes - 1);
621
81.9k
        const bool hasSignBit = (hasSign && 
i == 048.6k
);
622
81.9k
        if (hasSignBit)
623
11.3k
        {
624
11.3k
            if (isNegative)
625
3.92k
                byte |= 0x80U;
626
11.3k
            numBits--;
627
11.3k
        }
628
81.9k
        if (hasNextByte)
629
60.5k
        {
630
60.5k
            numBits--;
631
60.5k
            const uint8_t add = static_cast<uint8_t>(0x01U << numBits);
632
60.5k
            byte = static_cast<uint8_t>(byte | add); // use bit 6 if signed bit is present, use bit 7 otherwise
633
60.5k
        }
634
21.4k
        else // this is the last byte
635
21.4k
        {
636
21.4k
            if (!hasMaxByteRange) // next byte indicator is not used in last byte in case of max byte range
637
18.8k
                numBits--;
638
21.4k
        }
639
640
81.9k
        const size_t shiftBits = (numVarBytes - (i + 1)) * 7 + ((hasMaxByteRange && 
hasNextByte17.7k
) ?
115.1k
:
066.8k
);
641
81.9k
        const uint8_t add = static_cast<uint8_t>((value >> shiftBits) & bitMasks[numBits - 1]);
642
81.9k
        byte = static_cast<uint8_t>(byte | add);
643
81.9k
        writeUnsignedBits(byte, 8);
644
81.9k
    }
645
21.4k
}
646
647
inline void BitStreamWriter::throwInsufficientCapacityException() const
648
71
{
649
71
    throw InsufficientCapacityException("BitStreamWriter: Reached end of bit buffer!");
650
71
}
651
652
inline void BitStreamWriter::checkCapacity(size_t bitSize) const
653
67.1k
{
654
67.1k
    if (bitSize > m_bufferBitSize)
655
71
        throwInsufficientCapacityException();
656
67.1k
}
657
658
} // namespace zserio