2727from abc import ABCMeta
2828from collections import OrderedDict
2929from typing import Any , BinaryIO , List , Dict , Optional , Type , Tuple , Union
30- from .base import STRUCTS
3130import hashlib
31+ from .base import STRUCTS
3232from .c_parser import parse_struct , parse_def , Tokens
3333from .field import calculate_padding , FieldType
34+ from .exceptions import CStructException
3435
3536__all__ = ['CStructMeta' , 'AbstractCStruct' ]
3637
3738
3839class CStructMeta (ABCMeta ):
3940 __size__ : int = 0
4041
41- # def __new__(cls: Type[type], name: str, bases: tuple, classdict: dict) -> MetaClass:
4242 def __new__ (metacls : Type [type ], name : str , bases : Tuple [str ], namespace : Dict [str , Any ]) -> Type [Any ]:
4343 __struct__ = namespace .get ('__struct__' , None )
4444 namespace ['__cls__' ] = bases [0 ] if bases else None
@@ -58,6 +58,7 @@ def __new__(metacls: Type[type], name: str, bases: Tuple[str], namespace: Dict[s
5858 return new_class
5959
6060 def __len__ (cls ) -> int :
61+ "Structure size (in bytes)"
6162 return cls .__size__
6263
6364 @property
@@ -67,12 +68,22 @@ def size(cls) -> int:
6768
6869
6970class AbstractCStruct (metaclass = CStructMeta ):
71+ """
72+ Abstract C struct to Python class
73+ """
74+
7075 __size__ : int = 0
76+ " Size in bytes "
7177 __fields__ : List [str ] = []
78+ " Struct/union fileds "
7279 __fields_types__ : Dict [str , FieldType ]
80+ " Dictionary mapping field names to types "
7381 __byte_order__ : Optional [str ] = None
82+ " Byte order "
7483 __alignment__ : int = 0
84+ " Alignament "
7585 __is_union__ : bool = False
86+ " True if the class is an union, False if it is a struct "
7687
7788 def __init__ (
7889 self , buffer : Optional [Union [bytes , BinaryIO ]] = None , flexible_array_length : Optional [int ] = None , ** kargs : Dict [str , Any ]
@@ -92,18 +103,30 @@ def __init__(
92103
93104 @classmethod
94105 def parse (
95- cls , __struct__ : Union [str , Tokens , Dict [str , Any ]], __name__ : Optional [str ] = None , ** kargs : Dict [str , Any ]
106+ cls ,
107+ __struct__ : Union [str , Tokens , Dict [str , Any ]],
108+ __name__ : Optional [str ] = None ,
109+ __byte_order__ : Optional [str ] = None ,
110+ __is_union__ : Optional [bool ] = False ,
111+ ** kargs : Dict [str , Any ]
96112 ) -> Type ["AbstractCStruct" ]:
97113 """
98114 Return a new class mapping a C struct/union definition.
99115
100- :param __struct__: definition of the struct (or union) in C syntax
101- :param __name__: (optional) name of the new class. If empty, a name based on the __struct__ hash is generated
102- :param __byte_order__: (optional) byte order, valid values are LITTLE_ENDIAN, BIG_ENDIAN, NATIVE_ORDER
103- :param __is_union__: (optional) True for union, False for struct (default)
104- :returns: cls subclass
116+ Args:
117+ __struct__: definition of the struct (or union) in C syntax
118+ __name__: name of the new class. If empty, a name based on the __struct__ hash is generated
119+ __byte_order__: byte order, valid values are LITTLE_ENDIAN, BIG_ENDIAN, NATIVE_ORDER
120+ __is_union__: True for union, False for struct
121+
122+ Returns:
123+ cls: a new class mapping the defintion
105124 """
106125 cls_kargs : Dict [str , Any ] = dict (kargs )
126+ if __byte_order__ is not None :
127+ cls_kargs ['__byte_order__' ] = __byte_order__
128+ if __is_union__ is not None :
129+ cls_kargs ['__is_union__' ] = __is_union__
107130 cls_kargs ['__struct__' ] = __struct__
108131 if isinstance (__struct__ , (str , Tokens )):
109132 del cls_kargs ['__struct__' ]
@@ -123,20 +146,23 @@ def set_flexible_array_length(self, flexible_array_length: Optional[int]) -> Non
123146 """
124147 Set flexible array length (i.e. number of elements)
125148
126- :flexible_array_length: flexible array length
149+ Args:
150+ flexible_array_length: flexible array length
127151 """
128152 if flexible_array_length is not None :
129153 # Search for the flexible array
130154 flexible_array : Optional [FieldType ] = [x for x in self .__fields_types__ .values () if x .flexible_array ][0 ]
131155 if flexible_array is None :
132- raise ValueError ("Flexible array not found in struct" )
156+ raise CStructException ("Flexible array not found in struct" )
133157 flexible_array .vlen = flexible_array_length
134158
135159 def unpack (self , buffer : Optional [Union [bytes , BinaryIO ]], flexible_array_length : Optional [int ] = None ) -> bool :
136160 """
137161 Unpack bytes containing packed C structure data
138162
139- :param buffer: bytes or binary stream to be unpacked
163+ Args:
164+ buffer: bytes or binary stream to be unpacked
165+ flexible_array_length: flexible array length
140166 """
141167 self .set_flexible_array_length (flexible_array_length )
142168 if hasattr (buffer , 'read' ):
@@ -151,8 +177,10 @@ def unpack_from(
151177 """
152178 Unpack bytes containing packed C structure data
153179
154- :param buffer: bytes to be unpacked
155- :param offset: optional buffer offset
180+ Args:
181+ buffer: bytes to be unpacked
182+ offset: optional buffer offset
183+ flexible_array_length: flexible array length
156184 """
157185 raise NotImplementedError
158186
0 commit comments