Coverage Report

Created: 2024-07-18 11:41

test/zserio/BitStreamTest.cpp
Line
Count
Source
1
#include <array>
2
#include <cstring>
3
#include <functional>
4
#include <string>
5
6
#include "gtest/gtest.h"
7
#include "zserio/BitStreamReader.h"
8
#include "zserio/BitStreamWriter.h"
9
#include "zserio/CppRuntimeException.h"
10
#include "zserio/Types.h"
11
#include "zserio/Vector.h"
12
13
namespace zserio
14
{
15
16
class BitStreamTest : public ::testing::Test
17
{
18
public:
19
    BitStreamTest() :
20
            m_byteBuffer(),
21
            m_externalWriter(m_byteBuffer.data(), m_byteBuffer.size()),
22
            m_dummyWriter(nullptr, 0)
23
23
    {
24
23
        m_byteBuffer.fill(0);
25
23
    }
26
27
protected:
28
    template <typename T, size_t N, typename U>
29
    void testImpl(const std::array<T, N>& values, std::function<void(BitStreamWriter&, U)> writerFunc,
30
            std::function<T(BitStreamReader&)> readerFunc, uint8_t maxStartBitPos)
31
16
    {
32
16
        testBitStreamValues(values, m_externalWriter, writerFunc, readerFunc, maxStartBitPos);
33
16
        testBitStreamValues(values, m_dummyWriter, writerFunc, readerFunc, maxStartBitPos);
34
16
    }
35
36
    template <typename T, size_t N, typename U>
37
    void testBitStreamValues(const std::array<T, N>& values, BitStreamWriter& writer,
38
            std::function<void(BitStreamWriter&, U)> writerFunc, std::function<T(BitStreamReader&)> readerFunc,
39
            uint8_t maxStartBitPos)
40
32
    {
41
1.04k
        for (uint8_t bitPos = 0; bitPos < maxStartBitPos; 
++bitPos1.00k
)
42
1.00k
        {
43
1.00k
            if (bitPos > 0)
44
976
            {
45
976
                writer.writeBits64(0, bitPos);
46
976
            }
47
19.1k
            for (size_t i = 0; i < N; 
++i18.1k
)
48
18.1k
            {
49
18.1k
                writerFunc(writer, values.at(i));
50
18.1k
            }
51
52
1.00k
            if (!writer.hasWriteBuffer())
53
504
            {
54
504
                continue;
55
504
            }
56
57
504
            BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag());
58
504
            if (bitPos > 0)
59
488
            {
60
488
                reader.readBits64(bitPos);
61
488
            }
62
9.57k
            for (size_t i = 0; i < N; 
++i9.07k
)
63
9.07k
            {
64
18.1k
                ASSERT_EQ(readerFunc(reader), values.at(i)) << "[bitPos=" << bitPos << "]";
65
9.07k
            }
66
67
504
            writer.setBitPosition(0);
68
504
            m_byteBuffer.fill(0);
69
504
        }
70
32
    }
71
72
    void testReadBits(BitStreamWriter& writer)
73
2
    {
74
2
        writer.writeBits(1, 1);
75
2
        writer.writeBits(2, 2);
76
2
        writer.writeBits(42, 12);
77
2
        writer.writeBits(15999999, 24);
78
2
        writer.writeBits(7, 3);
79
80
2
        if (!writer.hasWriteBuffer())
81
1
        {
82
1
            return;
83
1
        }
84
85
1
        BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag());
86
1
        ASSERT_EQ(1, reader.readBits(1));
87
1
        ASSERT_EQ(2, reader.readBits(2));
88
1
        ASSERT_EQ(42, reader.readBits(12));
89
1
        ASSERT_EQ(15999999, reader.readBits(24));
90
1
        ASSERT_EQ(7, reader.readBits(3));
91
1
    }
92
93
    void testReadBits64(BitStreamWriter& writer)
94
2
    {
95
2
        writer.writeBits(1, 1);
96
2
        writer.writeBits64(UINT64_C(42424242424242), 48);
97
2
        writer.writeBits64(UINT64_C(0xFFFFFFFFFFFFFFFE), 64);
98
99
2
        if (!writer.hasWriteBuffer())
100
1
        {
101
1
            return;
102
1
        }
103
104
1
        BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag());
105
1
        ASSERT_EQ(1, reader.readBits(1));
106
1
        ASSERT_EQ(UINT64_C(42424242424242), reader.readBits64(48));
107
1
        ASSERT_EQ(UINT64_C(0xFFFFFFFFFFFFFFFE), reader.readBits64(64));
108
1
    }
109
110
    void testReadSignedBits(BitStreamWriter& writer)
111
2
    {
112
2
        writer.writeSignedBits(-1, 5);
113
2
        writer.writeSignedBits(3, 12);
114
2
        writer.writeSignedBits(-142, 9);
115
116
2
        if (!writer.hasWriteBuffer())
117
1
        {
118
1
            return;
119
1
        }
120
121
1
        BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag());
122
1
        ASSERT_EQ(-1, reader.readSignedBits(5));
123
1
        ASSERT_EQ(3, reader.readSignedBits(12));
124
1
        ASSERT_EQ(-142, reader.readSignedBits(9));
125
1
    }
126
127
    void testReadSignedBits64(BitStreamWriter& writer)
128
2
    {
129
2
        writer.writeSignedBits64(INT64_C(1), 4);
130
2
        writer.writeSignedBits64(INT64_C(-1), 48);
131
2
        writer.writeSignedBits64(INT64_C(-42424242), 61);
132
2
        writer.writeSignedBits64(INT64_C(-820816), 32);
133
134
2
        if (!writer.hasWriteBuffer())
135
1
        {
136
1
            return;
137
1
        }
138
139
1
        BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag());
140
1
        ASSERT_EQ(INT64_C(1), reader.readSignedBits(4));
141
1
        ASSERT_EQ(INT64_C(-1), reader.readSignedBits64(48));
142
1
        ASSERT_EQ(INT64_C(-42424242), reader.readSignedBits64(61));
143
1
        ASSERT_EQ(INT64_C(-820816), reader.readSignedBits64(32));
144
1
    }
145
146
    void testAlignedBytes(BitStreamWriter& writer)
147
2
    {
148
        // reads aligned data directly from buffer, bit cache should remain empty
149
2
        writer.writeBits(UINT8_C(0xCA), 8);
150
2
        writer.writeBits(UINT16_C(0xCAFE), 16);
151
2
        writer.writeBits(UINT32_C(0xCAFEC0), 24);
152
2
        writer.writeBits(UINT32_C(0xCAFEC0DE), 32);
153
2
        writer.writeBits64(UINT64_C(0xCAFEC0DEDE), 40);
154
2
        writer.writeBits64(UINT64_C(0xCAFEC0DEDEAD), 48);
155
2
        writer.writeBits64(UINT64_C(0xCAFEC0DEDEADFA), 56);
156
2
        writer.writeBits64(UINT64_C(0xCAFEC0DEDEADFACE), 64);
157
158
2
        if (!writer.hasWriteBuffer())
159
1
        {
160
1
            return;
161
1
        }
162
163
1
        BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag());
164
1
        ASSERT_EQ(UINT8_C(0xCA), reader.readBits(8));
165
1
        ASSERT_EQ(UINT16_C(0xCAFE), reader.readBits(16));
166
1
        ASSERT_EQ(UINT32_C(0xCAFEC0), reader.readBits(24));
167
1
        ASSERT_EQ(UINT32_C(0xCAFEC0DE), reader.readBits(32));
168
1
        ASSERT_EQ(UINT64_C(0xCAFEC0DEDE), reader.readBits64(40));
169
1
        ASSERT_EQ(UINT64_C(0xCAFEC0DEDEAD), reader.readBits64(48));
170
1
        ASSERT_EQ(UINT64_C(0xCAFEC0DEDEADFA), reader.readBits64(56));
171
1
        ASSERT_EQ(UINT64_C(0xCAFEC0DEDEADFACE), reader.readBits64(64));
172
1
    }
173
174
    void testSetBitPosition(BitStreamWriter& writer)
175
2
    {
176
2
        ASSERT_EQ(0, writer.getBitPosition());
177
2
        writer.writeBits(1, 1);
178
2
        ASSERT_EQ(1, writer.getBitPosition());
179
2
        writer.alignTo(4);
180
2
        ASSERT_EQ(4, writer.getBitPosition());
181
2
        writer.writeBits(5, 5);
182
2
        ASSERT_EQ(9, writer.getBitPosition());
183
2
        if (writer.hasWriteBuffer())
184
1
        {
185
1
            ASSERT_THROW(writer.setBitPosition(m_byteBuffer.size() * 8 + 1), CppRuntimeException);
186
1
        }
187
1
        else
188
1
        {
189
            // dummy buffer
190
1
            writer.setBitPosition(m_byteBuffer.size() * 8 + 1);
191
1
            ASSERT_EQ(m_byteBuffer.size() * 8 + 1, writer.getBitPosition());
192
1
        }
193
2
        writer.setBitPosition(4);
194
2
        ASSERT_EQ(4, writer.getBitPosition());
195
2
        writer.writeBits(3, 3);
196
2
        ASSERT_EQ(7, writer.getBitPosition());
197
198
2
        if (!writer.hasWriteBuffer())
199
1
        {
200
1
            return;
201
1
        }
202
203
1
        BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag());
204
1
        ASSERT_EQ(0, reader.getBitPosition());
205
1
        ASSERT_EQ(1, reader.readBits(1));
206
1
        ASSERT_EQ(1, reader.getBitPosition());
207
1
        reader.alignTo(4);
208
1
        ASSERT_EQ(4, reader.getBitPosition());
209
1
        ASSERT_EQ(3, reader.readBits(3));
210
1
        ASSERT_EQ(7, reader.getBitPosition());
211
1
        ASSERT_THROW(reader.setBitPosition(writer.getBitPosition() + 1), CppRuntimeException);
212
213
1
        reader.setBitPosition(4);
214
1
        ASSERT_EQ(4, reader.getBitPosition());
215
1
        ASSERT_EQ(3, reader.readBits(3));
216
1
        ASSERT_EQ(7, reader.getBitPosition());
217
1
    }
218
219
    void testAlignTo(BitStreamWriter& writer)
220
2
    {
221
2
        writer.writeBits(1, 1);
222
2
        writer.alignTo(4);
223
2
        ASSERT_EQ(4, writer.getBitPosition());
224
2
        writer.writeBits(1, 1);
225
2
        writer.alignTo(4);
226
2
        ASSERT_EQ(8, writer.getBitPosition());
227
2
        writer.writeBits(37, 11);
228
2
        writer.alignTo(8);
229
2
        ASSERT_EQ(24, writer.getBitPosition());
230
2
        writer.writeBits(1, 1);
231
2
        writer.alignTo(16);
232
2
        ASSERT_EQ(32, writer.getBitPosition());
233
2
        writer.writeBits(13, 13);
234
2
        writer.alignTo(32);
235
2
        ASSERT_EQ(64, writer.getBitPosition());
236
2
        writer.writeBits(42, 15);
237
2
        writer.alignTo(64);
238
2
        ASSERT_EQ(128, writer.getBitPosition());
239
2
        writer.writeBits(99, 9);
240
2
        ASSERT_EQ(137, writer.getBitPosition());
241
242
2
        if (!writer.hasWriteBuffer())
243
1
        {
244
1
            return;
245
1
        }
246
247
1
        BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag());
248
1
        ASSERT_EQ(1, reader.readBits(1));
249
1
        reader.alignTo(4);
250
1
        ASSERT_EQ(1, reader.readBits(1));
251
1
        reader.alignTo(4);
252
1
        ASSERT_EQ(37, reader.readBits(11));
253
1
        reader.alignTo(8);
254
1
        ASSERT_EQ(1, reader.readBits(1));
255
1
        reader.alignTo(16);
256
1
        ASSERT_EQ(13, reader.readBits(13));
257
1
        reader.alignTo(32);
258
1
        ASSERT_EQ(42, reader.readBits(15));
259
1
        reader.alignTo(64);
260
1
        ASSERT_EQ(99, reader.readBits(9));
261
1
        ASSERT_EQ(137, reader.getBitPosition());
262
1
    }
263
264
    std::array<uint8_t, 256> m_byteBuffer;
265
    BitStreamWriter m_externalWriter;
266
    BitStreamWriter m_dummyWriter;
267
};
268
269
TEST_F(BitStreamTest, readBits)
270
1
{
271
1
    testReadBits(m_externalWriter);
272
1
    testReadBits(m_dummyWriter);
273
1
}
274
275
TEST_F(BitStreamTest, readBits64)
276
1
{
277
1
    testReadBits64(m_externalWriter);
278
1
    testReadBits64(m_dummyWriter);
279
1
}
280
281
TEST_F(BitStreamTest, readSignedBits)
282
1
{
283
1
    testReadSignedBits(m_externalWriter);
284
1
    testReadSignedBits(m_dummyWriter);
285
1
}
286
287
TEST_F(BitStreamTest, readSignedBits64)
288
1
{
289
1
    testReadSignedBits64(m_externalWriter);
290
1
    testReadSignedBits64(m_dummyWriter);
291
1
}
292
293
TEST_F(BitStreamTest, alignedBytes)
294
1
{
295
1
    testAlignedBytes(m_externalWriter);
296
1
    testAlignedBytes(m_dummyWriter);
297
1
}
298
299
TEST_F(BitStreamTest, readVarInt64)
300
1
{
301
1
    const std::array<int64_t, 33> values = {
302
1
            INT64_C(0),
303
1
            INT64_C(-32),
304
1
            INT64_C(32),
305
1
            INT64_C(-4096),
306
1
            INT64_C(4096),
307
1
            INT64_C(-524288),
308
1
            INT64_C(524288),
309
1
            INT64_C(-67108864),
310
1
            INT64_C(67108864),
311
1
            INT64_C(-8589934592),
312
1
            INT64_C(8589934592),
313
1
            INT64_C(-1099511627776),
314
1
            INT64_C(1099511627776),
315
1
            INT64_C(-140737488355328),
316
1
            INT64_C(140737488355328),
317
1
            INT64_C(-18014398509481984),
318
1
            INT64_C(18014398509481984),
319
320
1
            (INT64_C(1) << (0)),
321
1
            (INT64_C(1) << (6)) - 1,
322
323
1
            (INT64_C(1) << (6)),
324
1
            (INT64_C(1) << (6 + 7)) - 1,
325
326
1
            (INT64_C(1) << (6 + 7)),
327
1
            (INT64_C(1) << (6 + 7 + 7)) - 1,
328
329
1
            (INT64_C(1) << (6 + 7 + 7)),
330
1
            (INT64_C(1) << (6 + 7 + 7 + 7)) - 1,
331
332
1
            (INT64_C(1) << (6 + 7 + 7 + 7)),
333
1
            (INT64_C(1) << (6 + 7 + 7 + 7 + 7)) - 1,
334
335
1
            (INT64_C(1) << (6 + 7 + 7 + 7 + 7)),
336
1
            (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7)) - 1,
337
338
1
            (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7)),
339
1
            (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7)) - 1,
340
341
1
            (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7)),
342
1
            (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1,
343
1
    };
344
345
1
    std::function<void(BitStreamWriter&, int64_t)> writerFunc = &BitStreamWriter::writeVarInt64;
346
1
    std::function<int64_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarInt64;
347
348
1
    testImpl(values, writerFunc, readerFunc, 63);
349
1
}
350
351
TEST_F(BitStreamTest, readVarInt32)
352
1
{
353
1
    const std::array<int32_t, 17> values = {
354
1
            static_cast<int32_t>(0),
355
1
            static_cast<int32_t>(-32),
356
1
            static_cast<int32_t>(32),
357
1
            static_cast<int32_t>(-4096),
358
1
            static_cast<int32_t>(4096),
359
1
            static_cast<int32_t>(-524288),
360
1
            static_cast<int32_t>(524288),
361
1
            static_cast<int32_t>(-67108864),
362
1
            static_cast<int32_t>(67108864),
363
364
1
            static_cast<int32_t>(1U << (0U)),
365
1
            static_cast<int32_t>(1U << (6U)) - 1,
366
367
1
            static_cast<int32_t>(1U << (6U)),
368
1
            static_cast<int32_t>(1U << (6U + 7)) - 1,
369
370
1
            static_cast<int32_t>(1U << (6U + 7)),
371
1
            static_cast<int32_t>(1U << (6U + 7 + 7)) - 1,
372
373
1
            static_cast<int32_t>(1U << (6U + 7 + 7)),
374
1
            static_cast<int32_t>(1U << (6U + 7 + 7 + 8)) - 1,
375
1
    };
376
377
1
    std::function<void(BitStreamWriter&, int32_t)> writerFunc = &BitStreamWriter::writeVarInt32;
378
1
    std::function<int32_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarInt32;
379
380
1
    testImpl(values, writerFunc, readerFunc, 31);
381
1
}
382
383
TEST_F(BitStreamTest, readVarInt16)
384
1
{
385
1
    const std::array<int16_t, 9> values = {
386
1
            static_cast<int16_t>(0),
387
1
            static_cast<int16_t>(-32),
388
1
            static_cast<int16_t>(32),
389
1
            static_cast<int16_t>(-4096),
390
1
            static_cast<int16_t>(4096),
391
392
1
            static_cast<int16_t>(1U << (0U)),
393
1
            static_cast<int16_t>(1U << (6U)) - 1,
394
395
1
            static_cast<int16_t>(1U << (6U)),
396
1
            static_cast<int16_t>(1U << (6 + 8U)) - 1,
397
1
    };
398
399
1
    std::function<void(BitStreamWriter&, int16_t)> writerFunc = &BitStreamWriter::writeVarInt16;
400
1
    std::function<int16_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarInt16;
401
402
1
    testImpl(values, writerFunc, readerFunc, 15);
403
1
}
404
405
TEST_F(BitStreamTest, readVarUInt64)
406
1
{
407
1
    const std::array<uint64_t, 19> values = {
408
1
            0,
409
1
            262144,
410
1
            524288,
411
412
1
            (UINT64_C(1) << (0U)),
413
1
            (UINT64_C(1) << (7U)) - 1,
414
415
1
            (UINT64_C(1) << (7U)),
416
1
            (UINT64_C(1) << (7U + 7)) - 1,
417
418
1
            (UINT64_C(1) << (7U + 7)),
419
1
            (UINT64_C(1) << (7U + 7 + 7)) - 1,
420
421
1
            (UINT64_C(1) << (7U + 7 + 7)),
422
1
            (UINT64_C(1) << (7U + 7 + 7 + 7)) - 1,
423
424
1
            (UINT64_C(1) << (7U + 7 + 7 + 7)),
425
1
            (UINT64_C(1) << (7U + 7 + 7 + 7 + 7)) - 1,
426
427
1
            (UINT64_C(1) << (7U + 7 + 7 + 7 + 7)),
428
1
            (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7)) - 1,
429
430
1
            (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7)),
431
1
            (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7 + 7)) - 1,
432
433
1
            (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7 + 7)),
434
1
            (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1,
435
1
    };
436
437
1
    std::function<void(BitStreamWriter&, uint64_t)> writerFunc = &BitStreamWriter::writeVarUInt64;
438
1
    std::function<uint64_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarUInt64;
439
440
1
    testImpl(values, writerFunc, readerFunc, 63);
441
1
}
442
443
TEST_F(BitStreamTest, readVarUInt32)
444
1
{
445
1
    const std::array<uint32_t, 11> values = {
446
1
            0,
447
1
            65536,
448
1
            131072,
449
450
1
            (1U << (0U)),
451
1
            (1U << (7U)) - 1,
452
453
1
            (1U << (7U)),
454
1
            (1U << (7U + 7)) - 1,
455
456
1
            (1U << (7U + 7)),
457
1
            (1U << (7U + 7 + 7)) - 1,
458
459
1
            (1U << (7U + 7 + 7)),
460
1
            (1U << (7U + 7 + 7 + 8)) - 1,
461
1
    };
462
463
1
    std::function<void(BitStreamWriter&, uint32_t)> writerFunc = &BitStreamWriter::writeVarUInt32;
464
1
    std::function<uint32_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarUInt32;
465
466
1
    testImpl(values, writerFunc, readerFunc, 31);
467
1
}
468
469
TEST_F(BitStreamTest, readVarUInt16)
470
1
{
471
1
    const std::array<uint16_t, 7> values = {
472
1
            0,
473
1
            8192,
474
1
            16384,
475
476
1
            (1U << (0U)),
477
1
            (1U << (6U)) - 1,
478
479
1
            (1U << (6U)),
480
1
            (1U << (6U + 8)) - 1,
481
1
    };
482
483
1
    std::function<void(BitStreamWriter&, uint16_t)> writerFunc = &BitStreamWriter::writeVarUInt16;
484
1
    std::function<uint16_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarUInt16;
485
486
1
    testImpl(values, writerFunc, readerFunc, 15);
487
1
}
488
489
TEST_F(BitStreamTest, readVarInt)
490
1
{
491
1
    const std::array<int64_t, 38> values = {
492
            // 1 byte
493
1
            0,
494
1
            -1,
495
1
            1,
496
1
            -static_cast<int64_t>(UINT64_C(1) << 6U) + 1,
497
1
            static_cast<int64_t>(UINT64_C(1) << 6U) - 1,
498
            // 2 bytes
499
1
            -static_cast<int64_t>(UINT64_C(1) << 6U),
500
1
            static_cast<int64_t>(UINT64_C(1) << 6U),
501
1
            -static_cast<int64_t>(UINT64_C(1) << 13U) + 1,
502
1
            static_cast<int64_t>(UINT64_C(1) << 13U) - 1,
503
            // 3 bytes
504
1
            -static_cast<int64_t>(UINT64_C(1) << 13U),
505
1
            static_cast<int64_t>(UINT64_C(1) << 13U),
506
1
            -static_cast<int64_t>(UINT64_C(1) << 20U) + 1,
507
1
            static_cast<int64_t>(UINT64_C(1) << 20U) - 1,
508
            // 4 bytes
509
1
            -static_cast<int64_t>(UINT64_C(1) << 20U),
510
1
            static_cast<int64_t>(UINT64_C(1) << 20U),
511
1
            -static_cast<int64_t>(UINT64_C(1) << 27U) + 1,
512
1
            static_cast<int64_t>(UINT64_C(1) << 27U) - 1,
513
            // 5 bytes
514
1
            -static_cast<int64_t>(UINT64_C(1) << 27U),
515
1
            static_cast<int64_t>(UINT64_C(1) << 27U),
516
1
            -static_cast<int64_t>(UINT64_C(1) << 34U) + 1,
517
1
            static_cast<int64_t>(UINT64_C(1) << 34U) - 1,
518
            // 6 bytes
519
1
            -static_cast<int64_t>(UINT64_C(1) << 34U),
520
1
            static_cast<int64_t>(UINT64_C(1) << 34U),
521
1
            -static_cast<int64_t>(UINT64_C(1) << 41U) + 1,
522
1
            static_cast<int64_t>(UINT64_C(1) << 41U) - 1,
523
            // 7 bytes
524
1
            -static_cast<int64_t>(UINT64_C(1) << 41U),
525
1
            static_cast<int64_t>(UINT64_C(1) << 41U),
526
1
            -static_cast<int64_t>(UINT64_C(1) << 48U) + 1,
527
1
            static_cast<int64_t>(UINT64_C(1) << 48U) - 1,
528
            // 8 bytes
529
1
            -static_cast<int64_t>(UINT64_C(1) << 48U),
530
1
            static_cast<int64_t>(UINT64_C(1) << 48U),
531
1
            -static_cast<int64_t>(UINT64_C(1) << 55U) + 1,
532
1
            static_cast<int64_t>(UINT64_C(1) << 55U) - 1,
533
            // 9 bytes
534
1
            -static_cast<int64_t>(UINT64_C(1) << 55U),
535
1
            static_cast<int64_t>(UINT64_C(1) << 55U),
536
1
            INT64_MIN + 1,
537
1
            INT64_MAX,
538
539
            // special case - stored as -0 (1 byte)
540
1
            INT64_MIN,
541
1
    };
542
543
1
    std::function<void(BitStreamWriter&, int64_t)> writerFunc = &BitStreamWriter::writeVarInt;
544
1
    std::function<int64_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarInt;
545
546
1
    testImpl(values, writerFunc, readerFunc, 63);
547
1
}
548
549
TEST_F(BitStreamTest, readVarUInt)
550
1
{
551
1
    const std::array<uint64_t, 19> values = {
552
            // 1 byte
553
1
            0,
554
1
            1,
555
1
            (UINT64_C(1) << 7U) - 1,
556
            // 2 bytes
557
1
            (UINT64_C(1) << 7U),
558
1
            (UINT64_C(1) << 14U) - 1,
559
            // 3 bytes
560
1
            (UINT64_C(1) << 14U),
561
1
            (UINT64_C(1) << 21U) - 1,
562
            // 4 bytes
563
1
            (UINT64_C(1) << 21U),
564
1
            (UINT64_C(1) << 28U) - 1,
565
            // 5 bytes
566
1
            (UINT64_C(1) << 28U),
567
1
            (UINT64_C(1) << 35U) - 1,
568
            // 6 bytes
569
1
            (UINT64_C(1) << 35U),
570
1
            (UINT64_C(1) << 42U) - 1,
571
            // 7 bytes
572
1
            (UINT64_C(1) << 42U),
573
1
            (UINT64_C(1) << 49U) - 1,
574
            // 8 bytes
575
1
            (UINT64_C(1) << 49U),
576
1
            (UINT64_C(1) << 56U) - 1,
577
            // 9 bytes
578
1
            (UINT64_C(1) << 56U),
579
1
            UINT64_MAX,
580
1
    };
581
582
1
    std::function<void(BitStreamWriter&, uint64_t)> writerFunc = &BitStreamWriter::writeVarUInt;
583
1
    std::function<uint64_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarUInt;
584
585
1
    testImpl(values, writerFunc, readerFunc, 63);
586
1
}
587
588
TEST_F(BitStreamTest, readVarSize)
589
1
{
590
1
    const std::array<uint32_t, 13> values = {
591
1
            0,
592
1
            65536,
593
1
            131072,
594
595
1
            (1U << (0U)),
596
1
            (1U << (7U)) - 1,
597
598
1
            (1U << (7U)),
599
1
            (1U << (7U + 7)) - 1,
600
601
1
            (1U << (7U + 7)),
602
1
            (1U << (7U + 7 + 7)) - 1,
603
604
1
            (1U << (7U + 7 + 7)),
605
1
            (1U << (7U + 7 + 7 + 7)) - 1,
606
607
1
            (1U << (7U + 7 + 7 + 7)),
608
1
            (1U << (7U + 7 + 7 + 7 + 3)) - 1,
609
1
    };
610
611
1
    std::function<void(BitStreamWriter&, uint32_t)> writerFunc = &BitStreamWriter::writeVarSize;
612
1
    std::function<uint32_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarSize;
613
614
1
    testImpl(values, writerFunc, readerFunc, 31);
615
1
}
616
617
TEST_F(BitStreamTest, readFloat16)
618
1
{
619
1
    const std::array<float, 6> values = {2.0, -2.0, 0.6171875, 0.875, 9.875, 42.5};
620
621
1
    std::function<void(BitStreamWriter&, float)> writerFunc = &BitStreamWriter::writeFloat16;
622
1
    std::function<float(BitStreamReader&)> readerFunc = &BitStreamReader::readFloat16;
623
624
1
    testImpl(values, writerFunc, readerFunc, 15);
625
1
}
626
627
TEST_F(BitStreamTest, readFloat32)
628
1
{
629
1
    const std::array<float, 6> values = {2.0, -2.0, 0.6171875, 0.875, 9.875, 42.5};
630
631
1
    std::function<void(BitStreamWriter&, float)> writerFunc = &BitStreamWriter::writeFloat32;
632
1
    std::function<float(BitStreamReader&)> readerFunc = &BitStreamReader::readFloat32;
633
634
1
    testImpl(values, writerFunc, readerFunc, 31);
635
1
}
636
637
TEST_F(BitStreamTest, readFloat64)
638
1
{
639
1
    const std::array<double, 6> values = {2.0, -2.0, 0.6171875, 0.875, 9.875, 42.5};
640
641
1
    std::function<void(BitStreamWriter&, double)> writerFunc = &BitStreamWriter::writeFloat64;
642
1
    std::function<double(BitStreamReader&)> readerFunc = &BitStreamReader::readFloat64;
643
644
1
    testImpl(values, writerFunc, readerFunc, 61);
645
1
}
646
647
TEST_F(BitStreamTest, readString)
648
1
{
649
1
    const std::array<std::string, 3> values = {
650
1
            "Hello World", "\n\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\"\'Hello World2\0nonWrittenPart",
651
1
            "Price: \xE2\x82\xAC 3 what's this? -> \xC2\xA2" /* '€' '¢' */
652
1
    };
653
654
1
    std::function<void(BitStreamWriter&, const std::string&)> writerFunc = &BitStreamWriter::writeString;
655
1
    std::function<std::string(BitStreamReader&)> readerFunc = std::bind(
656
1
            &BitStreamReader::readString<std::allocator<char>>, std::placeholders::_1, std::allocator<char>());
657
658
1
    testImpl(values, writerFunc, readerFunc, 7);
659
1
}
660
661
TEST_F(BitStreamTest, readBool)
662
1
{
663
1
    const std::array<bool, 2> values = {true, false};
664
665
1
    std::function<void(BitStreamWriter&, bool)> writerFunc = &BitStreamWriter::writeBool;
666
1
    std::function<bool(BitStreamReader&)> readerFunc = &BitStreamReader::readBool;
667
668
1
    testImpl(values, writerFunc, readerFunc, 1);
669
1
}
670
671
TEST_F(BitStreamTest, readBitBuffer)
672
1
{
673
1
    const std::array<BitBuffer, 2> values = {BitBuffer(std::vector<uint8_t>({0xAB, 0xE0}), 11),
674
1
            BitBuffer(std::vector<uint8_t>({0xAB, 0xCD, 0xFE}), 23)};
675
676
1
    std::function<void(BitStreamWriter&, const BitBuffer&)> writerFunc =
677
1
            &BitStreamWriter::writeBitBuffer<std::allocator<uint8_t>>;
678
1
    std::function<BitBuffer(BitStreamReader&)> readerFunc = std::bind(
679
1
            &BitStreamReader::readBitBuffer<std::allocator<uint8_t>>, std::placeholders::_1,
680
1
            std::allocator<uint8_t>());
681
682
1
    testImpl(values, writerFunc, readerFunc, 7);
683
1
}
684
685
TEST_F(BitStreamTest, readBytes)
686
1
{
687
1
    const std::array<vector<uint8_t>, 2> values = {
688
1
            vector<uint8_t>{{0, 255}},
689
1
            vector<uint8_t>{{1, 127, 128, 254}},
690
1
    };
691
692
1
    std::function<void(BitStreamWriter&, const vector<uint8_t>&)> writerFunc = &BitStreamWriter::writeBytes;
693
1
    std::function<vector<uint8_t>(BitStreamReader&)> readerFunc = std::bind(
694
1
            &BitStreamReader::readBytes<std::allocator<uint8_t>>, std::placeholders::_1,
695
1
            std::allocator<uint8_t>());
696
697
1
    testImpl(values, writerFunc, readerFunc, 7);
698
1
}
699
700
TEST_F(BitStreamTest, setBitPosition)
701
1
{
702
1
    testSetBitPosition(m_externalWriter);
703
1
    testSetBitPosition(m_dummyWriter);
704
1
}
705
706
TEST_F(BitStreamTest, alignTo)
707
1
{
708
1
    testAlignTo(m_externalWriter);
709
1
    testAlignTo(m_dummyWriter);
710
1
}
711
712
} // namespace zserio