Coverage Report

Created: 2024-04-30 09:35

test/zserio/BitStreamReaderTest.cpp
Line
Count
Source
1
#include <array>
2
#include <cstring>
3
4
#include "gtest/gtest.h"
5
#include "zserio/BitStreamReader.h"
6
#include "zserio/CppRuntimeException.h"
7
8
namespace zserio
9
{
10
11
class BitStreamReaderTest : public ::testing::Test
12
{
13
public:
14
    BitStreamReaderTest() :
15
            m_byteBuffer(),
16
            m_reader(m_byteBuffer.data(), m_byteBuffer.size())
17
12
    {
18
12
        m_byteBuffer.fill(0);
19
12
    }
20
21
protected:
22
    std::array<uint8_t, 16> m_byteBuffer;
23
    BitStreamReader m_reader;
24
};
25
26
TEST_F(BitStreamReaderTest, spanConstructor)
27
1
{
28
1
    const std::array<const uint8_t, 3> data = {0xAE, 0xEA, 0x80};
29
1
    const Span<const uint8_t> span(data);
30
1
    BitStreamReader reader(span);
31
32
1
    ASSERT_EQ(span.size() * 8, reader.getBufferBitSize());
33
1
    ASSERT_EQ(0xAEE, reader.readBits(12));
34
1
    ASSERT_EQ(0xA, reader.readBits(4));
35
1
    ASSERT_EQ(0x80, reader.readBits(8));
36
37
1
    ASSERT_THROW(reader.readBits(1), CppRuntimeException);
38
1
}
39
40
TEST_F(BitStreamReaderTest, spanConstructorWithBitSize)
41
1
{
42
1
    const std::array<const uint8_t, 3> data = {0xAE, 0xEA, 0x80};
43
1
    const Span<const uint8_t> span(data);
44
1
    BitStreamReader reader(span, 23);
45
1
    ASSERT_THROW(BitStreamReader wrongReader(span, 25), CppRuntimeException);
46
47
1
    ASSERT_EQ(23, reader.getBufferBitSize());
48
1
    ASSERT_EQ(0xAEE, reader.readBits(12));
49
1
    ASSERT_EQ(0xA, reader.readBits(4));
50
1
    ASSERT_EQ(0x40, reader.readBits(7));
51
52
1
    ASSERT_THROW(reader.readBits(1), CppRuntimeException);
53
1
}
54
55
TEST_F(BitStreamReaderTest, bitBufferConstructor)
56
1
{
57
1
    const std::vector<uint8_t> data = {0xAE, 0xEA, 0x80};
58
1
    BitBuffer bitBuffer(data, 17);
59
1
    BitStreamReader reader(bitBuffer);
60
61
1
    ASSERT_EQ(bitBuffer.getBitSize(), reader.getBufferBitSize());
62
1
    ASSERT_EQ(0xAEE, reader.readBits(12));
63
1
    ASSERT_EQ(0xA, reader.readBits(4));
64
1
    ASSERT_EQ(1, reader.readBits(1));
65
66
1
    ASSERT_THROW(reader.readBits(1), CppRuntimeException);
67
68
1
    ASSERT_THROW(BitStreamReader(nullptr, std::numeric_limits<size_t>::max() / 8), CppRuntimeException);
69
1
}
70
71
TEST_F(BitStreamReaderTest, bitBufferConstructorOverflow)
72
1
{
73
1
    const std::vector<uint8_t> data = {0xFF, 0xFF, 0xF0};
74
1
    BitBuffer bitBuffer(data, 19);
75
1
    BitStreamReader reader(bitBuffer);
76
77
1
    ASSERT_EQ(bitBuffer.getBitSize(), reader.getBufferBitSize());
78
1
    ASSERT_THROW(reader.readBits(20), CppRuntimeException);
79
1
}
80
81
TEST_F(BitStreamReaderTest, readUnalignedData)
82
1
{
83
    // number expected to read at offset
84
1
    const uint8_t testValue = 123;
85
86
66
    for (uint8_t offset = 0; offset <= 64; 
++offset65
)
87
65
    {
88
65
        BitBuffer buffer(8 + offset);
89
90
        // write test value at offset to data buffer
91
65
        buffer.getData()[offset / 8U] = static_cast<uint8_t>(
92
65
                buffer.getData()[offset / 8U] | static_cast<uint8_t>(testValue >> (offset % 8U)));
93
65
        if (offset % 8 != 0) // don't write behind the buffer
94
56
        {
95
56
            buffer.getData()[offset / 8U + 1] = static_cast<uint8_t>(buffer.getData()[offset / 8U + 1] |
96
56
                    static_cast<uint8_t>(testValue << (8U - (offset % 8U))));
97
56
        }
98
99
65
        BitStreamReader reader(buffer);
100
101
        // read offset bits
102
65
        ASSERT_EQ(0, reader.readBits64(offset));
103
104
        // read magic number
105
130
        ASSERT_EQ(testValue, reader.readBits(8)) << "Offset: " << offset;
106
107
        // check eof
108
130
        ASSERT_THROW(reader.readBits(1), CppRuntimeException) << "Offset: " << offset;
109
65
    }
110
1
}
111
112
TEST_F(BitStreamReaderTest, readBits)
113
1
{
114
    // check invalid bitlength acceptance
115
1
    ASSERT_THROW(m_reader.readBits(255), CppRuntimeException);
116
1
    ASSERT_THROW(m_reader.readBits(33), CppRuntimeException);
117
118
    // return 0 for 0 bits
119
1
    ASSERT_EQ(0, m_reader.readBits(0));
120
1
}
121
122
TEST_F(BitStreamReaderTest, readBits64)
123
1
{
124
    // check invalid bit length acceptance
125
1
    ASSERT_THROW(m_reader.readBits64(255), CppRuntimeException);
126
1
    ASSERT_THROW(m_reader.readBits64(65), CppRuntimeException);
127
128
    // return 0 for 0 bits
129
1
    ASSERT_EQ(0, m_reader.readBits64(0));
130
1
}
131
132
TEST_F(BitStreamReaderTest, readSignedBits)
133
1
{
134
    // check invalid bit length acceptance
135
1
    ASSERT_THROW(m_reader.readSignedBits(255), CppRuntimeException);
136
1
    ASSERT_THROW(m_reader.readSignedBits(33), CppRuntimeException);
137
138
    // return 0 for 0 bits
139
1
    ASSERT_EQ(0, m_reader.readSignedBits(0));
140
1
}
141
142
TEST_F(BitStreamReaderTest, readSignedBits64)
143
1
{
144
    // check invalid bit length acceptance
145
1
    ASSERT_THROW(m_reader.readSignedBits64(255), CppRuntimeException);
146
1
    ASSERT_THROW(m_reader.readSignedBits64(65), CppRuntimeException);
147
148
    // return 0 for 0 bits
149
1
    ASSERT_EQ(0, m_reader.readSignedBits64(0));
150
1
}
151
152
TEST_F(BitStreamReaderTest, readVarSize)
153
1
{
154
1
    {
155
        // overflow, 2^32 - 1 is too much ({ 0x83, 0xFF, 0xFF, 0xFF, 0xFF } is the maximum)
156
1
        const std::array<uint8_t, 5> buffer = {0x87, 0xFF, 0xFF, 0xFF, 0xFF};
157
1
        zserio::BitStreamReader reader(buffer.data(), buffer.size());
158
1
        ASSERT_THROW(reader.readVarSize(), CppRuntimeException);
159
1
    }
160
161
1
    {
162
        // overflow, 2^36 - 1 is too much ({ 0x83, 0xFF, 0xFF, 0xFF, 0xFF } is the maximum)
163
1
        const std::array<uint8_t, 5> buffer = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
164
1
        zserio::BitStreamReader reader(buffer.data(), buffer.size());
165
1
        ASSERT_THROW(reader.readVarSize(), CppRuntimeException);
166
1
    }
167
1
}
168
169
TEST_F(BitStreamReaderTest, getBitPosition)
170
1
{
171
1
    ASSERT_EQ(0, m_reader.getBitPosition());
172
1
    m_reader.readBits(10);
173
1
    ASSERT_EQ(10, m_reader.getBitPosition());
174
1
}
175
176
TEST_F(BitStreamReaderTest, getBufferBitSize)
177
1
{
178
1
    ASSERT_EQ(m_byteBuffer.size() * 8, m_reader.getBufferBitSize());
179
1
}
180
181
} // namespace zserio