Coverage Report

Created: 2023-12-13 14:58

src/zserio/BitSizeOfCalculator.cpp
Line
Count
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
static size_t bitSizeOfVarIntImpl(uint64_t value, const std::array<uint64_t, SIZE>& maxValues,
99
        const char* varIntName)
100
32.7k
{
101
32.7k
    size_t byteSize = 1;
102
32.7k
    for (uint64_t maxValue : maxValues)
103
112k
    {
104
112k
        if (value <= maxValue)
105
32.7k
            break;
106
79.8k
        byteSize++;
107
79.8k
    }
108
109
32.7k
    if (byteSize > maxValues.size())
110
14
    {
111
14
        throw CppRuntimeException("BitSizeOfCalculator: Value '") << value <<
112
14
                "' is out of range for " << varIntName << "!";
113
14
    }
114
115
32.7k
    return byteSize * 8;
116
32.7k
}
117
118
template <typename T>
119
static uint64_t convertToAbsValue(T value)
120
13.6k
{
121
13.6k
    return static_cast<uint64_t>((value < 0) ? 
-value4.62k
:
value9.05k
);
122
13.6k
}
123
124
size_t bitSizeOfVarInt16(int16_t value)
125
492
{
126
492
    return bitSizeOfVarIntImpl(convertToAbsValue(value), VARIN16_MAX_VALUES, "varint16");
127
492
}
128
129
size_t bitSizeOfVarInt32(int32_t value)
130
1.47k
{
131
1.47k
    return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT32_MAX_VALUES, "varint32");
132
1.47k
}
133
134
size_t bitSizeOfVarInt64(int64_t value)
135
4.98k
{
136
4.98k
    return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT64_MAX_VALUES, "varint64");
137
4.98k
}
138
139
size_t bitSizeOfVarUInt16(uint16_t value)
140
428
{
141
428
    return bitSizeOfVarIntImpl(value, VARUINT16_MAX_VALUES, "varuint16");
142
428
}
143
144
size_t bitSizeOfVarUInt32(uint32_t value)
145
1.09k
{
146
1.09k
    return bitSizeOfVarIntImpl(value, VARUINT32_MAX_VALUES, "varuint32");
147
1.09k
}
148
149
size_t bitSizeOfVarUInt64(uint64_t value)
150
6.08k
{
151
6.08k
    return bitSizeOfVarIntImpl(value, VARUINT64_MAX_VALUES, "varuint64");
152
6.08k
}
153
154
size_t bitSizeOfVarInt(int64_t value)
155
6.79k
{
156
6.79k
    if (value == INT64_MIN)
157
65
        return 8; // INT64_MIN is stored as -0
158
159
6.73k
    return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT_MAX_VALUES, "varint");
160
6.79k
}
161
162
size_t bitSizeOfVarUInt(uint64_t value)
163
3.49k
{
164
3.49k
    return bitSizeOfVarIntImpl(value, VARUINT_MAX_VALUES, "varuint");
165
3.49k
}
166
167
size_t bitSizeOfVarSize(uint32_t value)
168
8.01k
{
169
8.01k
    return bitSizeOfVarIntImpl(value, VARSIZE_MAX_VALUES, "varsize");
170
8.01k
}
171
172
size_t bitSizeOfBytes(Span<const uint8_t> bytesValue)
173
135
{
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
135
}
179
180
size_t bitSizeOfString(StringView stringValue)
181
231
{
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
231
}
187
188
} // namespace zserio