c-struct-data-parser 0.2.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/PKG-INFO +1 -1
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/pyproject.toml +1 -1
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/bytes_reader.py +1 -1
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/data_structures.py +59 -28
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/parser.py +0 -1
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/reader_abc.py +3 -1
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/README.md +0 -0
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/__init__.py +0 -0
- {c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/py.typed +0 -0
{c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/bytes_reader.py
RENAMED
|
@@ -11,7 +11,7 @@ class BytesReader(Reader):
|
|
|
11
11
|
read_bytes = self.bs[current : current + size]
|
|
12
12
|
if len(read_bytes) < size:
|
|
13
13
|
raise ValueError(f"Failed to read requested number of bytes: {size}")
|
|
14
|
-
return (self.address
|
|
14
|
+
return (self.address, read_bytes), self.new_reader(self.address + size)
|
|
15
15
|
|
|
16
16
|
def new_reader(self, address: int) -> Reader:
|
|
17
17
|
delta = address - self.address
|
|
@@ -35,7 +35,7 @@ class DataDefinition(ABC):
|
|
|
35
35
|
|
|
36
36
|
def __init__(
|
|
37
37
|
self,
|
|
38
|
-
metadata:
|
|
38
|
+
metadata: Metadata,
|
|
39
39
|
):
|
|
40
40
|
self.metadata = metadata
|
|
41
41
|
|
|
@@ -60,9 +60,8 @@ class IntDefinition(DataDefinition):
|
|
|
60
60
|
def __init__(
|
|
61
61
|
self,
|
|
62
62
|
value: int | Enum,
|
|
63
|
-
metadata:
|
|
63
|
+
metadata: Metadata = None,
|
|
64
64
|
):
|
|
65
|
-
|
|
66
65
|
super().__init__(metadata)
|
|
67
66
|
if isinstance(value, int):
|
|
68
67
|
self.value = value
|
|
@@ -74,7 +73,13 @@ class IntDefinition(DataDefinition):
|
|
|
74
73
|
@classmethod
|
|
75
74
|
def parser(cls, reader: Reader) -> Tuple[IntDefinition, Reader]:
|
|
76
75
|
(address, data_bytes), new_reader = reader.read(cls.size)
|
|
77
|
-
return
|
|
76
|
+
return (
|
|
77
|
+
cls(
|
|
78
|
+
int.from_bytes(data_bytes, byteorder=cls.byteorder),
|
|
79
|
+
metadata=Metadata(address),
|
|
80
|
+
),
|
|
81
|
+
new_reader,
|
|
82
|
+
)
|
|
78
83
|
|
|
79
84
|
def __repr__(self) -> str:
|
|
80
85
|
cls_name = type(self).__name__
|
|
@@ -96,9 +101,13 @@ class IntDefinition(DataDefinition):
|
|
|
96
101
|
enum_type = self._enum_type
|
|
97
102
|
if enum_type:
|
|
98
103
|
try:
|
|
99
|
-
val_str = repr(
|
|
104
|
+
val_str = repr(
|
|
105
|
+
enum_type(val)
|
|
106
|
+
) # repr(Enum(<num>)) looks more like str(Enum(<num>)) and vice versa
|
|
100
107
|
except ValueError:
|
|
101
|
-
val_str =
|
|
108
|
+
val_str = (
|
|
109
|
+
f"{val:#x} ({val}) not a valid Enumeration of type: {enum_type}"
|
|
110
|
+
)
|
|
102
111
|
else:
|
|
103
112
|
val_str = hex(val)
|
|
104
113
|
|
|
@@ -137,26 +146,32 @@ class StructDefinition(DataDefinition):
|
|
|
137
146
|
def __init__(
|
|
138
147
|
self,
|
|
139
148
|
fields: Sequence[DataDefinition],
|
|
140
|
-
metadata:
|
|
149
|
+
metadata: Metadata,
|
|
141
150
|
):
|
|
142
151
|
super().__init__(metadata)
|
|
143
152
|
self.fields = tuple(fields)
|
|
144
153
|
fields_len = len(fields)
|
|
145
154
|
field_types_len = len(self.field_types)
|
|
146
155
|
if fields_len != field_types_len:
|
|
147
|
-
raise ValueError(
|
|
156
|
+
raise ValueError(
|
|
157
|
+
f"Supplied number of fields: {fields_len} doesn't match expectation: {field_types_len}"
|
|
158
|
+
)
|
|
148
159
|
for (k, t), v in zip(self.field_types.items(), fields):
|
|
149
160
|
if not isinstance(v, t):
|
|
150
|
-
raise ValueError(f"Got unexpected value: {v} for type: {t}")
|
|
161
|
+
raise ValueError(f"Got unexpected value: {v} for type: {t!r}")
|
|
151
162
|
setattr(self, k, v)
|
|
152
163
|
|
|
153
164
|
def __str__(self) -> str:
|
|
154
165
|
cls_name = type(self).__name__
|
|
155
166
|
|
|
156
|
-
fields_strs = map(
|
|
167
|
+
fields_strs = map(
|
|
168
|
+
lambda k, v: f"{k}: {v}", self.field_types.keys(), map(str, self.fields)
|
|
169
|
+
)
|
|
157
170
|
fields_strs_indented = map(indent_4, fields_strs)
|
|
158
171
|
fields_str = "\n".join(fields_strs_indented)
|
|
159
|
-
return
|
|
172
|
+
return (
|
|
173
|
+
f"{cls_name} (size: {self.size}) {self.add_metadata_repr()}:\n{fields_str}"
|
|
174
|
+
)
|
|
160
175
|
|
|
161
176
|
@classmethod
|
|
162
177
|
def parser(cls, reader: Reader) -> Tuple[StructDefinition, Reader]:
|
|
@@ -187,18 +202,23 @@ def create_struct_definition(
|
|
|
187
202
|
struct_name: str,
|
|
188
203
|
field_types: Dict[str, Type[DataDefinition] | ForwardPointer],
|
|
189
204
|
) -> Type[StructDefinition]:
|
|
190
|
-
|
|
191
205
|
new_struct = type(
|
|
192
206
|
struct_name,
|
|
193
207
|
(StructDefinition,),
|
|
194
208
|
{},
|
|
195
209
|
)
|
|
196
210
|
|
|
197
|
-
normalized_field_types = {
|
|
198
|
-
|
|
211
|
+
normalized_field_types = {
|
|
212
|
+
k: replace_forward_pointer(new_struct, v) for (k, v) in field_types.items()
|
|
213
|
+
}
|
|
214
|
+
sequence_parser = create_sequence_parser(
|
|
215
|
+
*map(get_parser, normalized_field_types.values())
|
|
216
|
+
)
|
|
199
217
|
|
|
200
218
|
@classmethod
|
|
201
|
-
def parser(
|
|
219
|
+
def parser(
|
|
220
|
+
cls: Type[StructDefinition], reader: Reader
|
|
221
|
+
) -> Tuple[StructDefinition, Reader]:
|
|
202
222
|
parsed_field_results, new_reader = sequence_parser(reader)
|
|
203
223
|
metadata = Metadata(parsed_field_results[0].metadata.address)
|
|
204
224
|
return cls(parsed_field_results, metadata=metadata), new_reader
|
|
@@ -220,7 +240,9 @@ class BitFieldDefinition:
|
|
|
220
240
|
value: int,
|
|
221
241
|
):
|
|
222
242
|
if value > self.mask:
|
|
223
|
-
raise ValueError(
|
|
243
|
+
raise ValueError(
|
|
244
|
+
f"Passed in value: {value:#x} greater than mask: {self.mask:#x}"
|
|
245
|
+
)
|
|
224
246
|
self.value = value
|
|
225
247
|
|
|
226
248
|
def __repr__(self):
|
|
@@ -244,7 +266,7 @@ class BitFieldsDefinition(DataDefinition):
|
|
|
244
266
|
def __init__(
|
|
245
267
|
self,
|
|
246
268
|
value: int,
|
|
247
|
-
metadata:
|
|
269
|
+
metadata: Metadata,
|
|
248
270
|
):
|
|
249
271
|
super().__init__(metadata)
|
|
250
272
|
self.value = value
|
|
@@ -253,7 +275,9 @@ class BitFieldsDefinition(DataDefinition):
|
|
|
253
275
|
field_types_len = len(self.field_types)
|
|
254
276
|
|
|
255
277
|
if fields_len != field_types_len:
|
|
256
|
-
raise ValueError(
|
|
278
|
+
raise ValueError(
|
|
279
|
+
f"Supplied number of fields: {fields_len} doesn't match expectation: {field_types_len}"
|
|
280
|
+
)
|
|
257
281
|
for (k, t), v in zip(self.field_types.items(), self.fields):
|
|
258
282
|
if not isinstance(v, t):
|
|
259
283
|
raise ValueError(f"Got unexpected value: {v} for type: {t}")
|
|
@@ -286,7 +310,9 @@ BitFieldDef = Tuple[str, int]
|
|
|
286
310
|
BitFieldDefs = Dict[str, int]
|
|
287
311
|
|
|
288
312
|
|
|
289
|
-
def _create_bit_field_definition_from_bit_field_def(
|
|
313
|
+
def _create_bit_field_definition_from_bit_field_def(
|
|
314
|
+
position: int, bf_def: BitFieldDef
|
|
315
|
+
) -> Type[BitFieldDefinition]:
|
|
290
316
|
name, size = bf_def
|
|
291
317
|
bit_field_definition = type(
|
|
292
318
|
name,
|
|
@@ -304,7 +330,9 @@ def _create_bit_field_definition_from_bit_field_def(position: int, bf_def: BitFi
|
|
|
304
330
|
PosFieldsTup = Tuple[int, Tuple[Type[BitFieldDefinition], ...]]
|
|
305
331
|
|
|
306
332
|
|
|
307
|
-
def _create_fields_reducer(
|
|
333
|
+
def _create_fields_reducer(
|
|
334
|
+
pos_fields_tup: PosFieldsTup, field_def: BitFieldDef
|
|
335
|
+
) -> PosFieldsTup:
|
|
308
336
|
pos, fields = pos_fields_tup
|
|
309
337
|
name, size = field_def
|
|
310
338
|
new_field = _create_bit_field_definition_from_bit_field_def(pos, field_def)
|
|
@@ -340,7 +368,7 @@ class PointerDefinition(DataDefinition):
|
|
|
340
368
|
def __init__(
|
|
341
369
|
self,
|
|
342
370
|
address: int,
|
|
343
|
-
metadata:
|
|
371
|
+
metadata: Metadata,
|
|
344
372
|
):
|
|
345
373
|
super().__init__(metadata)
|
|
346
374
|
self.address = address
|
|
@@ -379,7 +407,7 @@ def create_pointer_definition(
|
|
|
379
407
|
{
|
|
380
408
|
"target_type": target_type,
|
|
381
409
|
"address_type": address_type,
|
|
382
|
-
"size":
|
|
410
|
+
"size": address_type.size,
|
|
383
411
|
},
|
|
384
412
|
)
|
|
385
413
|
|
|
@@ -397,13 +425,14 @@ def _create_pointer_definition_from_forward_pointer(
|
|
|
397
425
|
class ArrayDefinition(DataDefinition):
|
|
398
426
|
target_type: Type[DataDefinition]
|
|
399
427
|
size: int
|
|
428
|
+
num_elems: int
|
|
400
429
|
_fields_parser: Parser
|
|
401
430
|
_array_splitter = "\n" + 80 * "=" + "\n"
|
|
402
431
|
|
|
403
432
|
def __init__(
|
|
404
433
|
self,
|
|
405
434
|
fields: Sequence[DataDefinition],
|
|
406
|
-
metadata:
|
|
435
|
+
metadata: Metadata,
|
|
407
436
|
):
|
|
408
437
|
super().__init__(metadata)
|
|
409
438
|
self.fields = fields
|
|
@@ -414,7 +443,7 @@ class ArrayDefinition(DataDefinition):
|
|
|
414
443
|
fields_strs = map(str, self.fields)
|
|
415
444
|
fields_strs_indented = map(indent_4, fields_strs)
|
|
416
445
|
fields_str = self._array_splitter.join(fields_strs_indented)
|
|
417
|
-
return f"{cls_name}:: {target_cls}[{self.
|
|
446
|
+
return f"{cls_name}:: {target_cls}[{self.num_elems}] {self.add_metadata_repr()}:\n{fields_str}"
|
|
418
447
|
|
|
419
448
|
@classmethod
|
|
420
449
|
def parser(cls, reader: Reader) -> Tuple[ArrayDefinition, Reader]:
|
|
@@ -427,16 +456,18 @@ class ArrayDefinition(DataDefinition):
|
|
|
427
456
|
|
|
428
457
|
|
|
429
458
|
def create_array_definition(
|
|
459
|
+
name: str,
|
|
430
460
|
target_type: Type[DataDefinition],
|
|
431
|
-
|
|
461
|
+
num_elems: int,
|
|
432
462
|
) -> Type[ArrayDefinition]:
|
|
433
|
-
fields_parser = create_repeat_parser(
|
|
463
|
+
fields_parser = create_repeat_parser(num_elems, target_type.parser)
|
|
434
464
|
return type(
|
|
435
|
-
|
|
465
|
+
name,
|
|
436
466
|
(ArrayDefinition,),
|
|
437
467
|
{
|
|
438
468
|
"target_type": target_type,
|
|
439
|
-
"
|
|
469
|
+
"num_elems": num_elems,
|
|
470
|
+
"size": target_type.size * num_elems,
|
|
440
471
|
"_fields_parser": fields_parser,
|
|
441
472
|
},
|
|
442
473
|
)
|
{c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/reader_abc.py
RENAMED
|
@@ -8,7 +8,6 @@ AddressData = Tuple[int, bytes | memoryview]
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class Reader(ABC):
|
|
11
|
-
|
|
12
11
|
def __init__(self, address: int, offset: int = 0):
|
|
13
12
|
self.address = address
|
|
14
13
|
self.offset = offset
|
|
@@ -24,5 +23,8 @@ class Reader(ABC):
|
|
|
24
23
|
def new_reader(self, address: int) -> Reader:
|
|
25
24
|
return type(self)(address)
|
|
26
25
|
|
|
26
|
+
def __repr__(self) -> str:
|
|
27
|
+
return f"{type(self).__name__}({self.address:#x})"
|
|
28
|
+
|
|
27
29
|
|
|
28
30
|
ReaderData = Tuple[AddressData, Reader]
|
|
File without changes
|
{c_struct_data_parser-0.2.0 → c_struct_data_parser-0.4.0}/src/c_struct_data_parser/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|