Coverage for /home/runner/work/zserio/zserio/compiler/extensions/python/runtime/tests/test_bitwriter.py: 100%
208 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-12-05 10:43 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-12-05 10:43 +0000
1import unittest
3from zserio.bitbuffer import BitBuffer
4from zserio.bitwriter import BitStreamWriter
5from zserio.exception import PythonRuntimeException
6from zserio.limits import (
7 VARINT16_MIN,
8 VARINT16_MAX,
9 VARINT32_MIN,
10 VARINT32_MAX,
11 VARINT64_MIN,
12 VARINT64_MAX,
13 VARINT_MIN,
14 VARINT_MAX,
15 VARUINT16_MIN,
16 VARUINT16_MAX,
17 VARUINT32_MIN,
18 VARUINT32_MAX,
19 VARUINT64_MIN,
20 VARUINT64_MAX,
21 VARUINT_MIN,
22 VARUINT_MAX,
23 VARSIZE_MIN,
24 VARSIZE_MAX,
25)
28class BitStreamWriterTest(unittest.TestCase):
30 def test_write_unaligned_data(self):
31 # number expected to be written at offset
32 test_value = 123
34 for offset in range(65):
35 writer = BitStreamWriter()
37 if offset != 0:
38 writer.write_bits(0, offset)
39 writer.write_bits(test_value, 8)
41 # check written value
42 buffer = writer.byte_array
43 written_test_value = buffer[offset // 8] << (offset % 8)
44 if offset % 8 != 0:
45 written_test_value |= buffer[offset // 8 + 1] >> (8 - (offset % 8))
46 self.assertEqual(test_value, written_test_value, msg="Offset: " + str(offset))
48 def test_write_bits(self):
49 writer = BitStreamWriter()
50 writer.write_bits(0, 8)
51 writer.write_bits(255, 8)
52 writer.write_bits(1, 1)
53 writer.write_bits(0x3F, 6)
54 writer.write_bits(1, 1)
55 self.assertEqual(b"\x00\xff\xff", writer.byte_array)
56 self.assertEqual(3 * 8, writer.bitposition)
57 writer.write_bits(0xFF, 8)
58 self.assertEqual(b"\x00\xff\xff\xff", writer.byte_array)
59 self.assertEqual(4 * 8, writer.bitposition)
60 writer.write_bits(0, 4)
61 self.assertEqual(b"\x00\xff\xff\xff\x00", writer.byte_array)
62 self.assertEqual(4 * 8 + 4, writer.bitposition)
63 writer.write_bits(0x0F, 4)
64 self.assertEqual(b"\x00\xff\xff\xff\x0f", writer.byte_array)
65 self.assertEqual(5 * 8, writer.bitposition)
66 writer.write_bits(0x80, 8)
67 self.assertEqual(b"\x00\xff\xff\xff\x0f\x80", writer.byte_array)
68 self.assertEqual(6 * 8, writer.bitposition)
70 for numbits in [-1, 0, 65]:
71 with self.assertRaises(PythonRuntimeException):
72 writer.write_bits(0, numbits)
74 with self.assertRaises(PythonRuntimeException):
75 writer.write_bits(1, numbits)
77 with self.assertRaises(PythonRuntimeException):
78 writer.write_bits(256, 8) # above the upper bound
80 with self.assertRaises(PythonRuntimeException):
81 writer.write_bits(-1, 8) # below the lower bound
83 def test_write_signed_bits(self):
84 writer = BitStreamWriter()
85 writer.write_signed_bits(0, 1)
86 writer.write_signed_bits(-1, 2)
87 writer.write_signed_bits(-1, 5)
88 self.assertEqual(b"\x7f", writer.byte_array)
89 self.assertEqual(8, writer.bitposition)
90 writer.write_signed_bits(-1, 1)
91 writer.write_signed_bits(-1, 7)
92 self.assertEqual(b"\x7f\xff", writer.byte_array)
93 self.assertEqual(16, writer.bitposition)
95 for numbits in [-1, 0, 65]:
96 with self.assertRaises(PythonRuntimeException):
97 writer.write_signed_bits(0, numbits)
99 with self.assertRaises(PythonRuntimeException):
100 writer.write_signed_bits(1, numbits)
102 with self.assertRaises(PythonRuntimeException):
103 writer.write_signed_bits(1, 1) # above the upper bound
105 with self.assertRaises(PythonRuntimeException):
106 writer.write_signed_bits(128, 8) # above the upper bound
108 with self.assertRaises(PythonRuntimeException):
109 writer.write_signed_bits(-129, 8) # below the lower bound
111 def test_write_varint16(self):
112 writer = BitStreamWriter()
113 writer.write_varint16(0)
114 self.assertEqual(8, writer.bitposition)
115 self.assertEqual(b"\x00", writer.byte_array)
116 with self.assertRaises(PythonRuntimeException):
117 writer.write_varint16(VARINT16_MIN - 1)
118 with self.assertRaises(PythonRuntimeException):
119 writer.write_varint16(VARINT16_MAX + 1)
121 def test_write_varint32(self):
122 writer = BitStreamWriter()
123 writer.write_varint32(0)
124 self.assertEqual(8, writer.bitposition)
125 self.assertEqual(b"\x00", writer.byte_array)
126 with self.assertRaises(PythonRuntimeException):
127 writer.write_varint32(VARINT32_MIN - 1)
128 with self.assertRaises(PythonRuntimeException):
129 writer.write_varint32(VARINT32_MAX + 1)
131 def test_write_varint64(self):
132 writer = BitStreamWriter()
133 writer.write_varint64(0)
134 self.assertEqual(8, writer.bitposition)
135 self.assertEqual(b"\x00", writer.byte_array)
136 with self.assertRaises(PythonRuntimeException):
137 writer.write_varint64(VARINT64_MIN - 1)
138 with self.assertRaises(PythonRuntimeException):
139 writer.write_varint64(VARINT64_MAX + 1)
141 def test_write_varint(self):
142 writer = BitStreamWriter()
143 writer.write_varint(0)
144 self.assertEqual(b"\x00", writer.byte_array)
145 self.assertEqual(8, writer.bitposition)
146 writer.write_varint(VARINT_MIN)
147 self.assertEqual(16, writer.bitposition)
148 self.assertEqual(b"\x00\x80", writer.byte_array) # INT64_MIN is encoded as -0
149 with self.assertRaises(PythonRuntimeException):
150 writer.write_varint(VARINT_MIN - 1)
151 with self.assertRaises(PythonRuntimeException):
152 writer.write_varint(VARINT_MAX + 1)
154 def test_write_varuint16(self):
155 writer = BitStreamWriter()
156 writer.write_varuint16(0)
157 self.assertEqual(8, writer.bitposition)
158 self.assertEqual(b"\x00", writer.byte_array)
159 with self.assertRaises(PythonRuntimeException):
160 writer.write_varuint16(VARUINT16_MIN - 1)
161 with self.assertRaises(PythonRuntimeException):
162 writer.write_varuint16(VARUINT16_MAX + 1)
164 def test_write_varuint32(self):
165 writer = BitStreamWriter()
166 writer.write_varuint32(0)
167 self.assertEqual(8, writer.bitposition)
168 self.assertEqual(b"\x00", writer.byte_array)
169 with self.assertRaises(PythonRuntimeException):
170 writer.write_varuint32(VARUINT32_MIN - 1)
171 with self.assertRaises(PythonRuntimeException):
172 writer.write_varuint32(VARUINT32_MAX + 1)
174 def test_write_varuint64(self):
175 writer = BitStreamWriter()
176 writer.write_varuint64(0)
177 self.assertEqual(8, writer.bitposition)
178 self.assertEqual(b"\x00", writer.byte_array)
179 with self.assertRaises(PythonRuntimeException):
180 writer.write_varuint64(VARUINT64_MIN - 1)
181 with self.assertRaises(PythonRuntimeException):
182 writer.write_varuint64(VARUINT64_MAX + 1)
184 def test_write_varuint(self):
185 writer = BitStreamWriter()
186 writer.write_varuint(0)
187 self.assertEqual(8, writer.bitposition)
188 self.assertEqual(b"\x00", writer.byte_array)
189 with self.assertRaises(PythonRuntimeException):
190 writer.write_varuint(VARUINT_MIN - 1)
191 with self.assertRaises(PythonRuntimeException):
192 writer.write_varuint(VARUINT_MAX + 1)
194 def test_write_varsize(self):
195 writer = BitStreamWriter()
196 writer.write_varsize(0)
197 self.assertEqual(8, writer.bitposition)
198 self.assertEqual(b"\x00", writer.byte_array)
199 with self.assertRaises(PythonRuntimeException):
200 writer.write_varsize(VARSIZE_MIN - 1)
201 with self.assertRaises(PythonRuntimeException):
202 writer.write_varsize(VARSIZE_MAX + 1)
204 def test_write_float16(self):
205 writer = BitStreamWriter()
206 writer.write_float16(0)
207 self.assertEqual(16, writer.bitposition)
208 self.assertEqual(b"\x00\x00", writer.byte_array)
210 def test_write_float32(self):
211 writer = BitStreamWriter()
212 writer.write_float32(0)
213 self.assertEqual(32, writer.bitposition)
214 self.assertEqual(b"\x00\x00\x00\x00", writer.byte_array)
216 def test_write_float64(self):
217 writer = BitStreamWriter()
218 writer.write_float64(0)
219 self.assertEqual(64, writer.bitposition)
220 self.assertEqual(b"\x00\x00\x00\x00\x00\x00\x00\x00", writer.byte_array)
222 def test_write_string(self):
223 writer = BitStreamWriter()
224 writer.write_string("")
225 self.assertEqual(8, writer.bitposition) # length 0
226 self.assertEqual(b"\x00", writer.byte_array)
228 def test_write_bool(self):
229 writer = BitStreamWriter()
230 writer.write_bool(True)
231 writer.write_bool(False)
232 writer.write_bool(True)
233 writer.write_bool(False)
234 writer.write_bool(True)
235 writer.write_bool(False)
236 self.assertEqual(6, writer.bitposition)
237 self.assertEqual(b"\xA8", writer.byte_array)
239 def test_write_bitbuffer(self):
240 writer = BitStreamWriter()
241 writer.write_bitbuffer(BitBuffer(bytes([0xAB, 0xE0]), 11))
242 writer.write_bitbuffer(BitBuffer(bytes([0x00, 0xFE]), 15))
243 self.assertEqual(8 + 11 + 8 + 15, writer.bitposition)
244 self.assertEqual(b"\x0B\xAB\xE1\xE0\x1F\xC0", writer.byte_array)
246 def test_byte_array(self):
247 writer = BitStreamWriter()
248 self.assertEqual(b"", writer.byte_array)
250 def test_bitposition(self):
251 writer = BitStreamWriter()
252 self.assertEqual(0, writer.bitposition)
254 def test_alignto(self):
255 writer = BitStreamWriter()
256 writer.alignto(8)
257 self.assertEqual(0, writer.bitposition)
258 writer.alignto(2)
259 self.assertEqual(0, writer.bitposition)
260 writer.write_bool(True)
261 writer.alignto(8)
262 self.assertEqual(8, writer.bitposition)
263 writer.write_bool(True)
264 writer.alignto(2)
265 self.assertEqual(10, writer.bitposition)