Coverage Report

Created: 2023-12-13 14:58

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