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