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