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 |