test/zserio/BitStreamTest.cpp
Line | Count | Source |
1 | | #include <array> |
2 | | #include <cstring> |
3 | | #include <functional> |
4 | | #include <string> |
5 | | |
6 | | #include "gtest/gtest.h" |
7 | | #include "zserio/BitStreamReader.h" |
8 | | #include "zserio/BitStreamWriter.h" |
9 | | #include "zserio/CppRuntimeException.h" |
10 | | #include "zserio/Types.h" |
11 | | #include "zserio/Vector.h" |
12 | | |
13 | | namespace zserio |
14 | | { |
15 | | |
16 | | class BitStreamTest : public ::testing::Test |
17 | | { |
18 | | public: |
19 | | BitStreamTest() : |
20 | | m_byteBuffer(), |
21 | | m_externalWriter(m_byteBuffer.data(), m_byteBuffer.size()), |
22 | | m_dummyWriter(nullptr, 0) |
23 | 23 | { |
24 | 23 | m_byteBuffer.fill(0); |
25 | 23 | } |
26 | | |
27 | | protected: |
28 | | template <typename T, size_t N, typename U> |
29 | | void testImpl(const std::array<T, N>& values, std::function<void(BitStreamWriter&, U)> writerFunc, |
30 | | std::function<T(BitStreamReader&)> readerFunc, uint8_t maxStartBitPos) |
31 | 16 | { |
32 | 16 | testBitStreamValues(values, m_externalWriter, writerFunc, readerFunc, maxStartBitPos); |
33 | 16 | testBitStreamValues(values, m_dummyWriter, writerFunc, readerFunc, maxStartBitPos); |
34 | 16 | } |
35 | | |
36 | | template <typename T, size_t N, typename U> |
37 | | void testBitStreamValues(const std::array<T, N>& values, BitStreamWriter& writer, |
38 | | std::function<void(BitStreamWriter&, U)> writerFunc, std::function<T(BitStreamReader&)> readerFunc, |
39 | | uint8_t maxStartBitPos) |
40 | 32 | { |
41 | 1.04k | for (uint8_t bitPos = 0; bitPos < maxStartBitPos; ++bitPos1.00k ) |
42 | 1.00k | { |
43 | 1.00k | if (bitPos > 0) |
44 | 976 | { |
45 | 976 | writer.writeBits64(0, bitPos); |
46 | 976 | } |
47 | 19.1k | for (size_t i = 0; i < N; ++i18.1k ) |
48 | 18.1k | { |
49 | 18.1k | writerFunc(writer, values.at(i)); |
50 | 18.1k | } |
51 | | |
52 | 1.00k | if (!writer.hasWriteBuffer()) |
53 | 504 | { |
54 | 504 | continue; |
55 | 504 | } |
56 | | |
57 | 504 | BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag()); |
58 | 504 | if (bitPos > 0) |
59 | 488 | { |
60 | 488 | reader.readBits64(bitPos); |
61 | 488 | } |
62 | 9.57k | for (size_t i = 0; i < N; ++i9.07k ) |
63 | 9.07k | { |
64 | 18.1k | ASSERT_EQ(readerFunc(reader), values.at(i)) << "[bitPos=" << bitPos << "]"; |
65 | 9.07k | } |
66 | | |
67 | 504 | writer.setBitPosition(0); |
68 | 504 | m_byteBuffer.fill(0); |
69 | 504 | } |
70 | 32 | } |
71 | | |
72 | | void testReadBits(BitStreamWriter& writer) |
73 | 2 | { |
74 | 2 | writer.writeBits(1, 1); |
75 | 2 | writer.writeBits(2, 2); |
76 | 2 | writer.writeBits(42, 12); |
77 | 2 | writer.writeBits(15999999, 24); |
78 | 2 | writer.writeBits(7, 3); |
79 | | |
80 | 2 | if (!writer.hasWriteBuffer()) |
81 | 1 | { |
82 | 1 | return; |
83 | 1 | } |
84 | | |
85 | 1 | BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag()); |
86 | 1 | ASSERT_EQ(1, reader.readBits(1)); |
87 | 1 | ASSERT_EQ(2, reader.readBits(2)); |
88 | 1 | ASSERT_EQ(42, reader.readBits(12)); |
89 | 1 | ASSERT_EQ(15999999, reader.readBits(24)); |
90 | 1 | ASSERT_EQ(7, reader.readBits(3)); |
91 | 1 | } |
92 | | |
93 | | void testReadBits64(BitStreamWriter& writer) |
94 | 2 | { |
95 | 2 | writer.writeBits(1, 1); |
96 | 2 | writer.writeBits64(UINT64_C(42424242424242), 48); |
97 | 2 | writer.writeBits64(UINT64_C(0xFFFFFFFFFFFFFFFE), 64); |
98 | | |
99 | 2 | if (!writer.hasWriteBuffer()) |
100 | 1 | { |
101 | 1 | return; |
102 | 1 | } |
103 | | |
104 | 1 | BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag()); |
105 | 1 | ASSERT_EQ(1, reader.readBits(1)); |
106 | 1 | ASSERT_EQ(UINT64_C(42424242424242), reader.readBits64(48)); |
107 | 1 | ASSERT_EQ(UINT64_C(0xFFFFFFFFFFFFFFFE), reader.readBits64(64)); |
108 | 1 | } |
109 | | |
110 | | void testReadSignedBits(BitStreamWriter& writer) |
111 | 2 | { |
112 | 2 | writer.writeSignedBits(-1, 5); |
113 | 2 | writer.writeSignedBits(3, 12); |
114 | 2 | writer.writeSignedBits(-142, 9); |
115 | | |
116 | 2 | if (!writer.hasWriteBuffer()) |
117 | 1 | { |
118 | 1 | return; |
119 | 1 | } |
120 | | |
121 | 1 | BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag()); |
122 | 1 | ASSERT_EQ(-1, reader.readSignedBits(5)); |
123 | 1 | ASSERT_EQ(3, reader.readSignedBits(12)); |
124 | 1 | ASSERT_EQ(-142, reader.readSignedBits(9)); |
125 | 1 | } |
126 | | |
127 | | void testReadSignedBits64(BitStreamWriter& writer) |
128 | 2 | { |
129 | 2 | writer.writeSignedBits64(INT64_C(1), 4); |
130 | 2 | writer.writeSignedBits64(INT64_C(-1), 48); |
131 | 2 | writer.writeSignedBits64(INT64_C(-42424242), 61); |
132 | 2 | writer.writeSignedBits64(INT64_C(-820816), 32); |
133 | | |
134 | 2 | if (!writer.hasWriteBuffer()) |
135 | 1 | { |
136 | 1 | return; |
137 | 1 | } |
138 | | |
139 | 1 | BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag()); |
140 | 1 | ASSERT_EQ(INT64_C(1), reader.readSignedBits(4)); |
141 | 1 | ASSERT_EQ(INT64_C(-1), reader.readSignedBits64(48)); |
142 | 1 | ASSERT_EQ(INT64_C(-42424242), reader.readSignedBits64(61)); |
143 | 1 | ASSERT_EQ(INT64_C(-820816), reader.readSignedBits64(32)); |
144 | 1 | } |
145 | | |
146 | | void testAlignedBytes(BitStreamWriter& writer) |
147 | 2 | { |
148 | | // reads aligned data directly from buffer, bit cache should remain empty |
149 | 2 | writer.writeBits(UINT8_C(0xCA), 8); |
150 | 2 | writer.writeBits(UINT16_C(0xCAFE), 16); |
151 | 2 | writer.writeBits(UINT32_C(0xCAFEC0), 24); |
152 | 2 | writer.writeBits(UINT32_C(0xCAFEC0DE), 32); |
153 | 2 | writer.writeBits64(UINT64_C(0xCAFEC0DEDE), 40); |
154 | 2 | writer.writeBits64(UINT64_C(0xCAFEC0DEDEAD), 48); |
155 | 2 | writer.writeBits64(UINT64_C(0xCAFEC0DEDEADFA), 56); |
156 | 2 | writer.writeBits64(UINT64_C(0xCAFEC0DEDEADFACE), 64); |
157 | | |
158 | 2 | if (!writer.hasWriteBuffer()) |
159 | 1 | { |
160 | 1 | return; |
161 | 1 | } |
162 | | |
163 | 1 | BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag()); |
164 | 1 | ASSERT_EQ(UINT8_C(0xCA), reader.readBits(8)); |
165 | 1 | ASSERT_EQ(UINT16_C(0xCAFE), reader.readBits(16)); |
166 | 1 | ASSERT_EQ(UINT32_C(0xCAFEC0), reader.readBits(24)); |
167 | 1 | ASSERT_EQ(UINT32_C(0xCAFEC0DE), reader.readBits(32)); |
168 | 1 | ASSERT_EQ(UINT64_C(0xCAFEC0DEDE), reader.readBits64(40)); |
169 | 1 | ASSERT_EQ(UINT64_C(0xCAFEC0DEDEAD), reader.readBits64(48)); |
170 | 1 | ASSERT_EQ(UINT64_C(0xCAFEC0DEDEADFA), reader.readBits64(56)); |
171 | 1 | ASSERT_EQ(UINT64_C(0xCAFEC0DEDEADFACE), reader.readBits64(64)); |
172 | 1 | } |
173 | | |
174 | | void testSetBitPosition(BitStreamWriter& writer) |
175 | 2 | { |
176 | 2 | ASSERT_EQ(0, writer.getBitPosition()); |
177 | 2 | writer.writeBits(1, 1); |
178 | 2 | ASSERT_EQ(1, writer.getBitPosition()); |
179 | 2 | writer.alignTo(4); |
180 | 2 | ASSERT_EQ(4, writer.getBitPosition()); |
181 | 2 | writer.writeBits(5, 5); |
182 | 2 | ASSERT_EQ(9, writer.getBitPosition()); |
183 | 2 | if (writer.hasWriteBuffer()) |
184 | 1 | { |
185 | 1 | ASSERT_THROW(writer.setBitPosition(m_byteBuffer.size() * 8 + 1), CppRuntimeException); |
186 | 1 | } |
187 | 1 | else |
188 | 1 | { |
189 | | // dummy buffer |
190 | 1 | writer.setBitPosition(m_byteBuffer.size() * 8 + 1); |
191 | 1 | ASSERT_EQ(m_byteBuffer.size() * 8 + 1, writer.getBitPosition()); |
192 | 1 | } |
193 | 2 | writer.setBitPosition(4); |
194 | 2 | ASSERT_EQ(4, writer.getBitPosition()); |
195 | 2 | writer.writeBits(3, 3); |
196 | 2 | ASSERT_EQ(7, writer.getBitPosition()); |
197 | | |
198 | 2 | if (!writer.hasWriteBuffer()) |
199 | 1 | { |
200 | 1 | return; |
201 | 1 | } |
202 | | |
203 | 1 | BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag()); |
204 | 1 | ASSERT_EQ(0, reader.getBitPosition()); |
205 | 1 | ASSERT_EQ(1, reader.readBits(1)); |
206 | 1 | ASSERT_EQ(1, reader.getBitPosition()); |
207 | 1 | reader.alignTo(4); |
208 | 1 | ASSERT_EQ(4, reader.getBitPosition()); |
209 | 1 | ASSERT_EQ(3, reader.readBits(3)); |
210 | 1 | ASSERT_EQ(7, reader.getBitPosition()); |
211 | 1 | ASSERT_THROW(reader.setBitPosition(writer.getBitPosition() + 1), CppRuntimeException); |
212 | | |
213 | 1 | reader.setBitPosition(4); |
214 | 1 | ASSERT_EQ(4, reader.getBitPosition()); |
215 | 1 | ASSERT_EQ(3, reader.readBits(3)); |
216 | 1 | ASSERT_EQ(7, reader.getBitPosition()); |
217 | 1 | } |
218 | | |
219 | | void testAlignTo(BitStreamWriter& writer) |
220 | 2 | { |
221 | 2 | writer.writeBits(1, 1); |
222 | 2 | writer.alignTo(4); |
223 | 2 | ASSERT_EQ(4, writer.getBitPosition()); |
224 | 2 | writer.writeBits(1, 1); |
225 | 2 | writer.alignTo(4); |
226 | 2 | ASSERT_EQ(8, writer.getBitPosition()); |
227 | 2 | writer.writeBits(37, 11); |
228 | 2 | writer.alignTo(8); |
229 | 2 | ASSERT_EQ(24, writer.getBitPosition()); |
230 | 2 | writer.writeBits(1, 1); |
231 | 2 | writer.alignTo(16); |
232 | 2 | ASSERT_EQ(32, writer.getBitPosition()); |
233 | 2 | writer.writeBits(13, 13); |
234 | 2 | writer.alignTo(32); |
235 | 2 | ASSERT_EQ(64, writer.getBitPosition()); |
236 | 2 | writer.writeBits(42, 15); |
237 | 2 | writer.alignTo(64); |
238 | 2 | ASSERT_EQ(128, writer.getBitPosition()); |
239 | 2 | writer.writeBits(99, 9); |
240 | 2 | ASSERT_EQ(137, writer.getBitPosition()); |
241 | | |
242 | 2 | if (!writer.hasWriteBuffer()) |
243 | 1 | { |
244 | 1 | return; |
245 | 1 | } |
246 | | |
247 | 1 | BitStreamReader reader(writer.getWriteBuffer(), writer.getBitPosition(), BitsTag()); |
248 | 1 | ASSERT_EQ(1, reader.readBits(1)); |
249 | 1 | reader.alignTo(4); |
250 | 1 | ASSERT_EQ(1, reader.readBits(1)); |
251 | 1 | reader.alignTo(4); |
252 | 1 | ASSERT_EQ(37, reader.readBits(11)); |
253 | 1 | reader.alignTo(8); |
254 | 1 | ASSERT_EQ(1, reader.readBits(1)); |
255 | 1 | reader.alignTo(16); |
256 | 1 | ASSERT_EQ(13, reader.readBits(13)); |
257 | 1 | reader.alignTo(32); |
258 | 1 | ASSERT_EQ(42, reader.readBits(15)); |
259 | 1 | reader.alignTo(64); |
260 | 1 | ASSERT_EQ(99, reader.readBits(9)); |
261 | 1 | ASSERT_EQ(137, reader.getBitPosition()); |
262 | 1 | } |
263 | | |
264 | | std::array<uint8_t, 256> m_byteBuffer; |
265 | | BitStreamWriter m_externalWriter; |
266 | | BitStreamWriter m_dummyWriter; |
267 | | }; |
268 | | |
269 | | TEST_F(BitStreamTest, readBits) |
270 | 1 | { |
271 | 1 | testReadBits(m_externalWriter); |
272 | 1 | testReadBits(m_dummyWriter); |
273 | 1 | } |
274 | | |
275 | | TEST_F(BitStreamTest, readBits64) |
276 | 1 | { |
277 | 1 | testReadBits64(m_externalWriter); |
278 | 1 | testReadBits64(m_dummyWriter); |
279 | 1 | } |
280 | | |
281 | | TEST_F(BitStreamTest, readSignedBits) |
282 | 1 | { |
283 | 1 | testReadSignedBits(m_externalWriter); |
284 | 1 | testReadSignedBits(m_dummyWriter); |
285 | 1 | } |
286 | | |
287 | | TEST_F(BitStreamTest, readSignedBits64) |
288 | 1 | { |
289 | 1 | testReadSignedBits64(m_externalWriter); |
290 | 1 | testReadSignedBits64(m_dummyWriter); |
291 | 1 | } |
292 | | |
293 | | TEST_F(BitStreamTest, alignedBytes) |
294 | 1 | { |
295 | 1 | testAlignedBytes(m_externalWriter); |
296 | 1 | testAlignedBytes(m_dummyWriter); |
297 | 1 | } |
298 | | |
299 | | TEST_F(BitStreamTest, readVarInt64) |
300 | 1 | { |
301 | 1 | const std::array<int64_t, 33> values = { |
302 | 1 | INT64_C(0), |
303 | 1 | INT64_C(-32), |
304 | 1 | INT64_C(32), |
305 | 1 | INT64_C(-4096), |
306 | 1 | INT64_C(4096), |
307 | 1 | INT64_C(-524288), |
308 | 1 | INT64_C(524288), |
309 | 1 | INT64_C(-67108864), |
310 | 1 | INT64_C(67108864), |
311 | 1 | INT64_C(-8589934592), |
312 | 1 | INT64_C(8589934592), |
313 | 1 | INT64_C(-1099511627776), |
314 | 1 | INT64_C(1099511627776), |
315 | 1 | INT64_C(-140737488355328), |
316 | 1 | INT64_C(140737488355328), |
317 | 1 | INT64_C(-18014398509481984), |
318 | 1 | INT64_C(18014398509481984), |
319 | | |
320 | 1 | (INT64_C(1) << (0)), |
321 | 1 | (INT64_C(1) << (6)) - 1, |
322 | | |
323 | 1 | (INT64_C(1) << (6)), |
324 | 1 | (INT64_C(1) << (6 + 7)) - 1, |
325 | | |
326 | 1 | (INT64_C(1) << (6 + 7)), |
327 | 1 | (INT64_C(1) << (6 + 7 + 7)) - 1, |
328 | | |
329 | 1 | (INT64_C(1) << (6 + 7 + 7)), |
330 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7)) - 1, |
331 | | |
332 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7)), |
333 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7 + 7)) - 1, |
334 | | |
335 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7 + 7)), |
336 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7)) - 1, |
337 | | |
338 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7)), |
339 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7)) - 1, |
340 | | |
341 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7)), |
342 | 1 | (INT64_C(1) << (6 + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1, |
343 | 1 | }; |
344 | | |
345 | 1 | std::function<void(BitStreamWriter&, int64_t)> writerFunc = &BitStreamWriter::writeVarInt64; |
346 | 1 | std::function<int64_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarInt64; |
347 | | |
348 | 1 | testImpl(values, writerFunc, readerFunc, 63); |
349 | 1 | } |
350 | | |
351 | | TEST_F(BitStreamTest, readVarInt32) |
352 | 1 | { |
353 | 1 | const std::array<int32_t, 17> values = { |
354 | 1 | static_cast<int32_t>(0), |
355 | 1 | static_cast<int32_t>(-32), |
356 | 1 | static_cast<int32_t>(32), |
357 | 1 | static_cast<int32_t>(-4096), |
358 | 1 | static_cast<int32_t>(4096), |
359 | 1 | static_cast<int32_t>(-524288), |
360 | 1 | static_cast<int32_t>(524288), |
361 | 1 | static_cast<int32_t>(-67108864), |
362 | 1 | static_cast<int32_t>(67108864), |
363 | | |
364 | 1 | static_cast<int32_t>(1U << (0U)), |
365 | 1 | static_cast<int32_t>(1U << (6U)) - 1, |
366 | | |
367 | 1 | static_cast<int32_t>(1U << (6U)), |
368 | 1 | static_cast<int32_t>(1U << (6U + 7)) - 1, |
369 | | |
370 | 1 | static_cast<int32_t>(1U << (6U + 7)), |
371 | 1 | static_cast<int32_t>(1U << (6U + 7 + 7)) - 1, |
372 | | |
373 | 1 | static_cast<int32_t>(1U << (6U + 7 + 7)), |
374 | 1 | static_cast<int32_t>(1U << (6U + 7 + 7 + 8)) - 1, |
375 | 1 | }; |
376 | | |
377 | 1 | std::function<void(BitStreamWriter&, int32_t)> writerFunc = &BitStreamWriter::writeVarInt32; |
378 | 1 | std::function<int32_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarInt32; |
379 | | |
380 | 1 | testImpl(values, writerFunc, readerFunc, 31); |
381 | 1 | } |
382 | | |
383 | | TEST_F(BitStreamTest, readVarInt16) |
384 | 1 | { |
385 | 1 | const std::array<int16_t, 9> values = { |
386 | 1 | static_cast<int16_t>(0), |
387 | 1 | static_cast<int16_t>(-32), |
388 | 1 | static_cast<int16_t>(32), |
389 | 1 | static_cast<int16_t>(-4096), |
390 | 1 | static_cast<int16_t>(4096), |
391 | | |
392 | 1 | static_cast<int16_t>(1U << (0U)), |
393 | 1 | static_cast<int16_t>(1U << (6U)) - 1, |
394 | | |
395 | 1 | static_cast<int16_t>(1U << (6U)), |
396 | 1 | static_cast<int16_t>(1U << (6 + 8U)) - 1, |
397 | 1 | }; |
398 | | |
399 | 1 | std::function<void(BitStreamWriter&, int16_t)> writerFunc = &BitStreamWriter::writeVarInt16; |
400 | 1 | std::function<int16_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarInt16; |
401 | | |
402 | 1 | testImpl(values, writerFunc, readerFunc, 15); |
403 | 1 | } |
404 | | |
405 | | TEST_F(BitStreamTest, readVarUInt64) |
406 | 1 | { |
407 | 1 | const std::array<uint64_t, 19> values = { |
408 | 1 | 0, |
409 | 1 | 262144, |
410 | 1 | 524288, |
411 | | |
412 | 1 | (UINT64_C(1) << (0U)), |
413 | 1 | (UINT64_C(1) << (7U)) - 1, |
414 | | |
415 | 1 | (UINT64_C(1) << (7U)), |
416 | 1 | (UINT64_C(1) << (7U + 7)) - 1, |
417 | | |
418 | 1 | (UINT64_C(1) << (7U + 7)), |
419 | 1 | (UINT64_C(1) << (7U + 7 + 7)) - 1, |
420 | | |
421 | 1 | (UINT64_C(1) << (7U + 7 + 7)), |
422 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7)) - 1, |
423 | | |
424 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7)), |
425 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7 + 7)) - 1, |
426 | | |
427 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7 + 7)), |
428 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7)) - 1, |
429 | | |
430 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7)), |
431 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7 + 7)) - 1, |
432 | | |
433 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7 + 7)), |
434 | 1 | (UINT64_C(1) << (7U + 7 + 7 + 7 + 7 + 7 + 7 + 8)) - 1, |
435 | 1 | }; |
436 | | |
437 | 1 | std::function<void(BitStreamWriter&, uint64_t)> writerFunc = &BitStreamWriter::writeVarUInt64; |
438 | 1 | std::function<uint64_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarUInt64; |
439 | | |
440 | 1 | testImpl(values, writerFunc, readerFunc, 63); |
441 | 1 | } |
442 | | |
443 | | TEST_F(BitStreamTest, readVarUInt32) |
444 | 1 | { |
445 | 1 | const std::array<uint32_t, 11> values = { |
446 | 1 | 0, |
447 | 1 | 65536, |
448 | 1 | 131072, |
449 | | |
450 | 1 | (1U << (0U)), |
451 | 1 | (1U << (7U)) - 1, |
452 | | |
453 | 1 | (1U << (7U)), |
454 | 1 | (1U << (7U + 7)) - 1, |
455 | | |
456 | 1 | (1U << (7U + 7)), |
457 | 1 | (1U << (7U + 7 + 7)) - 1, |
458 | | |
459 | 1 | (1U << (7U + 7 + 7)), |
460 | 1 | (1U << (7U + 7 + 7 + 8)) - 1, |
461 | 1 | }; |
462 | | |
463 | 1 | std::function<void(BitStreamWriter&, uint32_t)> writerFunc = &BitStreamWriter::writeVarUInt32; |
464 | 1 | std::function<uint32_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarUInt32; |
465 | | |
466 | 1 | testImpl(values, writerFunc, readerFunc, 31); |
467 | 1 | } |
468 | | |
469 | | TEST_F(BitStreamTest, readVarUInt16) |
470 | 1 | { |
471 | 1 | const std::array<uint16_t, 7> values = { |
472 | 1 | 0, |
473 | 1 | 8192, |
474 | 1 | 16384, |
475 | | |
476 | 1 | (1U << (0U)), |
477 | 1 | (1U << (6U)) - 1, |
478 | | |
479 | 1 | (1U << (6U)), |
480 | 1 | (1U << (6U + 8)) - 1, |
481 | 1 | }; |
482 | | |
483 | 1 | std::function<void(BitStreamWriter&, uint16_t)> writerFunc = &BitStreamWriter::writeVarUInt16; |
484 | 1 | std::function<uint16_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarUInt16; |
485 | | |
486 | 1 | testImpl(values, writerFunc, readerFunc, 15); |
487 | 1 | } |
488 | | |
489 | | TEST_F(BitStreamTest, readVarInt) |
490 | 1 | { |
491 | 1 | const std::array<int64_t, 38> values = { |
492 | | // 1 byte |
493 | 1 | 0, |
494 | 1 | -1, |
495 | 1 | 1, |
496 | 1 | -static_cast<int64_t>(UINT64_C(1) << 6U) + 1, |
497 | 1 | static_cast<int64_t>(UINT64_C(1) << 6U) - 1, |
498 | | // 2 bytes |
499 | 1 | -static_cast<int64_t>(UINT64_C(1) << 6U), |
500 | 1 | static_cast<int64_t>(UINT64_C(1) << 6U), |
501 | 1 | -static_cast<int64_t>(UINT64_C(1) << 13U) + 1, |
502 | 1 | static_cast<int64_t>(UINT64_C(1) << 13U) - 1, |
503 | | // 3 bytes |
504 | 1 | -static_cast<int64_t>(UINT64_C(1) << 13U), |
505 | 1 | static_cast<int64_t>(UINT64_C(1) << 13U), |
506 | 1 | -static_cast<int64_t>(UINT64_C(1) << 20U) + 1, |
507 | 1 | static_cast<int64_t>(UINT64_C(1) << 20U) - 1, |
508 | | // 4 bytes |
509 | 1 | -static_cast<int64_t>(UINT64_C(1) << 20U), |
510 | 1 | static_cast<int64_t>(UINT64_C(1) << 20U), |
511 | 1 | -static_cast<int64_t>(UINT64_C(1) << 27U) + 1, |
512 | 1 | static_cast<int64_t>(UINT64_C(1) << 27U) - 1, |
513 | | // 5 bytes |
514 | 1 | -static_cast<int64_t>(UINT64_C(1) << 27U), |
515 | 1 | static_cast<int64_t>(UINT64_C(1) << 27U), |
516 | 1 | -static_cast<int64_t>(UINT64_C(1) << 34U) + 1, |
517 | 1 | static_cast<int64_t>(UINT64_C(1) << 34U) - 1, |
518 | | // 6 bytes |
519 | 1 | -static_cast<int64_t>(UINT64_C(1) << 34U), |
520 | 1 | static_cast<int64_t>(UINT64_C(1) << 34U), |
521 | 1 | -static_cast<int64_t>(UINT64_C(1) << 41U) + 1, |
522 | 1 | static_cast<int64_t>(UINT64_C(1) << 41U) - 1, |
523 | | // 7 bytes |
524 | 1 | -static_cast<int64_t>(UINT64_C(1) << 41U), |
525 | 1 | static_cast<int64_t>(UINT64_C(1) << 41U), |
526 | 1 | -static_cast<int64_t>(UINT64_C(1) << 48U) + 1, |
527 | 1 | static_cast<int64_t>(UINT64_C(1) << 48U) - 1, |
528 | | // 8 bytes |
529 | 1 | -static_cast<int64_t>(UINT64_C(1) << 48U), |
530 | 1 | static_cast<int64_t>(UINT64_C(1) << 48U), |
531 | 1 | -static_cast<int64_t>(UINT64_C(1) << 55U) + 1, |
532 | 1 | static_cast<int64_t>(UINT64_C(1) << 55U) - 1, |
533 | | // 9 bytes |
534 | 1 | -static_cast<int64_t>(UINT64_C(1) << 55U), |
535 | 1 | static_cast<int64_t>(UINT64_C(1) << 55U), |
536 | 1 | INT64_MIN + 1, |
537 | 1 | INT64_MAX, |
538 | | |
539 | | // special case - stored as -0 (1 byte) |
540 | 1 | INT64_MIN, |
541 | 1 | }; |
542 | | |
543 | 1 | std::function<void(BitStreamWriter&, int64_t)> writerFunc = &BitStreamWriter::writeVarInt; |
544 | 1 | std::function<int64_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarInt; |
545 | | |
546 | 1 | testImpl(values, writerFunc, readerFunc, 63); |
547 | 1 | } |
548 | | |
549 | | TEST_F(BitStreamTest, readVarUInt) |
550 | 1 | { |
551 | 1 | const std::array<uint64_t, 19> values = { |
552 | | // 1 byte |
553 | 1 | 0, |
554 | 1 | 1, |
555 | 1 | (UINT64_C(1) << 7U) - 1, |
556 | | // 2 bytes |
557 | 1 | (UINT64_C(1) << 7U), |
558 | 1 | (UINT64_C(1) << 14U) - 1, |
559 | | // 3 bytes |
560 | 1 | (UINT64_C(1) << 14U), |
561 | 1 | (UINT64_C(1) << 21U) - 1, |
562 | | // 4 bytes |
563 | 1 | (UINT64_C(1) << 21U), |
564 | 1 | (UINT64_C(1) << 28U) - 1, |
565 | | // 5 bytes |
566 | 1 | (UINT64_C(1) << 28U), |
567 | 1 | (UINT64_C(1) << 35U) - 1, |
568 | | // 6 bytes |
569 | 1 | (UINT64_C(1) << 35U), |
570 | 1 | (UINT64_C(1) << 42U) - 1, |
571 | | // 7 bytes |
572 | 1 | (UINT64_C(1) << 42U), |
573 | 1 | (UINT64_C(1) << 49U) - 1, |
574 | | // 8 bytes |
575 | 1 | (UINT64_C(1) << 49U), |
576 | 1 | (UINT64_C(1) << 56U) - 1, |
577 | | // 9 bytes |
578 | 1 | (UINT64_C(1) << 56U), |
579 | 1 | UINT64_MAX, |
580 | 1 | }; |
581 | | |
582 | 1 | std::function<void(BitStreamWriter&, uint64_t)> writerFunc = &BitStreamWriter::writeVarUInt; |
583 | 1 | std::function<uint64_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarUInt; |
584 | | |
585 | 1 | testImpl(values, writerFunc, readerFunc, 63); |
586 | 1 | } |
587 | | |
588 | | TEST_F(BitStreamTest, readVarSize) |
589 | 1 | { |
590 | 1 | const std::array<uint32_t, 13> values = { |
591 | 1 | 0, |
592 | 1 | 65536, |
593 | 1 | 131072, |
594 | | |
595 | 1 | (1U << (0U)), |
596 | 1 | (1U << (7U)) - 1, |
597 | | |
598 | 1 | (1U << (7U)), |
599 | 1 | (1U << (7U + 7)) - 1, |
600 | | |
601 | 1 | (1U << (7U + 7)), |
602 | 1 | (1U << (7U + 7 + 7)) - 1, |
603 | | |
604 | 1 | (1U << (7U + 7 + 7)), |
605 | 1 | (1U << (7U + 7 + 7 + 7)) - 1, |
606 | | |
607 | 1 | (1U << (7U + 7 + 7 + 7)), |
608 | 1 | (1U << (7U + 7 + 7 + 7 + 3)) - 1, |
609 | 1 | }; |
610 | | |
611 | 1 | std::function<void(BitStreamWriter&, uint32_t)> writerFunc = &BitStreamWriter::writeVarSize; |
612 | 1 | std::function<uint32_t(BitStreamReader&)> readerFunc = &BitStreamReader::readVarSize; |
613 | | |
614 | 1 | testImpl(values, writerFunc, readerFunc, 31); |
615 | 1 | } |
616 | | |
617 | | TEST_F(BitStreamTest, readFloat16) |
618 | 1 | { |
619 | 1 | const std::array<float, 6> values = {2.0, -2.0, 0.6171875, 0.875, 9.875, 42.5}; |
620 | | |
621 | 1 | std::function<void(BitStreamWriter&, float)> writerFunc = &BitStreamWriter::writeFloat16; |
622 | 1 | std::function<float(BitStreamReader&)> readerFunc = &BitStreamReader::readFloat16; |
623 | | |
624 | 1 | testImpl(values, writerFunc, readerFunc, 15); |
625 | 1 | } |
626 | | |
627 | | TEST_F(BitStreamTest, readFloat32) |
628 | 1 | { |
629 | 1 | const std::array<float, 6> values = {2.0, -2.0, 0.6171875, 0.875, 9.875, 42.5}; |
630 | | |
631 | 1 | std::function<void(BitStreamWriter&, float)> writerFunc = &BitStreamWriter::writeFloat32; |
632 | 1 | std::function<float(BitStreamReader&)> readerFunc = &BitStreamReader::readFloat32; |
633 | | |
634 | 1 | testImpl(values, writerFunc, readerFunc, 31); |
635 | 1 | } |
636 | | |
637 | | TEST_F(BitStreamTest, readFloat64) |
638 | 1 | { |
639 | 1 | const std::array<double, 6> values = {2.0, -2.0, 0.6171875, 0.875, 9.875, 42.5}; |
640 | | |
641 | 1 | std::function<void(BitStreamWriter&, double)> writerFunc = &BitStreamWriter::writeFloat64; |
642 | 1 | std::function<double(BitStreamReader&)> readerFunc = &BitStreamReader::readFloat64; |
643 | | |
644 | 1 | testImpl(values, writerFunc, readerFunc, 61); |
645 | 1 | } |
646 | | |
647 | | TEST_F(BitStreamTest, readString) |
648 | 1 | { |
649 | 1 | const std::array<std::string, 3> values = { |
650 | 1 | "Hello World", "\n\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\"\'Hello World2\0nonWrittenPart", |
651 | 1 | "Price: \xE2\x82\xAC 3 what's this? -> \xC2\xA2" /* '€' '¢' */ |
652 | 1 | }; |
653 | | |
654 | 1 | std::function<void(BitStreamWriter&, const std::string&)> writerFunc = &BitStreamWriter::writeString; |
655 | 1 | std::function<std::string(BitStreamReader&)> readerFunc = std::bind( |
656 | 1 | &BitStreamReader::readString<std::allocator<char>>, std::placeholders::_1, std::allocator<char>()); |
657 | | |
658 | 1 | testImpl(values, writerFunc, readerFunc, 7); |
659 | 1 | } |
660 | | |
661 | | TEST_F(BitStreamTest, readBool) |
662 | 1 | { |
663 | 1 | const std::array<bool, 2> values = {true, false}; |
664 | | |
665 | 1 | std::function<void(BitStreamWriter&, bool)> writerFunc = &BitStreamWriter::writeBool; |
666 | 1 | std::function<bool(BitStreamReader&)> readerFunc = &BitStreamReader::readBool; |
667 | | |
668 | 1 | testImpl(values, writerFunc, readerFunc, 1); |
669 | 1 | } |
670 | | |
671 | | TEST_F(BitStreamTest, readBitBuffer) |
672 | 1 | { |
673 | 1 | const std::array<BitBuffer, 2> values = {BitBuffer(std::vector<uint8_t>({0xAB, 0xE0}), 11), |
674 | 1 | BitBuffer(std::vector<uint8_t>({0xAB, 0xCD, 0xFE}), 23)}; |
675 | | |
676 | 1 | std::function<void(BitStreamWriter&, const BitBuffer&)> writerFunc = |
677 | 1 | &BitStreamWriter::writeBitBuffer<std::allocator<uint8_t>>; |
678 | 1 | std::function<BitBuffer(BitStreamReader&)> readerFunc = std::bind( |
679 | 1 | &BitStreamReader::readBitBuffer<std::allocator<uint8_t>>, std::placeholders::_1, |
680 | 1 | std::allocator<uint8_t>()); |
681 | | |
682 | 1 | testImpl(values, writerFunc, readerFunc, 7); |
683 | 1 | } |
684 | | |
685 | | TEST_F(BitStreamTest, readBytes) |
686 | 1 | { |
687 | 1 | const std::array<vector<uint8_t>, 2> values = { |
688 | 1 | vector<uint8_t>{{0, 255}}, |
689 | 1 | vector<uint8_t>{{1, 127, 128, 254}}, |
690 | 1 | }; |
691 | | |
692 | 1 | std::function<void(BitStreamWriter&, const vector<uint8_t>&)> writerFunc = &BitStreamWriter::writeBytes; |
693 | 1 | std::function<vector<uint8_t>(BitStreamReader&)> readerFunc = std::bind( |
694 | 1 | &BitStreamReader::readBytes<std::allocator<uint8_t>>, std::placeholders::_1, |
695 | 1 | std::allocator<uint8_t>()); |
696 | | |
697 | 1 | testImpl(values, writerFunc, readerFunc, 7); |
698 | 1 | } |
699 | | |
700 | | TEST_F(BitStreamTest, setBitPosition) |
701 | 1 | { |
702 | 1 | testSetBitPosition(m_externalWriter); |
703 | 1 | testSetBitPosition(m_dummyWriter); |
704 | 1 | } |
705 | | |
706 | | TEST_F(BitStreamTest, alignTo) |
707 | 1 | { |
708 | 1 | testAlignTo(m_externalWriter); |
709 | 1 | testAlignTo(m_dummyWriter); |
710 | 1 | } |
711 | | |
712 | | } // namespace zserio |