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