src/zserio/BitSizeOfCalculator.cpp
Line | Count | Source |
1 | | #include <array> |
2 | | #include <limits> |
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 | | (UINT64_C(1) << (6)) - 1, |
12 | | (UINT64_C(1) << (6 + 8)) - 1, |
13 | | }; |
14 | | |
15 | | static const std::array<uint64_t, 4> VARINT32_MAX_VALUES = { |
16 | | (UINT64_C(1) << (6)) - 1, |
17 | | (UINT64_C(1) << (6 + 7)) - 1, |
18 | | (UINT64_C(1) << (6 + 7 + 7)) - 1, |
19 | | (UINT64_C(1) << (6 + 7 + 7 + 8)) - 1, |
20 | | }; |
21 | | |
22 | | static const std::array<uint64_t, 8> VARINT64_MAX_VALUES = { |
23 | | (UINT64_C(1) << (6)) - 1, |
24 | | (UINT64_C(1) << (6 + 7)) - 1, |
25 | | (UINT64_C(1) << (6 + 7 + 7)) - 1, |
26 | | (UINT64_C(1) << (6 + 7 + 7 + 7)) - 1, |
27 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7)) - 1, |
28 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7)) - 1, |
29 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7)) - 1, |
30 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1, |
31 | | }; |
32 | | |
33 | | static const std::array<uint64_t, 2> VARUINT16_MAX_VALUES = { |
34 | | (UINT64_C(1) << (7)) - 1, |
35 | | (UINT64_C(1) << (7 + 8)) - 1, |
36 | | }; |
37 | | |
38 | | static const std::array<uint64_t, 4> VARUINT32_MAX_VALUES = { |
39 | | (UINT64_C(1) << (7)) - 1, |
40 | | (UINT64_C(1) << (7 + 7)) - 1, |
41 | | (UINT64_C(1) << (7 + 7 + 7)) - 1, |
42 | | (UINT64_C(1) << (7 + 7 + 7 + 8)) - 1, |
43 | | }; |
44 | | |
45 | | static const std::array<uint64_t, 8> VARUINT64_MAX_VALUES = { |
46 | | (UINT64_C(1) << (7)) - 1, |
47 | | (UINT64_C(1) << (7 + 7)) - 1, |
48 | | (UINT64_C(1) << (7 + 7 + 7)) - 1, |
49 | | (UINT64_C(1) << (7 + 7 + 7 + 7)) - 1, |
50 | | (UINT64_C(1) << (7 + 7 + 7 + 7 + 7)) - 1, |
51 | | (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7)) - 1, |
52 | | (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7 + 7)) - 1, |
53 | | (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1, |
54 | | }; |
55 | | |
56 | | static const std::array<uint64_t, 9> VARINT_MAX_VALUES = { |
57 | | (UINT64_C(1) << (6)) - 1, |
58 | | (UINT64_C(1) << (6 + 7)) - 1, |
59 | | (UINT64_C(1) << (6 + 7 + 7)) - 1, |
60 | | (UINT64_C(1) << (6 + 7 + 7 + 7)) - 1, |
61 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7)) - 1, |
62 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7)) - 1, |
63 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7)) - 1, |
64 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7 + 7)) - 1, |
65 | | (UINT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1, |
66 | | }; |
67 | | |
68 | | static const std::array<uint64_t, 9> VARUINT_MAX_VALUES = { |
69 | | (UINT64_C(1) << (7)) - 1, |
70 | | (UINT64_C(1) << (7 + 7)) - 1, |
71 | | (UINT64_C(1) << (7 + 7 + 7)) - 1, |
72 | | (UINT64_C(1) << (7 + 7 + 7 + 7)) - 1, |
73 | | (UINT64_C(1) << (7 + 7 + 7 + 7 + 7)) - 1, |
74 | | (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7)) - 1, |
75 | | (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7 + 7)) - 1, |
76 | | (UINT64_C(1) << (7 + 7 + 7 + 7 + 7 + 7 + 7 + 7)) - 1, |
77 | | UINT64_MAX, |
78 | | }; |
79 | | |
80 | | static const std::array<uint64_t, 5> VARSIZE_MAX_VALUES = { |
81 | | (UINT64_C(1) << (7)) - 1, |
82 | | (UINT64_C(1) << (7 + 7)) - 1, |
83 | | (UINT64_C(1) << (7 + 7 + 7)) - 1, |
84 | | (UINT64_C(1) << (7 + 7 + 7 + 7)) - 1, |
85 | | (UINT64_C(1) << (2 + 7 + 7 + 7 + 8)) - 1, |
86 | | }; |
87 | | |
88 | | template <std::size_t SIZE> |
89 | | static size_t bitSizeOfVarIntImpl( |
90 | | uint64_t value, const std::array<uint64_t, SIZE>& maxValues, const char* varIntName) |
91 | 32.7k | { |
92 | 32.7k | size_t byteSize = 1; |
93 | 32.7k | for (uint64_t maxValue : maxValues) |
94 | 112k | { |
95 | 112k | if (value <= maxValue) |
96 | 32.7k | { |
97 | 32.7k | break; |
98 | 32.7k | } |
99 | 79.8k | byteSize++; |
100 | 79.8k | } |
101 | | |
102 | 32.7k | if (byteSize > maxValues.size()) |
103 | 14 | { |
104 | 14 | throw CppRuntimeException("BitSizeOfCalculator: Value '") |
105 | 14 | << value << "' is out of range for " << varIntName << "!"; |
106 | 14 | } |
107 | | |
108 | 32.7k | return byteSize * 8; |
109 | 32.7k | } |
110 | | |
111 | | template <typename T> |
112 | | static uint64_t convertToAbsValue(T value) |
113 | 13.6k | { |
114 | 13.6k | return static_cast<uint64_t>((value < 0) ? -value4.62k : value9.05k ); |
115 | 13.6k | } |
116 | | |
117 | | size_t bitSizeOfVarInt16(int16_t value) |
118 | 492 | { |
119 | 492 | return bitSizeOfVarIntImpl(convertToAbsValue(value), VARIN16_MAX_VALUES, "varint16"); |
120 | 492 | } |
121 | | |
122 | | size_t bitSizeOfVarInt32(int32_t value) |
123 | 1.47k | { |
124 | 1.47k | return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT32_MAX_VALUES, "varint32"); |
125 | 1.47k | } |
126 | | |
127 | | size_t bitSizeOfVarInt64(int64_t value) |
128 | 4.98k | { |
129 | 4.98k | return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT64_MAX_VALUES, "varint64"); |
130 | 4.98k | } |
131 | | |
132 | | size_t bitSizeOfVarUInt16(uint16_t value) |
133 | 428 | { |
134 | 428 | return bitSizeOfVarIntImpl(value, VARUINT16_MAX_VALUES, "varuint16"); |
135 | 428 | } |
136 | | |
137 | | size_t bitSizeOfVarUInt32(uint32_t value) |
138 | 1.09k | { |
139 | 1.09k | return bitSizeOfVarIntImpl(value, VARUINT32_MAX_VALUES, "varuint32"); |
140 | 1.09k | } |
141 | | |
142 | | size_t bitSizeOfVarUInt64(uint64_t value) |
143 | 6.08k | { |
144 | 6.08k | return bitSizeOfVarIntImpl(value, VARUINT64_MAX_VALUES, "varuint64"); |
145 | 6.08k | } |
146 | | |
147 | | size_t bitSizeOfVarInt(int64_t value) |
148 | 6.79k | { |
149 | 6.79k | if (value == INT64_MIN) |
150 | 65 | { |
151 | 65 | return 8; // INT64_MIN is stored as -0 |
152 | 65 | } |
153 | | |
154 | 6.73k | return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT_MAX_VALUES, "varint"); |
155 | 6.79k | } |
156 | | |
157 | | size_t bitSizeOfVarUInt(uint64_t value) |
158 | 3.49k | { |
159 | 3.49k | return bitSizeOfVarIntImpl(value, VARUINT_MAX_VALUES, "varuint"); |
160 | 3.49k | } |
161 | | |
162 | | size_t bitSizeOfVarSize(uint32_t value) |
163 | 8.01k | { |
164 | 8.01k | return bitSizeOfVarIntImpl(value, VARSIZE_MAX_VALUES, "varsize"); |
165 | 8.01k | } |
166 | | |
167 | | size_t bitSizeOfBytes(Span<const uint8_t> bytesValue) |
168 | 135 | { |
169 | 135 | const size_t bytesSize = bytesValue.size(); |
170 | | |
171 | | // the bytes consists of varsize for size followed by the bytes |
172 | 135 | return bitSizeOfVarSize(convertSizeToUInt32(bytesSize)) + bytesSize * 8; |
173 | 135 | } |
174 | | |
175 | | size_t bitSizeOfString(StringView stringValue) |
176 | 231 | { |
177 | 231 | const size_t stringSize = stringValue.size(); |
178 | | |
179 | | // the string consists of varsize for size followed by the UTF-8 encoded string |
180 | 231 | return bitSizeOfVarSize(convertSizeToUInt32(stringSize)) + stringSize * 8; |
181 | 231 | } |
182 | | |
183 | | } // namespace zserio |