Worldstone
 All Classes Files Functions Variables Enumerations Enumerator Macros Pages
BitStreamTests.cpp
Go to the documentation of this file.
1 
4 #include <BitStream.h>
5 #include <SystemUtils.h>
6 #include "doctest.h"
7 
9 
13 TEST_CASE("BitStreamView read.")
14 {
15  const char buffer[] = {0x01, 0x23, 0x45, 0x67, (char)0x89, (char)0xAB, (char)0xCD, (char)0xEF};
16  BitStreamView bitstream{buffer, sizeof(buffer) * CHAR_BIT};
17  CHECK(bitstream.bufferSizeInBytes() == sizeof(buffer));
18  CHECK(bitstream.sizeInBits() == sizeof(buffer) * CHAR_BIT);
19  SUBCASE("Unsigned integer reads")
20  {
21  // clang-format off
22  CHECK_EQ(bitstream.readUnsigned( 0) , /*==*/ ( 0 ));
23  CHECK_EQ(bitstream.readUnsigned( 8) , /*==*/ ( 0x01 ));
24  CHECK_EQ(bitstream.readUnsigned(16) , /*==*/ ( 0x4523 )); // Little endian
25  CHECK_EQ(bitstream.readUnsigned( 3) , /*==*/ ( 0x67 & 0b111 ));
26  CHECK_EQ(bitstream.readUnsigned(13) , /*==*/ ( 0x8967 >> 3 ));
27  CHECK_EQ(bitstream.readUnsigned(13) , /*==*/ ( 0xCDAB & 0x1FFF));
28  CHECK_EQ(bitstream.readUnsigned( 2) , /*==*/ ((0xCDAB >> 13) & 0b11 ));
29  CHECK_EQ(bitstream.readUnsigned( 9) , /*==*/ ( 0xEFCDAB >> 15 ));
30  // clang-format on
31  }
32  SUBCASE("Unsigned integer reads with smaller types")
33  {
34  // clang-format off
35  CHECK(bitstream.readUnsigned< uint8_t>( 0) == uint8_t( 0));
36  CHECK(bitstream.readUnsigned< uint8_t>( 8) == uint8_t( 0x01));
37  CHECK(bitstream.readUnsigned< uint8_t>( 8) == uint8_t( 0x23));
38  CHECK(bitstream.readUnsigned< uint8_t>( 8) == uint8_t( 0x45));
39  CHECK(bitstream.readUnsigned<uint16_t>(16) == uint16_t(0x8967));
40  // clang-format on
41  }
42  SUBCASE("Unsigned integer 8-bit or less reads")
43  {
44  // clang-format off
45  CHECK_EQ(bitstream.readUnsigned8OrLess(0), /*==*/ ( 0 ));
46  CHECK_EQ(bitstream.readUnsigned8OrLess(8), /*==*/ ( 0x01 ));
47  CHECK_EQ(bitstream.readUnsigned(16), /*==*/ ( 0x4523 )); // Little endian
48  CHECK_EQ(bitstream.readUnsigned8OrLess(3), /*==*/ ( 0x67 & 0b111 ));
49  CHECK_EQ(bitstream.readUnsigned(13), /*==*/ ( 0x8967 >> 3 ));
50  CHECK_EQ(bitstream.readUnsigned(13), /*==*/ ( 0xCDAB & 0x1FFF ));
51  CHECK_EQ(bitstream.readUnsigned8OrLess(2), /*==*/ ((0xCDAB >> 13) & 0b11 ));
52  CHECK_EQ(bitstream.readUnsigned8OrLess(5), /*==*/ ((0xEFCDAB >> 15) & 0b11111));
53  CHECK_EQ(bitstream.readUnsigned8OrLess(4), /*==*/ ((0xEFCDAB >> 20) & 0b1111 ));
54  // clang-format on
55  }
56  SUBCASE("Signed integer reads")
57  {
58  // clang-format off
59  CHECK_EQ(bitstream.readSigned< 0>() , /*==*/ ( 0 ));/*signbit=0*/
60  CHECK_EQ(bitstream.readSigned< 8>() , /*==*/ ( 0x01 ));/*signbit=0*/
61  CHECK_EQ(bitstream.readSigned<16>() , /*==*/ ( 0x4523 ));/*signbit=0*/
62  CHECK_EQ(bitstream.readSigned< 3>() , /*==*/ ( 0b111 | 0xFFFFFFF8));/*signbit=1*/
63  CHECK_EQ(bitstream.readSigned<13>() , /*==*/ ( 0x8967 >> 3 | 0xFFFFE000));/*signbit=1*/
64  CHECK_EQ(bitstream.readSigned<13>() , /*==*/ ( 0xCDAB & 0x1FFF ));/*signbit=0*/
65  CHECK_EQ(bitstream.readSigned< 2>() , /*==*/ ( 0b10 | 0xFFFFFFFC));/*signbit=1*/
66  CHECK_EQ(bitstream.readSigned< 9>() , /*==*/ ( 0x1DF | 0xFFFFFE00));/*signbit=1*/
67  // clang-format on
68  }
69  // Test the read 0/1 bits
70  SUBCASE("0 and 1 bits reads")
71  {
72  CHECK(bitstream.readBit());
73  CHECK_FALSE(bitstream.readBit());
74  CHECK(bitstream.tell() == 2);
75  CHECK(bitstream.read0Bits() == 0);
76  CHECK(bitstream.tell() == 2);
77  // Test the signed integers read
78  bitstream.skip(6);
79  CHECK(bitstream.readSigned<0>() == 0);
80  CHECK(bitstream.readSigned<1>() == -1);
81 
82  CHECK(bitstream.tell() == 2 + 6 + 1);
83  }
84  SUBCASE("Aligning to byte")
85  {
86  // Check if we align to the next byte correctly
87  bitstream.setPosition(9);
88  bitstream.alignToByte();
89  CHECK(bitstream.tell() == 16);
90  // Check that we do not change the position if already aligned
91  bitstream.alignToByte();
92  CHECK(bitstream.tell() == 16);
93  }
94 
95  SUBCASE("Subview of same size")
96  {
97  BitStreamView subView = bitstream.createSubView(bitstream.sizeInBits());
98  CHECK(subView.sizeInBits() == bitstream.sizeInBits());
99  CHECK(subView.tell() == bitstream.tell());
100  }
101  SUBCASE("Subview of same size and offset in first byte")
102  {
103  bitstream.setPosition(5);
104  BitStreamView subView = bitstream.createSubView(bitstream.sizeInBits() - 5);
105  CHECK(subView.bufferSizeInBytes() == bitstream.bufferSizeInBytes()); // Didn't change bytes
106  CHECK(subView.sizeInBits() == bitstream.sizeInBits() - 5); // Didn't change bytes
107  CHECK(subView.tell() == 0);
108  }
109  SUBCASE("Subview of same size and offset in 2nd byte")
110  {
111  const size_t offset = CHAR_BIT + 2;
112  bitstream.setPosition(offset);
113  BitStreamView subView = bitstream.createSubView(bitstream.sizeInBits() - offset);
114  CHECK(subView.bufferSizeInBytes() ==
115  bitstream.bufferSizeInBytes() - 1); // We're in the second byte
116  CHECK(subView.tell() == 0);
117  }
118  SUBCASE("Subview of size 0")
119  {
120  bitstream.setPosition(rand() % bitstream.sizeInBits());
121  BitStreamView subView = bitstream.createSubView(0);
122  CHECK(subView.bufferSizeInBytes() == 0); // We're in the second byte
123  CHECK(subView.tell() == 0);
124  }
125  CHECK(bitstream.good());
126  // TODO : set badbit on failure
127 }
void setPosition(size_t newPosition)
Set the current position, in bits.
Definition: BitStream.h:67
size_t tell() const
Returns the current position in the stream in bits.
Definition: BitStream.h:65
size_t sizeInBits() const
Returns the total size of the current stream buffer in bytes.
Definition: BitStream.h:93
TEST_CASE("BitStreamView read.")
Test the Bitstream usage in read-only.
Provides access to a variable bitsize values stream.
Definition: BitStream.h:33