Coverage Report

Created: 2024-07-18 11:41

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(8U + 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
        if (offset > 0)
103
64
        {
104
64
            ASSERT_EQ(0, reader.readBits64(offset));
105
64
        }
106
107
        // read magic number
108
130
        ASSERT_EQ(testValue, reader.readBits(8)) << "Offset: " << offset;
109
110
        // check eof
111
130
        ASSERT_THROW(reader.readBits(1), CppRuntimeException) << "Offset: " << offset;
112
65
    }
113
1
}
114
115
TEST_F(BitStreamReaderTest, readBits)
116
1
{
117
    // check invalid bitlength acceptance
118
1
    ASSERT_THROW(m_reader.readBits(255), CppRuntimeException);
119
1
    ASSERT_THROW(m_reader.readBits(0), CppRuntimeException);
120
1
    ASSERT_THROW(m_reader.readBits(33), CppRuntimeException);
121
1
}
122
123
TEST_F(BitStreamReaderTest, readBits64)
124
1
{
125
    // check invalid bit length acceptance
126
1
    ASSERT_THROW(m_reader.readBits64(255), CppRuntimeException);
127
1
    ASSERT_THROW(m_reader.readBits64(0), CppRuntimeException);
128
1
    ASSERT_THROW(m_reader.readBits64(65), CppRuntimeException);
129
1
}
130
131
TEST_F(BitStreamReaderTest, readSignedBits)
132
1
{
133
    // check invalid bit length acceptance
134
1
    ASSERT_THROW(m_reader.readSignedBits(255), CppRuntimeException);
135
1
    ASSERT_THROW(m_reader.readSignedBits(0), CppRuntimeException);
136
1
    ASSERT_THROW(m_reader.readSignedBits(33), CppRuntimeException);
137
1
}
138
139
TEST_F(BitStreamReaderTest, readSignedBits64)
140
1
{
141
    // check invalid bit length acceptance
142
1
    ASSERT_THROW(m_reader.readSignedBits64(255), CppRuntimeException);
143
1
    ASSERT_THROW(m_reader.readSignedBits64(0), CppRuntimeException);
144
1
    ASSERT_THROW(m_reader.readSignedBits64(65), CppRuntimeException);
145
1
}
146
147
TEST_F(BitStreamReaderTest, readVarSize)
148
1
{
149
1
    {
150
        // overflow, 2^32 - 1 is too much ({ 0x83, 0xFF, 0xFF, 0xFF, 0xFF } is the maximum)
151
1
        const std::array<uint8_t, 5> buffer = {0x87, 0xFF, 0xFF, 0xFF, 0xFF};
152
1
        zserio::BitStreamReader reader(buffer.data(), buffer.size());
153
1
        ASSERT_THROW(reader.readVarSize(), CppRuntimeException);
154
1
    }
155
156
1
    {
157
        // overflow, 2^36 - 1 is too much ({ 0x83, 0xFF, 0xFF, 0xFF, 0xFF } is the maximum)
158
1
        const std::array<uint8_t, 5> buffer = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
159
1
        zserio::BitStreamReader reader(buffer.data(), buffer.size());
160
1
        ASSERT_THROW(reader.readVarSize(), CppRuntimeException);
161
1
    }
162
1
}
163
164
TEST_F(BitStreamReaderTest, getBitPosition)
165
1
{
166
1
    ASSERT_EQ(0, m_reader.getBitPosition());
167
1
    m_reader.readBits(10);
168
1
    ASSERT_EQ(10, m_reader.getBitPosition());
169
1
}
170
171
TEST_F(BitStreamReaderTest, getBufferBitSize)
172
1
{
173
1
    ASSERT_EQ(m_byteBuffer.size() * 8, m_reader.getBufferBitSize());
174
1
}
175
176
} // namespace zserio