Skip to content

Commit 28f10e0

Browse files
committed
This allow user to properly check datatype of Enums or Structures.
Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
1 parent d309469 commit 28f10e0

File tree

2 files changed

+49
-43
lines changed

2 files changed

+49
-43
lines changed

dissect/cstruct/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
Parser,
1111
RawType,
1212
BaseType,
13+
StructureType,
14+
EnumType,
15+
ArrayType,
1316
Error,
1417
ParserError,
1518
CompilerError,
@@ -29,6 +32,9 @@
2932
"Parser",
3033
"RawType",
3134
"BaseType",
35+
"StructureType",
36+
"EnumType",
37+
"ArrayType",
3238
"Error",
3339
"ParserError",
3440
"CompilerError",

dissect/cstruct/cstruct.py

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
PRINTABLE = string.digits + string.ascii_letters + string.punctuation + " "
6767

6868
COMPILE_TEMPL = """
69-
class {name}(Structure):
69+
class {name}(StructureType):
7070
def __init__(self, cstruct, structure, source=None):
7171
self.structure = structure
7272
self.source = source
@@ -85,7 +85,7 @@ def add_fields(self, name, type_, offset=None, commentAttributes={{}}):
8585
raise NotImplementedError("Can't add fields to a compiled structure")
8686
8787
def __repr__(self):
88-
return '<Structure {name} +compiled>'
88+
return '<StructureType {name} +compiled>'
8989
"""
9090

9191
COMMENT_MULTILINE = r'/\*[^*]*\*+(?:[^/*][^*]*\*+)*/'
@@ -354,7 +354,7 @@ def _enums(self, data):
354354

355355
commentAttributes = self.parse_comment_block(d['commentBlock'])
356356

357-
enum = Enum(
357+
enum = EnumType(
358358
self.cstruct, d['name'], self.cstruct.resolve(d['type']), values, valuesDetails, commentAttributes
359359
)
360360
self.cstruct.addtype(enum.name, enum)
@@ -407,7 +407,7 @@ def _structs(self, data):
407407
if d['type'] == 'struct':
408408
data = self._parse_fields_struct(d['fields'][1:-1].strip())
409409
commentAttributes = self.parse_comment_block(d['commentBlock'])
410-
st = Structure(self.cstruct, name, data, commentAttributes)
410+
st = StructureType(self.cstruct, name, data, commentAttributes)
411411
if d['flags'] == 'compile' or self.compiled:
412412
st = compiler.compile(st)
413413
elif d['typedef'] == 'typedef':
@@ -452,7 +452,7 @@ def _parse_fields_struct(self, s):
452452
except Exception:
453453
pass
454454

455-
type_ = Array(self.cstruct, type_, count)
455+
type_ = ArrayType(self.cstruct, type_, count)
456456

457457
if d['name'].startswith('*'):
458458
d['name'] = d['name'][1:]
@@ -586,7 +586,7 @@ def _get(self):
586586
if self._value is None:
587587
pos = self._stream.tell()
588588
self._stream.seek(self._addr)
589-
if isinstance(self._type, Array):
589+
if isinstance(self._type, ArrayType):
590590
r = self._type._read(self._stream, self._ctx)
591591
else:
592592
r = self._type._read(self._stream)
@@ -761,7 +761,7 @@ def default_array(self):
761761
raise NotImplementedError()
762762

763763
def __getitem__(self, count):
764-
return Array(self.cstruct, self, count)
764+
return ArrayType(self.cstruct, self, count)
765765

766766
def __call__(self, *args, **kwargs):
767767
if len(args) > 0:
@@ -793,7 +793,7 @@ def __repr__(self):
793793
return BaseType.__repr__(self)
794794

795795

796-
class Structure(BaseType):
796+
class StructureType(BaseType):
797797
"""Type class for structures."""
798798

799799
def __init__(self, cstruct, name, fields=None, commentAttributes={}):
@@ -808,7 +808,7 @@ def __init__(self, cstruct, name, fields=None, commentAttributes={}):
808808
self.lookup[f.name] = f
809809

810810
self._calc_offsets()
811-
super(Structure, self).__init__(cstruct)
811+
super(StructureType, self).__init__(cstruct)
812812

813813
def _calc_offsets(self):
814814
offset = 0
@@ -860,7 +860,7 @@ def _calc_size(self):
860860
return size
861861

862862
def _read(self, stream, *args, **kwargs):
863-
log("[Structure::read] {} {}", self.name, self.size)
863+
log("[StructureType::read] {} {}", self.name, self.size)
864864
bitbuffer = BitBuffer(stream, self.cstruct.endian)
865865

866866
struct_start = stream.tell()
@@ -887,7 +887,7 @@ def _read(self, stream, *args, **kwargs):
887887
else:
888888
bitbuffer.reset()
889889

890-
if isinstance(ft, (Array, Pointer)):
890+
if isinstance(ft, (ArrayType, Pointer)):
891891
v = ft._read(stream, r)
892892
else:
893893
v = ft._read(stream)
@@ -950,7 +950,7 @@ def __len__(self):
950950
return self.size
951951

952952
def __repr__(self):
953-
return '<Structure {}>'.format(self.name)
953+
return '<StructureType {}>'.format(self.name)
954954

955955
def show(self, indent=0):
956956
"""Pretty print this structure."""
@@ -965,7 +965,7 @@ def show(self, indent=0):
965965

966966
print("{}+{} {} {}".format(' ' * indent, offset, field.name, field.type))
967967

968-
if isinstance(field.type, Structure):
968+
if isinstance(field.type, StructureType):
969969
field.type.show(indent + 1)
970970

971971

@@ -1037,7 +1037,7 @@ def __repr__(self):
10371037
return '<Field {} {} {}>'.format(self.name, self.type, self.commentAttributes)
10381038

10391039

1040-
class Array(BaseType):
1040+
class ArrayType(BaseType):
10411041
"""Implements a fixed or dynamically sized array type.
10421042
10431043
Example:
@@ -1053,7 +1053,7 @@ def __init__(self, cstruct, type_, count):
10531053
self.count = count
10541054
self.dynamic = isinstance(self.count, Expression) or self.count is None
10551055

1056-
super(Array, self).__init__(cstruct)
1056+
super(ArrayType, self).__init__(cstruct)
10571057

10581058
def _read(self, stream, context=None):
10591059
if self.count is None:
@@ -1332,10 +1332,10 @@ def default_array(self, count):
13321332
return [0] * count
13331333

13341334

1335-
class Enum(RawType):
1336-
"""Implements an Enum type.
1335+
class EnumType(RawType):
1336+
"""Implements an EnumType type.
13371337
1338-
Enums can be made using any type. The API for accessing enums and their
1338+
EnumTypes can be made using any type. The API for accessing enums and their
13391339
values is very similar to Python 3 native enums.
13401340
13411341
Example:
@@ -1362,7 +1362,7 @@ def __init__(self, cstruct, name, type_, values, valuesDetails, commentAttribute
13621362
for k, v in values.items():
13631363
self.reverse[v] = k
13641364

1365-
super(Enum, self).__init__(cstruct, name, len(self.type))
1365+
super(EnumType, self).__init__(cstruct, name, len(self.type))
13661366

13671367
def __call__(self, value):
13681368
return EnumInstance(self, value)
@@ -1408,11 +1408,11 @@ def __contains__(self, attr):
14081408
return attr in self.values
14091409

14101410
def __repr__(self):
1411-
return '<Enum {}>'.format(self.name)
1411+
return '<EnumType {}>'.format(self.name)
14121412

14131413

14141414
class EnumInstance(object):
1415-
"""Implements a value instance of an Enum"""
1415+
"""Implements a value instance of an EnumType"""
14161416

14171417
def __init__(self, enum, value):
14181418
self.enum = enum
@@ -1494,7 +1494,7 @@ def ctypes(structure):
14941494
t = ctypes_type(field.type)
14951495
fields.append((field.name, t))
14961496

1497-
tt = type(structure.name, (_ctypes.Structure, ), {"_fields_": fields})
1497+
tt = type(structure.name, (_ctypes.StructureType, ), {"_fields_": fields})
14981498
return tt
14991499

15001500

@@ -1511,7 +1511,7 @@ def ctypes_type(t):
15111511
if isinstance(t, CharType):
15121512
return _ctypes.c_char
15131513

1514-
if isinstance(t, Array):
1514+
if isinstance(t, ArrayType):
15151515
subtype = ctypes_type(t._type)
15161516
return subtype * t.count
15171517

@@ -1534,7 +1534,7 @@ def compile(self, structure):
15341534

15351535
env = {
15361536
'OrderedDict': OrderedDict,
1537-
'Structure': Structure,
1537+
'StructureType': StructureType,
15381538
'Instance': Instance,
15391539
'Expression': Expression,
15401540
'EnumInstance': EnumInstance,
@@ -1563,10 +1563,10 @@ def gen_struct_class(self, structure):
15631563
if not isinstance(
15641564
ft,
15651565
(
1566-
Structure,
1566+
StructureType,
15671567
Pointer,
1568-
Enum,
1569-
Array,
1568+
EnumType,
1569+
ArrayType,
15701570
PackedType,
15711571
CharType,
15721572
WcharType,
@@ -1575,14 +1575,14 @@ def gen_struct_class(self, structure):
15751575
):
15761576
raise CompilerError("Unsupported type for compiler: {}".format(ft))
15771577

1578-
if isinstance(ft, Structure) or (
1579-
isinstance(ft, Array) and isinstance(ft.type, Structure)
1578+
if isinstance(ft, StructureType) or (
1579+
isinstance(ft, ArrayType) and isinstance(ft.type, StructureType)
15801580
):
15811581
if cur_block:
15821582
blocks.append(self.gen_read_block(read_size, cur_block))
15831583

15841584
struct_read = 's = stream.tell()\n'
1585-
if isinstance(ft, Array):
1585+
if isinstance(ft, ArrayType):
15861586
num = ft.count
15871587

15881588
if isinstance(num, Expression):
@@ -1686,17 +1686,17 @@ def gen_read_block(self, size, block):
16861686
data_count = 1
16871687
read_slice = ''
16881688

1689-
if isinstance(t, Enum):
1689+
if isinstance(t, EnumType):
16901690
t = t.type
16911691
elif isinstance(t, Pointer):
16921692
t = self.cstruct.pointer
16931693

1694-
if isinstance(ft, Array):
1694+
if isinstance(ft, ArrayType):
16951695
count = t.count
16961696
data_count = count
16971697
t = t.type
16981698

1699-
if isinstance(t, Enum):
1699+
if isinstance(t, EnumType):
17001700
t = t.type
17011701
elif isinstance(t, Pointer):
17021702
t = self.cstruct.pointer
@@ -1720,7 +1720,7 @@ def gen_read_block(self, size, block):
17201720
else:
17211721
curtype = 'x'
17221722

1723-
if isinstance(t, (PackedType, CharType, WcharType, BytesInteger, Enum)):
1723+
if isinstance(t, (PackedType, CharType, WcharType, BytesInteger, EnumType)):
17241724
charcount = count
17251725

17261726
if isinstance(t, (CharType, WcharType, BytesInteger)):
@@ -1753,23 +1753,23 @@ def gen_read_block(self, size, block):
17531753
else:
17541754
getter = 'data[{}]'.format(read_slice)
17551755

1756-
if isinstance(ft, Enum):
1756+
if isinstance(ft, EnumType):
17571757
getter = 'EnumInstance(self.cstruct.{type_name}, {getter})'.format(
17581758
type_name=ft.name, getter=getter
17591759
)
1760-
elif isinstance(ft, Array) and isinstance(ft.type, Enum):
1760+
elif isinstance(ft, ArrayType) and isinstance(ft.type, EnumType):
17611761
getter = '[EnumInstance(self.cstruct.{type_name}, d) for d in {getter}]'.format(
17621762
type_name=ft.type.name, getter=getter
17631763
)
17641764
elif isinstance(ft, Pointer):
17651765
getter = 'PointerInstance(self.cstruct.{type_name}, stream, {getter}, r)'.format(
17661766
type_name=ft.type.name, getter=getter
17671767
)
1768-
elif isinstance(ft, Array) and isinstance(ft.type, Pointer):
1768+
elif isinstance(ft, ArrayType) and isinstance(ft.type, Pointer):
17691769
getter = '[PointerInstance(self.cstruct.{type_name}, stream, d, r) for d in {getter}]'.format(
17701770
type_name=ft.type.name, getter=getter
17711771
)
1772-
elif isinstance(ft, Array) and isinstance(t, PackedType):
1772+
elif isinstance(ft, ArrayType) and isinstance(t, PackedType):
17731773
getter = 'list({})'.format(getter)
17741774

17751775
readcode.append(
@@ -1788,9 +1788,9 @@ def gen_read_block(self, size, block):
17881788
return templ.format(''.join(fmt), '\n'.join(readcode))
17891789

17901790
def gen_dynamic_block(self, field):
1791-
if not isinstance(field.type, Array):
1791+
if not isinstance(field.type, ArrayType):
17921792
raise CompilerError(
1793-
"Only Array can be dynamic, got {!r}".format(field.type)
1793+
"Only ArrayType can be dynamic, got {!r}".format(field.type)
17941794
)
17951795

17961796
t = field.type.type
@@ -1928,8 +1928,8 @@ def dumpstruct(t, data=None, offset=0):
19281928
Prints a colorized hexdump and parsed structure output.
19291929
19301930
Args:
1931-
t: Structure or Instance to dump.
1932-
data: Bytes to parse the Structure on, if t is not a parsed Instance.
1931+
t: StructureType or Instance to dump.
1932+
data: Bytes to parse the StructureType on, if t is not a parsed Instance.
19331933
offset: Byte offset of the hexdump.
19341934
"""
19351935
colors = [
@@ -1946,7 +1946,7 @@ def dumpstruct(t, data=None, offset=0):
19461946
g = t
19471947
t = t._type
19481948
data = g.dumps()
1949-
elif isinstance(t, Structure) and data:
1949+
elif isinstance(t, StructureType) and data:
19501950
g = t(data)
19511951
else:
19521952
raise ValueError("Invalid arguments")

0 commit comments

Comments
 (0)