Coverage for /home/runner/work/zserio/zserio/compiler/extensions/python/runtime/tests/test_bitreader.py: 100%
188 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-04-30 09:38 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-04-30 09:38 +0000
1import unittest
3from zserio.bitbuffer import BitBuffer
4from zserio.bitreader import BitStreamReader
5from zserio.bitsizeof import INT64_MIN
6from zserio.exception import PythonRuntimeException
9class BitStreamReaderTest(unittest.TestCase):
11 def test_constructor(self):
12 reader = BitStreamReader(bytes([0xAE, 0xEA, 0x80]), 17)
13 self.assertEqual(0xAE, reader.read_bits(8))
14 self.assertEqual(0xEA, reader.read_bits(8))
15 self.assertEqual(0x01, reader.read_bits(1))
16 with self.assertRaises(PythonRuntimeException):
17 reader.read_bits(1) # no more bits available
19 def test_constructor_wrong_bitsize(self):
20 with self.assertRaises(PythonRuntimeException):
21 BitStreamReader(bytes([0xAE]), 9)
23 def test_from_bitbuffer(self):
24 bitbuffer = BitBuffer(bytes([0xAE, 0xEA, 0x80]), 17)
25 reader = BitStreamReader.from_bitbuffer(bitbuffer)
26 self.assertEqual(bitbuffer.bitsize, reader.buffer_bitsize)
27 self.assertEqual(0xAEE, reader.read_bits(12))
28 self.assertEqual(0x0A, reader.read_bits(4))
29 self.assertEqual(0x01, reader.read_bits(1))
30 with self.assertRaises(PythonRuntimeException):
31 reader.read_bits(1)
33 def test_from_bitbuffer_overflow(self):
34 bitbuffer = BitBuffer(bytes([0xFF, 0xFF, 0xF0]), 19)
35 reader = BitStreamReader.from_bitbuffer(bitbuffer)
36 self.assertEqual(bitbuffer.bitsize, reader.buffer_bitsize)
37 with self.assertRaises(PythonRuntimeException):
38 reader.read_bits(20)
40 def test_read_unaligned_data(self):
41 # number expected to read at offset
42 test_value = 123
44 for offset in range(65):
45 buffer = bytearray((8 + offset + 7) // 8)
47 # write test value at offset to data buffer
48 buffer[offset // 8] = test_value >> (offset % 8)
49 if offset % 8 != 0: # don't write behind the buffer
50 buffer[offset // 8 + 1] = 0xFF & test_value << (8 - offset % 8)
52 bitbuffer = BitBuffer(buffer, 8 + offset)
53 reader = BitStreamReader.from_bitbuffer(bitbuffer)
55 # read offset bits
56 self.assertEqual(0, reader.read_bits(offset))
58 # read magic number
59 self.assertEqual(test_value, reader.read_bits(8), msg="Offset: " + str(offset))
61 # check eof
62 with self.assertRaises(PythonRuntimeException):
63 reader.read_bits(1)
65 def test_read_bits(self):
66 data = [0, 1, 255, 128, 127]
67 reader = BitStreamReader(bytes(data))
68 for byte in data:
69 self.assertEqual(byte, reader.read_bits(8))
71 with self.assertRaises(PythonRuntimeException):
72 reader.read_bits(-1)
74 self.assertEqual(0, reader.read_bits(0)) # read 0 bits
76 with self.assertRaises(PythonRuntimeException):
77 reader.read_bits(1) # no more bits available
79 def test_read_signed_bits(self):
80 data = [0, 0xFF, 1, 127, 0x80]
81 reader = BitStreamReader(bytes(data))
82 self.assertEqual(0, reader.read_signed_bits(8))
83 self.assertEqual(-1, reader.read_signed_bits(8)) # 0xff == -1
84 self.assertEqual(1, reader.read_signed_bits(8))
85 self.assertEqual(127, reader.read_signed_bits(8))
86 self.assertEqual(-128, reader.read_signed_bits(8)) # 0x80 == -128
88 self.assertEqual(0, reader.read_signed_bits(0)) # read 0 bits
90 with self.assertRaises(PythonRuntimeException):
91 reader.read_signed_bits(1) # no more bits available
93 with self.assertRaises(PythonRuntimeException):
94 reader.read_signed_bits(-1)
96 def test_read_varint16(self):
97 reader = BitStreamReader(bytes(1))
98 self.assertEqual(0, reader.read_varint16())
99 self.assertEqual(8, reader.bitposition)
100 with self.assertRaises(PythonRuntimeException):
101 reader.read_varint16()
103 def test_read_varint32(self):
104 reader = BitStreamReader(bytes(1))
105 self.assertEqual(0, reader.read_varint32())
106 self.assertEqual(8, reader.bitposition)
107 with self.assertRaises(PythonRuntimeException):
108 reader.read_varint32()
110 def test_read_varint64(self):
111 reader = BitStreamReader(bytes(1))
112 self.assertEqual(0, reader.read_varint64())
113 self.assertEqual(8, reader.bitposition)
114 with self.assertRaises(PythonRuntimeException):
115 reader.read_varint64()
117 def test_read_varint(self):
118 reader = BitStreamReader(b"\x00\x80")
119 self.assertEqual(0, reader.read_varint())
120 self.assertEqual(8, reader.bitposition)
121 self.assertEqual(INT64_MIN, reader.read_varint())
122 self.assertEqual(16, reader.bitposition)
123 with self.assertRaises(PythonRuntimeException):
124 reader.read_varint()
126 def test_read_varuint16(self):
127 reader = BitStreamReader(bytes(1))
128 self.assertEqual(0, reader.read_varuint16())
129 self.assertEqual(8, reader.bitposition)
130 with self.assertRaises(PythonRuntimeException):
131 reader.read_varuint16()
133 def test_read_varuint32(self):
134 reader = BitStreamReader(bytes(1))
135 self.assertEqual(0, reader.read_varuint32())
136 self.assertEqual(8, reader.bitposition)
137 with self.assertRaises(PythonRuntimeException):
138 reader.read_varuint32()
140 def test_read_varuint64(self):
141 reader = BitStreamReader(bytes(1))
142 self.assertEqual(0, reader.read_varuint64())
143 self.assertEqual(8, reader.bitposition)
144 with self.assertRaises(PythonRuntimeException):
145 reader.read_varuint64()
147 def test_read_varuint(self):
148 reader = BitStreamReader(bytes(1))
149 self.assertEqual(0, reader.read_varuint())
150 self.assertEqual(8, reader.bitposition)
151 with self.assertRaises(PythonRuntimeException):
152 reader.read_varuint()
154 def test_read_varsize(self):
155 # overflow, 2^32 - 1 is too much (b'\x83\xFF\xFF\xFF\xFF') is the maximum)
156 reader = BitStreamReader(b"\x87\xFF\xFF\xFF\xFF")
157 with self.assertRaises(PythonRuntimeException):
158 reader.read_varsize()
160 # overflow, 2^36 - 1 is too much (b'\x83\xFF\xFF\xFF\xFF') is the maximum)
161 reader = BitStreamReader(b"\xFF\xFF\xFF\xFF\xFF")
162 with self.assertRaises(PythonRuntimeException):
163 reader.read_varsize()
165 def test_read_float16(self):
166 reader = BitStreamReader(bytes(2))
167 self.assertEqual(0.0, reader.read_float16())
168 self.assertEqual(16, reader.bitposition)
169 with self.assertRaises(PythonRuntimeException):
170 reader.read_float16()
172 def test_read_float32(self):
173 reader = BitStreamReader(bytes(4))
174 self.assertEqual(0.0, reader.read_float32())
175 self.assertEqual(32, reader.bitposition)
176 with self.assertRaises(PythonRuntimeException):
177 reader.read_float32()
179 def test_read_float64(self):
180 reader = BitStreamReader(bytes(8))
181 self.assertEqual(0.0, reader.read_float64())
182 self.assertEqual(64, reader.bitposition)
183 with self.assertRaises(PythonRuntimeException):
184 reader.read_float64()
186 def test_read_string(self):
187 reader = BitStreamReader(bytes(b"\x01\x41"))
188 self.assertEqual("A", reader.read_string())
189 self.assertEqual(16, reader.bitposition)
190 with self.assertRaises(PythonRuntimeException):
191 reader.read_string()
193 def test_read_bool(self):
194 reader = BitStreamReader(bytes(b"\xA8"))
195 self.assertEqual(True, reader.read_bool())
196 self.assertEqual(False, reader.read_bool())
197 self.assertEqual(True, reader.read_bool())
198 self.assertEqual(False, reader.read_bool())
199 self.assertEqual(True, reader.read_bool())
200 self.assertEqual(False, reader.read_bool())
201 self.assertEqual(False, reader.read_bool())
202 self.assertEqual(False, reader.read_bool())
203 with self.assertRaises(PythonRuntimeException):
204 reader.read_bool()
206 def test_read_bitbuffer(self):
207 reader = BitStreamReader(bytes(b"\x0B\xAB\xE1\xE0\x1F\xC0"))
208 self.assertEqual(BitBuffer(bytes([0xAB, 0xE0]), 11), reader.read_bitbuffer())
209 self.assertEqual(BitBuffer(bytes([0x00, 0xFE]), 15), reader.read_bitbuffer())
210 with self.assertRaises(PythonRuntimeException):
211 reader.read_bitbuffer()
213 def test_bitposition(self):
214 reader = BitStreamReader(bytes(1), 7)
215 reader.bitposition = 0
216 self.assertEqual(0, reader.bitposition)
217 reader.bitposition = 7
218 self.assertEqual(7, reader.bitposition)
220 with self.assertRaises(PythonRuntimeException):
221 reader.bitposition = 8
222 with self.assertRaises(PythonRuntimeException):
223 reader.bitposition = -1
225 reader.bitposition = 0
226 self.assertEqual(0, reader.bitposition)
228 def test_alignto(self):
229 reader = BitStreamReader(bytes(1))
230 reader.alignto(1)
231 self.assertEqual(0, reader.bitposition)
232 reader.read_bits(1)
233 self.assertEqual(1, reader.bitposition)
234 reader.alignto(1)
235 self.assertEqual(1, reader.bitposition)
236 reader.alignto(4)
237 self.assertEqual(4, reader.bitposition)