29 assert void_type
is not None
33 assert bits_type
is not None
37 assert uint_type
is not None
41 assert sint_type
is not None
43 assert sint_type.bit_width == 8
50 assert struct_type
is not None
52 field_map = {name: field_type
for name, field_type
in struct_type.fields}
57 assert array_type
is not None
59 assert hasattr(array_type,
"element_type")
61 assert hasattr(array_type,
"size")
62 assert array_type.size == 10
65 assert any_type
is not None
67 valid, reason = any_type.is_valid(0)
69 assert "any type" in reason
70 assert any_type.bit_width == -1
73 except ValueError
as exc:
74 assert "any type" in str(exc)
76 assert False,
"AnyType.serialize should raise"
80 assert type_alias
is not None
82 assert type_alias.name ==
"aliasName"
84 assert type_alias.bit_width == alias_inner.bit_width
85 alias_valid, alias_reason = type_alias.is_valid(42)
86 inner_valid, inner_reason = alias_inner.is_valid(42)
87 assert alias_valid == inner_valid
88 assert alias_reason == inner_reason
89 serialized = type_alias.serialize(42)
90 inner_serialized = alias_inner.serialize(42)
91 assert serialized == inner_serialized
92 assert type_alias.deserialize(serialized) == alias_inner.deserialize(
94 assert str(type_alias) ==
"aliasName"
102 assert union_type
is not None
104 assert union_type.bit_width == 16
106 field_map = {name: ty
for name, ty
in union_type.fields}
111 valid, reason = union_type.is_valid({
"a": 42})
113 valid, reason = union_type.is_valid({
"b": 1000})
117 valid, reason = union_type.is_valid({
"a": 1,
"b": 2})
119 assert "exactly 1" in reason
122 valid, reason = union_type.is_valid({
"c": 1})
124 assert "unknown" in reason
127 valid, reason = union_type.is_valid(42)
131 serialized_a = union_type.serialize({
"a": 42})
132 assert serialized_a == bytearray([42, 0])
133 (deserialized, remaining) = union_type.deserialize(serialized_a)
134 assert remaining == bytearray()
135 assert "a" in deserialized
136 assert "b" in deserialized
137 assert deserialized[
"a"] == 42
138 assert deserialized[
"b"] == 42
142 serialized_b = union_type.serialize({
"b": 0x1234})
143 assert len(serialized_b) == 2
144 assert serialized_b == bytearray([0x34, 0x12])
146 remaining_b) = union_type.deserialize(serialized_b + bytearray([0xDE, 0xAD]))
147 assert remaining_b == bytearray([0xDE, 0xAD])
148 assert deserialized_b[
"a"] == 0x34
149 assert deserialized_b[
"b"] == 0x1234
153 """Union members share the LSB without changing their internal layout."""
156 small_struct =
types.StructType(
"!hw.struct<x: ui8, y: ui8>", [(
"x", uint8),
159 (
"narrow", small_struct)])
160 assert union_type.bit_width == 32
162 serialized = union_type.serialize({
"narrow": {
"x": 0xAA,
"y": 0xBB}})
163 assert serialized == bytearray([0xBB, 0xAA, 0, 0])
165 (result, leftover) = union_type.deserialize(serialized)
166 assert leftover == bytearray()
167 assert result[
"narrow"] == {
"x": 0xAA,
"y": 0xBB}
168 assert result[
"wide"] == 0xAABB
192 union_bytes = (union_width + 7) // 8
193 for value
in [-16, -7, -1, 0, 7, 15]:
194 serialized = union_type.serialize({
"signed": value})
195 assert serialized == bytearray([value & 0x1F]) + bytearray(union_bytes - 1)
196 decoded, remaining = union_type.deserialize(serialized)
197 assert decoded[
"signed"] == value
198 assert decoded[
"unsigned"] == value & 7
199 assert decoded[
"bits"] == bytearray([value & 0x1F])
200 assert remaining == bytearray()
202 raw = bytearray([0xBC]) + bytearray([0x0A] * (union_bytes - 1))
203 decoded, remaining = union_type.deserialize(raw + bytearray([0xDE, 0xAD]))
204 assert decoded[
"signed"] == -4
205 assert decoded[
"unsigned"] == 4
206 assert decoded[
"bits"] == bytearray([0x1C])
207 assert remaining == bytearray([0xDE, 0xAD])
209 bits = bytearray([0xF9])
210 assert union_type.serialize({
"bits": bits}) == (bytearray([0x19]) +
211 bytearray(union_bytes - 1))
212 assert bits == bytearray([0xF9])
214 with pytest.raises(ValueError, match=
"insufficient data for union"):
215 union_type.deserialize(bytearray(union_bytes - 1))
248 list_type = types._get_esi_type(
249 types.cpp.ListType(
"!esi.list<ui8>", element_type.cpp_type))
253 assert list_type.element_type.id == element_type.id
254 assert list_type.bit_width == -1
256 supports_host, reason = list_type.supports_host
257 assert not supports_host
258 assert reason ==
"list types require an enclosing window encoding"
260 valid, invalid_reason = list_type.is_valid([0x12, 0x34])
262 assert invalid_reason
is None
264 valid, invalid_reason = list_type.is_valid(
"not a list")
266 assert "must be a list" in invalid_reason
268 valid, invalid_reason = list_type.is_valid([0x12, 0x1FF])
270 assert invalid_reason ==
"invalid element 1: out of range: 511"
272 with pytest.raises(ValueError, match=
"cannot be serialized without a window"):
273 list_type.serialize([0x12, 0x34])
275 with pytest.raises(ValueError,
276 match=
"cannot be deserialized without a window"):
277 list_type.deserialize(bytearray([0x12, 0x34]))
283 [(
"header", uint8), (
"data", uint8)])
284 header_type =
types.StructType(
"!hw.struct<header: ui8>", [(
"header", uint8)])
287 "!hw.union<header: !hw.struct<header: ui8>, data: !hw.struct<data: ui8>>",
288 [(
"header", header_type), (
"data", data_type)])
290 '!esi.window<"test_window", !hw.struct<header: ui8, data: ui8>, '
291 '[<"header", [<"header">]>, <"data", [<"data">]>]>',
303 supports_host, reason = window_type.supports_host
304 assert not supports_host
305 assert reason
is not None
306 assert "not yet supported" in reason
308 valid, invalid_reason = window_type.is_valid({
"header": 1,
"data": 2})
310 assert invalid_reason == reason
312 with pytest.raises(ValueError, match=
"not yet supported"):
313 window_type.serialize({
"header": 1,
"data": 2})
315 with pytest.raises(ValueError, match=
"not yet supported"):
316 window_type.deserialize(bytearray([1, 2]))