Zserio C++ runtime library  1.0.0
Built for Zserio 2.13.0
BitSizeOfCalculator.cpp
Go to the documentation of this file.
1 #include <limits>
2 #include <array>
3 
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 {
101  size_t byteSize = 1;
102  for (uint64_t maxValue : maxValues)
103  {
104  if (value <= maxValue)
105  break;
106  byteSize++;
107  }
108 
109  if (byteSize > maxValues.size())
110  {
111  throw CppRuntimeException("BitSizeOfCalculator: Value '") << value <<
112  "' is out of range for " << varIntName << "!";
113  }
114 
115  return byteSize * 8;
116 }
117 
118 template <typename T>
119 static uint64_t convertToAbsValue(T value)
120 {
121  return static_cast<uint64_t>((value < 0) ? -value : value);
122 }
123 
124 size_t bitSizeOfVarInt16(int16_t value)
125 {
126  return bitSizeOfVarIntImpl(convertToAbsValue(value), VARIN16_MAX_VALUES, "varint16");
127 }
128 
129 size_t bitSizeOfVarInt32(int32_t value)
130 {
131  return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT32_MAX_VALUES, "varint32");
132 }
133 
134 size_t bitSizeOfVarInt64(int64_t value)
135 {
136  return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT64_MAX_VALUES, "varint64");
137 }
138 
139 size_t bitSizeOfVarUInt16(uint16_t value)
140 {
141  return bitSizeOfVarIntImpl(value, VARUINT16_MAX_VALUES, "varuint16");
142 }
143 
144 size_t bitSizeOfVarUInt32(uint32_t value)
145 {
146  return bitSizeOfVarIntImpl(value, VARUINT32_MAX_VALUES, "varuint32");
147 }
148 
149 size_t bitSizeOfVarUInt64(uint64_t value)
150 {
151  return bitSizeOfVarIntImpl(value, VARUINT64_MAX_VALUES, "varuint64");
152 }
153 
154 size_t bitSizeOfVarInt(int64_t value)
155 {
156  if (value == INT64_MIN)
157  return 8; // INT64_MIN is stored as -0
158 
159  return bitSizeOfVarIntImpl(convertToAbsValue(value), VARINT_MAX_VALUES, "varint");
160 }
161 
162 size_t bitSizeOfVarUInt(uint64_t value)
163 {
164  return bitSizeOfVarIntImpl(value, VARUINT_MAX_VALUES, "varuint");
165 }
166 
167 size_t bitSizeOfVarSize(uint32_t value)
168 {
169  return bitSizeOfVarIntImpl(value, VARSIZE_MAX_VALUES, "varsize");
170 }
171 
173 {
174  const size_t bytesSize = bytesValue.size();
175 
176  // the bytes consists of varsize for size followed by the bytes
177  return bitSizeOfVarSize(convertSizeToUInt32(bytesSize)) + bytesSize * 8;
178 }
179 
180 size_t bitSizeOfString(StringView stringValue)
181 {
182  const size_t stringSize = stringValue.size();
183 
184  // the string consists of varsize for size followed by the UTF-8 encoded string
185  return bitSizeOfVarSize(convertSizeToUInt32(stringSize)) + stringSize * 8;
186 }
187 
188 } // namespace zserio
constexpr size_type size() const noexcept
Definition: StringView.h:237
size_t bitSizeOfVarUInt64(uint64_t value)
size_t bitSizeOfBytes(Span< const uint8_t > bytesValue)
size_t bitSizeOfVarSize(uint32_t value)
size_t bitSizeOfVarInt64(int64_t value)
size_t bitSizeOfVarInt16(int16_t value)
uint32_t convertSizeToUInt32(size_t value)
size_t bitSizeOfVarUInt16(uint16_t value)
constexpr size_type size() const noexcept
Definition: Span.h:276
size_t bitSizeOfVarUInt32(uint32_t value)
size_t bitSizeOfVarUInt(uint64_t value)
size_t bitSizeOfVarInt(int64_t value)
size_t bitSizeOfString(StringView stringValue)
size_t bitSizeOfVarInt32(int32_t value)