GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/zserio/BitSizeOfCalculator.cpp Lines: 38 38 100.0 %
Date: 2023-12-13 14:51:09 Branches: 50 82 61.0 %

Line Branch Exec Source
1
#include <limits>
2
#include <array>
3
4
#include "zserio/BitSizeOfCalculator.h"
5
#include "zserio/CppRuntimeException.h"
6
7
namespace zserio
8
{
9
10
static const std::array<uint64_t, 2> VARIN16_MAX_VALUES =
11
{
12
    (UINT64_C(1) << (6)) - 1,
13
    (UINT64_C(1) << (6 + 8)) - 1,
14
};
15
16
static const std::array<uint64_t, 4> VARINT32_MAX_VALUES =
17
{
18
    (UINT64_C(1) << (6)) - 1,
19
    (UINT64_C(1) << (6 + 7)) - 1,
20
    (UINT64_C(1) << (6 + 7 + 7)) - 1,
21
    (UINT64_C(1) << (6 + 7 + 7 + 8)) - 1
22
};
23
24
static const std::array<uint64_t, 8> VARINT64_MAX_VALUES =
25
{
26
    (UINT64_C(1) << (6)) - 1,
27
    (UINT64_C(1) << (6 + 7)) - 1,
28
    (UINT64_C(1) << (6 + 7 + 7)) - 1,
29
    (UINT64_C(1) << (6 + 7 + 7 + 7)) - 1,
30
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7)) - 1,
31
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7)) - 1,
32
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7)) - 1,
33
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1
34
};
35
36
static const std::array<uint64_t, 2> VARUINT16_MAX_VALUES =
37
{
38
    (UINT64_C(1) << (7)) - 1,
39
    (UINT64_C(1) << (7 + 8)) - 1,
40
};
41
42
static const std::array<uint64_t, 4> VARUINT32_MAX_VALUES =
43
{
44
    (UINT64_C(1) << (7)) - 1,
45
    (UINT64_C(1) << (7 + 7)) - 1,
46
    (UINT64_C(1) << (7 + 7 + 7)) - 1,
47
    (UINT64_C(1) << (7 + 7 + 7 + 8)) - 1
48
};
49
50
static const std::array<uint64_t, 8> VARUINT64_MAX_VALUES =
51
{
52
    (UINT64_C(1) << (7)) - 1,
53
    (UINT64_C(1) << (7 + 7)) - 1,
54
    (UINT64_C(1) << (7 + 7 + 7)) - 1,
55
    (UINT64_C(1) << (7 + 7 + 7 + 7)) - 1,
56
    (UINT64_C(1) << (7 + 7 + 7 + 7 + 7)) - 1,
57
    (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7)) - 1,
58
    (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7 + 7)) - 1,
59
    (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1
60
};
61
62
static const std::array<uint64_t, 9> VARINT_MAX_VALUES =
63
{
64
    (UINT64_C(1) << (6)) - 1,
65
    (UINT64_C(1) << (6 + 7)) - 1,
66
    (UINT64_C(1) << (6 + 7 + 7)) - 1,
67
    (UINT64_C(1) << (6 + 7 + 7 + 7)) - 1,
68
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7)) - 1,
69
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7)) - 1,
70
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7)) - 1,
71
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7 + 7)) - 1,
72
    (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1
73
};
74
75
static const std::array<uint64_t, 9> VARUINT_MAX_VALUES =
76
{
77
    (UINT64_C(1) << (7)) - 1,
78
    (UINT64_C(1) << (7 + 7)) - 1,
79
    (UINT64_C(1) << (7 + 7 + 7)) - 1,
80
    (UINT64_C(1) << (7 + 7 + 7 + 7)) - 1,
81
    (UINT64_C(1) << (7 + 7 + 7 + 7 + 7)) - 1,
82
    (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7)) - 1,
83
    (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7 + 7)) - 1,
84
    (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7 + 7 + 7)) - 1,
85
    UINT64_MAX
86
};
87
88
static const std::array<uint64_t, 5> VARSIZE_MAX_VALUES =
89
{
90
    (UINT64_C(1) << (7)) - 1,
91
    (UINT64_C(1) << (7 + 7)) - 1,
92
    (UINT64_C(1) << (7 + 7 + 7)) - 1,
93
    (UINT64_C(1) << (7 + 7 + 7 + 7)) - 1,
94
    (UINT64_C(1) << (2 + 7 + 7 + 7 + 8)) - 1,
95
};
96
97
template <std::size_t SIZE>
98
32793
static size_t bitSizeOfVarIntImpl(uint64_t value, const std::array<uint64_t, SIZE>& maxValues,
99
        const char* varIntName)
100
{
101
32793
    size_t byteSize = 1;
102


112651
    for (uint64_t maxValue : maxValues)
103
    {
104


112637
        if (value <= maxValue)
105
32779
            break;
106
79858
        byteSize++;
107
    }
108
109


32793
    if (byteSize > maxValues.size())
110
    {
111







28
        throw CppRuntimeException("BitSizeOfCalculator: Value '") << value <<
112





28
                "' is out of range for " << varIntName << "!";
113
    }
114
115
32779
    return byteSize * 8;
116
}
117
118
template <typename T>
119
13681
static uint64_t convertToAbsValue(T value)
120
{
121
13681
    return static_cast<uint64_t>((value < 0) ? -value : value);
122
}
123
124
492
size_t bitSizeOfVarInt16(int16_t value)
125
{
126
492
    return bitSizeOfVarIntImpl(convertToAbsValue(value), VARIN16_MAX_VALUES, "varint16");
127
}
128
129
1476
size_t bitSizeOfVarInt32(int32_t value)
130
{
131
1476
    return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT32_MAX_VALUES, "varint32");
132
}
133
134
4980
size_t bitSizeOfVarInt64(int64_t value)
135
{
136
4980
    return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT64_MAX_VALUES, "varint64");
137
}
138
139
428
size_t bitSizeOfVarUInt16(uint16_t value)
140
{
141
428
    return bitSizeOfVarIntImpl(value, VARUINT16_MAX_VALUES, "varuint16");
142
}
143
144
1096
size_t bitSizeOfVarUInt32(uint32_t value)
145
{
146
1096
    return bitSizeOfVarIntImpl(value, VARUINT32_MAX_VALUES, "varuint32");
147
}
148
149
6080
size_t bitSizeOfVarUInt64(uint64_t value)
150
{
151
6080
    return bitSizeOfVarIntImpl(value, VARUINT64_MAX_VALUES, "varuint64");
152
}
153
154
6798
size_t bitSizeOfVarInt(int64_t value)
155
{
156
6798
    if (value == INT64_MIN)
157
65
        return 8; // INT64_MIN is stored as -0
158
159
6733
    return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT_MAX_VALUES, "varint");
160
}
161
162
3498
size_t bitSizeOfVarUInt(uint64_t value)
163
{
164
3498
    return bitSizeOfVarIntImpl(value, VARUINT_MAX_VALUES, "varuint");
165
}
166
167
8010
size_t bitSizeOfVarSize(uint32_t value)
168
{
169
8010
    return bitSizeOfVarIntImpl(value, VARSIZE_MAX_VALUES, "varsize");
170
}
171
172
135
size_t bitSizeOfBytes(Span<const uint8_t> bytesValue)
173
{
174
135
    const size_t bytesSize = bytesValue.size();
175
176
    // the bytes consists of varsize for size followed by the bytes
177
135
    return bitSizeOfVarSize(convertSizeToUInt32(bytesSize)) + bytesSize * 8;
178
}
179
180
231
size_t bitSizeOfString(StringView stringValue)
181
{
182
231
    const size_t stringSize = stringValue.size();
183
184
    // the string consists of varsize for size followed by the UTF-8 encoded string
185
231
    return bitSizeOfVarSize(convertSizeToUInt32(stringSize)) + stringSize * 8;
186
}
187
188
} // namespace zserio