Skip to content

Commit 0583275

Browse files
committed
Add the default() method back in (#55)
1 parent 3339b43 commit 0583275

File tree

5 files changed

+111
-90
lines changed

5 files changed

+111
-90
lines changed

dissect/cstruct/types/base.py

+7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ def __len__(cls) -> int:
5454

5555
return cls.size
5656

57+
def default(cls) -> BaseType:
58+
"""Return the default value of this type."""
59+
return cls()
60+
5761
def reads(cls, data: bytes) -> BaseType:
5862
"""Parse the given data from a bytes-like object.
5963
@@ -196,6 +200,9 @@ def _read(cls, stream: BinaryIO, context: dict[str, Any] = None) -> Array:
196200

197201
return cls.type._read_array(stream, num, context)
198202

203+
def default(cls) -> BaseType:
204+
return [cls.type.default() for _ in range(0 if cls.dynamic or cls.null_terminated else cls.num_entries)]
205+
199206

200207
class Array(list, BaseType, metaclass=ArrayMetaType):
201208
"""Implements a fixed or dynamically sized array type.

dissect/cstruct/types/char.py

+8
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ def _write(cls, stream: BinaryIO, data: Union[bytes, int, str]) -> int:
4848

4949
return stream.write(data)
5050

51+
@classmethod
52+
def default(cls) -> Char:
53+
return type.__call__(cls, b"\x00")
54+
5155

5256
class CharArray(bytes, BaseType, metaclass=ArrayMetaType):
5357
"""Character array type for reading and writing byte strings."""
@@ -67,3 +71,7 @@ def _write(cls, stream: BinaryIO, data: bytes) -> int:
6771
if cls.null_terminated:
6872
return stream.write(data + b"\x00")
6973
return stream.write(data)
74+
75+
@classmethod
76+
def default(cls) -> CharArray:
77+
return type.__call__(cls, b"\x00" * (0 if cls.dynamic or cls.null_terminated else cls.num_entries))

dissect/cstruct/types/structure.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def __call__(cls, *args, **kwargs) -> Structure:
6363
# Shortcut for single char/bytes type
6464
return type.__call__(cls, *args, **kwargs)
6565
elif not args and not kwargs:
66-
obj = cls(**{field.name: field.type() for field in cls.__fields__})
66+
obj = cls(**{field.name: field.type.default() for field in cls.__fields__})
6767
object.__setattr__(obj, "_values", {})
6868
object.__setattr__(obj, "_sizes", {})
6969
return obj

dissect/cstruct/types/wchar.py

+8
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ def _read_0(cls, stream: BinaryIO, context: dict[str, Any] = None) -> Wchar:
5454
def _write(cls, stream: BinaryIO, data: str) -> int:
5555
return stream.write(data.encode(cls.__encoding_map__[cls.cs.endian]))
5656

57+
@classmethod
58+
def default(cls) -> Wchar:
59+
return type.__call__(cls, "\x00")
60+
5761

5862
class WcharArray(str, BaseType, metaclass=ArrayMetaType):
5963
"""Wide-character array type for reading and writing UTF-16 strings."""
@@ -67,3 +71,7 @@ def _write(cls, stream: BinaryIO, data: str) -> int:
6771
if cls.null_terminated:
6872
data += "\x00"
6973
return stream.write(data.encode(Wchar.__encoding_map__[cls.cs.endian]))
74+
75+
@classmethod
76+
def default(cls) -> WcharArray:
77+
return type.__call__(cls, "\x00" * (0 if cls.dynamic or cls.null_terminated else cls.num_entries))

tests/test_basic.py

+87-89
Original file line numberDiff line numberDiff line change
@@ -107,95 +107,93 @@ def test_lookups(cs: cstruct, compiled: bool):
107107
assert cs.lookups["a"] == {1: 3, 2: 4}
108108

109109

110-
# TODO:
111-
# def test_default_constructors(cs: cstruct, compiled: bool):
112-
# cdef = """
113-
# enum Enum {
114-
# a = 0,
115-
# b = 1
116-
# };
117-
118-
# flag Flag {
119-
# a = 0,
120-
# b = 1
121-
# };
122-
123-
# struct test {
124-
# uint32 t_int;
125-
# uint32 t_int_array[2];
126-
# uint24 t_bytesint;
127-
# uint24 t_bytesint_array[2];
128-
# char t_char;
129-
# char t_char_array[2];
130-
# wchar t_wchar;
131-
# wchar t_wchar_array[2];
132-
# Enum t_enum;
133-
# Enum t_enum_array[2];
134-
# Flag t_flag;
135-
# Flag t_flag_array[2];
136-
# };
137-
# """
138-
# cs.load(cdef, compiled=compiled)
139-
140-
# assert verify_compiled(cs.test, compiled)
141-
142-
# obj = cs.test()
143-
# assert obj.t_int == 0
144-
# assert obj.t_int_array == [0, 0]
145-
# assert obj.t_bytesint == 0
146-
# assert obj.t_bytesint_array == [0, 0]
147-
# assert obj.t_char == b"\x00"
148-
# assert obj.t_char_array == b"\x00\x00"
149-
# assert obj.t_wchar == "\x00"
150-
# assert obj.t_wchar_array == "\x00\x00"
151-
# assert obj.t_enum == cs.Enum(0)
152-
# assert obj.t_enum_array == [cs.Enum(0), cs.Enum(0)]
153-
# assert obj.t_flag == cs.Flag(0)
154-
# assert obj.t_flag_array == [cs.Flag(0), cs.Flag(0)]
155-
156-
# assert obj.dumps() == b"\x00" * 54
157-
158-
159-
# TODO:
160-
# def test_default_constructors_dynamic(cs: cstruct, compiled: bool):
161-
# cdef = """
162-
# enum Enum {
163-
# a = 0,
164-
# b = 1
165-
# };
166-
# flag Flag {
167-
# a = 0,
168-
# b = 1
169-
# };
170-
# struct test {
171-
# uint8 x;
172-
# uint32 t_int_array_n[];
173-
# uint32 t_int_array_d[x];
174-
# uint24 t_bytesint_array_n[];
175-
# uint24 t_bytesint_array_d[x];
176-
# char t_char_array_n[];
177-
# char t_char_array_d[x];
178-
# wchar t_wchar_array_n[];
179-
# wchar t_wchar_array_d[x];
180-
# Enum t_enum_array_n[];
181-
# Enum t_enum_array_d[x];
182-
# Flag t_flag_array_n[];
183-
# Flag t_flag_array_d[x];
184-
# };
185-
# """
186-
# cs.load(cdef, compiled=compiled)
187-
188-
# assert verify_compiled(cs.test, compiled)
189-
190-
# obj = cs.test()
191-
192-
# assert obj.t_int_array_n == obj.t_int_array_d == []
193-
# assert obj.t_bytesint_array_n == obj.t_bytesint_array_d == []
194-
# assert obj.t_char_array_n == obj.t_char_array_d == b""
195-
# assert obj.t_wchar_array_n == obj.t_wchar_array_d == ""
196-
# assert obj.t_enum_array_n == obj.t_enum_array_d == []
197-
# assert obj.t_flag_array_n == obj.t_flag_array_d == []
198-
# assert obj.dumps() == b"\x00" * 19
110+
def test_default_constructors(cs: cstruct, compiled: bool):
111+
cdef = """
112+
enum Enum {
113+
a = 0,
114+
b = 1
115+
};
116+
117+
flag Flag {
118+
a = 0,
119+
b = 1
120+
};
121+
122+
struct test {
123+
uint32 t_int;
124+
uint32 t_int_array[2];
125+
uint24 t_bytesint;
126+
uint24 t_bytesint_array[2];
127+
char t_char;
128+
char t_char_array[2];
129+
wchar t_wchar;
130+
wchar t_wchar_array[2];
131+
Enum t_enum;
132+
Enum t_enum_array[2];
133+
Flag t_flag;
134+
Flag t_flag_array[2];
135+
};
136+
"""
137+
cs.load(cdef, compiled=compiled)
138+
139+
assert verify_compiled(cs.test, compiled)
140+
141+
obj = cs.test()
142+
assert obj.t_int == 0
143+
assert obj.t_int_array == [0, 0]
144+
assert obj.t_bytesint == 0
145+
assert obj.t_bytesint_array == [0, 0]
146+
assert obj.t_char == b"\x00"
147+
assert obj.t_char_array == b"\x00\x00"
148+
assert obj.t_wchar == "\x00"
149+
assert obj.t_wchar_array == "\x00\x00"
150+
assert obj.t_enum == cs.Enum(0)
151+
assert obj.t_enum_array == [cs.Enum(0), cs.Enum(0)]
152+
assert obj.t_flag == cs.Flag(0)
153+
assert obj.t_flag_array == [cs.Flag(0), cs.Flag(0)]
154+
155+
assert obj.dumps() == b"\x00" * 54
156+
157+
158+
def test_default_constructors_dynamic(cs: cstruct, compiled: bool):
159+
cdef = """
160+
enum Enum {
161+
a = 0,
162+
b = 1
163+
};
164+
flag Flag {
165+
a = 0,
166+
b = 1
167+
};
168+
struct test {
169+
uint8 x;
170+
uint32 t_int_array_n[];
171+
uint32 t_int_array_d[x];
172+
uint24 t_bytesint_array_n[];
173+
uint24 t_bytesint_array_d[x];
174+
char t_char_array_n[];
175+
char t_char_array_d[x];
176+
wchar t_wchar_array_n[];
177+
wchar t_wchar_array_d[x];
178+
Enum t_enum_array_n[];
179+
Enum t_enum_array_d[x];
180+
Flag t_flag_array_n[];
181+
Flag t_flag_array_d[x];
182+
};
183+
"""
184+
cs.load(cdef, compiled=compiled)
185+
186+
assert verify_compiled(cs.test, compiled)
187+
188+
obj = cs.test()
189+
190+
assert obj.t_int_array_n == obj.t_int_array_d == []
191+
assert obj.t_bytesint_array_n == obj.t_bytesint_array_d == []
192+
assert obj.t_char_array_n == obj.t_char_array_d == b""
193+
assert obj.t_wchar_array_n == obj.t_wchar_array_d == ""
194+
assert obj.t_enum_array_n == obj.t_enum_array_d == []
195+
assert obj.t_flag_array_n == obj.t_flag_array_d == []
196+
assert obj.dumps() == b"\x00" * 19
199197

200198

201199
def test_config_flag_nocompile(cs: cstruct, compiled: bool):

0 commit comments

Comments
 (0)