@@ -43,23 +43,46 @@ class property is not `None`, it will consume the remainder of
4343 """
4444
4545 base = cls .from_buffer_copy (source , offset )
46+ vla_val : list | VLACompatLittleEndianStruct
4647 if cls .vla_field is None :
4748 return base
4849
4950 remainder = source [ctypes .sizeof (cls ) :]
5051 vla_field_name , vla_field_type = cls .vla_field # type: ignore
5152
5253 if issubclass (vla_field_type , ctypes .Array ):
53- array_base : ctypes ._CData = vla_field_type ._type_ # type: ignore
54+ array_base : ctypes ._PyCSimpleType = vla_field_type ._type_ # type: ignore
55+ if hasattr (array_base , "vla_counted_by" ):
56+ # This is an array of VLA arrays where the sub-arrys define their own length
57+ vla_val = []
58+ # Consume all remaining buffer bytes
59+ while len (remainder ) > 0 :
60+ sub_vla_field_name , sub_vla_field_type = array_base .vla_field # type: ignore
61+ sub_array_base : ctypes ._CData = sub_vla_field_type ._type_ # type: ignore
62+ sub_base = array_base .from_buffer_copy (remainder )
63+ sub_base_size = ctypes .sizeof (sub_base )
64+ sub_count = getattr (sub_base , array_base .vla_counted_by )
65+ if sub_count < 0 :
66+ # Assume that negative length is an error code and use 0
67+ vla_val .append (sub_base )
68+ else :
69+ sub_vla_type = sub_count * sub_array_base
70+ # Don't use ctypes.sizeof on constructed type, it returns the wrong value
71+ sub_vla_size = sub_count * ctypes .sizeof (sub_array_base )
72+ sub_vla_val = sub_vla_type .from_buffer_copy (remainder [sub_base_size :])
73+ setattr (sub_base , sub_vla_field_name , sub_vla_val )
74+ vla_val .append (sub_base )
75+ remainder = remainder [sub_base_size + sub_vla_size :]
76+ else :
77+ # Determine the number of VLA elements on "source"
78+ vla_byte_len = (len (source ) - offset ) - ctypes .sizeof (cls )
79+ vla_element_size = ctypes .sizeof (array_base )
80+ if vla_byte_len % vla_element_size != 0 :
81+ raise TypeError (f"Unaligned VLA buffer for { cls } (len { len (source )} )" )
82+ vla_num = vla_byte_len // vla_element_size
83+ vla_type = vla_num * array_base
84+ vla_val = vla_type .from_buffer_copy (remainder )
5485
55- # Determine the number of VLA elements on "source"
56- vla_byte_len = (len (source ) - offset ) - ctypes .sizeof (cls )
57- vla_element_size = ctypes .sizeof (array_base )
58- if vla_byte_len % vla_element_size != 0 :
59- raise TypeError (f"Unaligned VLA buffer for { cls } (len { len (source )} )" )
60- vla_num = vla_byte_len // vla_element_size
61- vla_type = vla_num * array_base
62- vla_val = vla_type .from_buffer_copy (remainder )
6386 elif issubclass (vla_field_type , VLACompatLittleEndianStruct ):
6487 vla_val = vla_field_type .vla_from_buffer_copy (remainder )
6588 else :
0 commit comments