28 void_type = types.VoidType(
"void")
29 assert void_type
is not None
30 assert isinstance(void_type, types.VoidType)
32 bits_type = types.BitsType(
"bits8", 8)
33 assert bits_type
is not None
34 assert isinstance(bits_type, types.BitsType)
36 uint_type = types.UIntType(
"uint32", 32)
37 assert uint_type
is not None
38 assert isinstance(uint_type, types.UIntType)
40 sint_type = types.SIntType(
"sint8", 8)
41 assert sint_type
is not None
42 assert isinstance(sint_type, types.SIntType)
43 assert sint_type.bit_width == 8
45 struct_type = types.StructType(
47 [(
"field1", types.UIntType(
"uint8", 8)),
48 (
"field2", types.UIntType(
"uint16", 16))],
50 assert struct_type
is not None
51 assert isinstance(struct_type, types.StructType)
52 field_map = {name: field_type
for name, field_type
in struct_type.fields}
53 assert isinstance(field_map[
"field1"], types.UIntType)
54 assert isinstance(field_map[
"field2"], types.UIntType)
56 array_type = types.ArrayType(
"uint8_array", types.UIntType(
"uint8", 8), 10)
57 assert array_type
is not None
58 assert isinstance(array_type, types.ArrayType)
59 assert hasattr(array_type,
"element_type")
60 assert isinstance(array_type.element_type, types.UIntType)
61 assert hasattr(array_type,
"size")
62 assert array_type.size == 10
64 any_type = types.AnyType(
"any")
65 assert any_type
is not None
66 assert isinstance(any_type, types.AnyType)
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"
78 alias_inner = types.UIntType(
"alias_inner", 16)
79 type_alias = types.TypeAlias(
"alias_scope",
"aliasName", alias_inner)
80 assert type_alias
is not None
81 assert isinstance(type_alias, types.TypeAlias)
82 assert type_alias.name ==
"aliasName"
83 assert isinstance(type_alias.inner_type, types.UIntType)
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"
98 uint8 = types.UIntType(
"uint8", 8)
99 uint16 = types.UIntType(
"uint16", 16)
101 union_type = types.UnionType(
"myunion", [(
"a", uint8), (
"b", uint16)])
102 assert union_type
is not None
103 assert isinstance(union_type, types.UnionType)
104 assert union_type.bit_width == 16
106 field_map = {name: ty
for name, ty
in union_type.fields}
107 assert isinstance(field_map[
"a"], types.UIntType)
108 assert isinstance(field_map[
"b"], types.UIntType)
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."""
154 uint8 = types.UIntType(
"uint8", 8)
155 uint32 = types.UIntType(
"uint32", 32)
156 small_struct = types.StructType(
"!hw.struct<x: ui8, y: ui8>", [(
"x", uint8),
158 union_type = types.UnionType(
"myunion2", [(
"wide", uint32),
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
184 signed = types.SIntType(
"si5", 5)
186 signed = types.TypeAlias(
"signed_alias",
"Signed", signed)
187 union_type = types.UnionType(
189 [(
"signed", signed), (
"unsigned", types.UIntType(
"ui3", 3)),
190 (
"bits", types.BitsType(
"i5", 5)),
191 (
"wide", types.UIntType(f
"ui{union_width}", union_width))])
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))
219 uint8 = types.UIntType(
"ui8", 8)
220 union_type = types.UnionType(
"nested_union",
222 (
"wide", types.UIntType(
"ui16", 16))])
223 struct_type = types.StructType(
"union_struct", [(
"tag", uint8),
224 (
"payload", union_type),
226 serialized = struct_type.serialize({
233 assert serialized == bytearray([0x87, 0xA5, 0, 0x12])
234 result, remaining = struct_type.deserialize(serialized)
243 assert remaining == bytearray()
247 element_type = types.UIntType(
"ui8", 8)
248 list_type = types._get_esi_type(
249 types.cpp.ListType(
"!esi.list<ui8>", element_type.cpp_type))
251 assert isinstance(list_type, types.ListType)
252 assert isinstance(list_type.element_type, types.UIntType)
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]))
281 uint8 = types.UIntType(
"ui8", 8)
282 into_type = types.StructType(
"!hw.struct<header: ui8, data: ui8>",
283 [(
"header", uint8), (
"data", uint8)])
284 header_type = types.StructType(
"!hw.struct<header: ui8>", [(
"header", uint8)])
285 data_type = types.StructType(
"!hw.struct<data: ui8>", [(
"data", uint8)])
286 lowered_type = types.UnionType(
287 "!hw.union<header: !hw.struct<header: ui8>, data: !hw.struct<data: ui8>>",
288 [(
"header", header_type), (
"data", data_type)])
289 window_type = types.WindowType(
290 '!esi.window<"test_window", !hw.struct<header: ui8, data: ui8>, '
291 '[<"header", [<"header">]>, <"data", [<"data">]>]>',
296 types.WindowType.Frame(
"header",
297 [types.WindowType.Field(
"header", 0, 0)]),
298 types.WindowType.Frame(
"data",
299 [types.WindowType.Field(
"data", 0, 0)]),
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]))