Skip to content

Commit

Permalink
Add support for real-time updating of union values
Browse files Browse the repository at this point in the history
  • Loading branch information
Schamper committed Oct 29, 2023
1 parent 82df7ca commit 961fc80
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 66 deletions.
20 changes: 6 additions & 14 deletions dissect/cstruct/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def compile(self, structure: type[Structure]) -> type[Structure]:
return structure

try:
structure._read = self.compile_read(structure.fields, structure.__name__, structure.align)
structure._read = self.compile_read(structure.fields, structure.__name__, structure.__align__)
structure.__compiled__ = True
except Exception as e:
# Silently ignore, we didn't compile unfortunately
Expand Down Expand Up @@ -218,19 +218,11 @@ def align_to_field(field: Field) -> Iterator[str]:
yield f"stream.seek(-stream.tell() & (cls.alignment - 1), {io.SEEK_CUR})"

def _generate_structure(self, field: Field) -> Iterator[str]:
if field.type.anonymous:
template = f"""
_s = stream.tell()
_v = {self._map_field(field)}._read(stream, context=r)
r.update(_v._values)
s.update(_v._sizes)
"""
else:
template = f"""
_s = stream.tell()
r["{field.name}"] = {self._map_field(field)}._read(stream, context=r)
s["{field.name}"] = stream.tell() - _s
"""
template = f"""
_s = stream.tell()
r["{field.name}"] = {self._map_field(field)}._read(stream, context=r)
s["{field.name}"] = stream.tell() - _s
"""

yield dedent(template)

Expand Down
6 changes: 3 additions & 3 deletions dissect/cstruct/cstruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def __getattr__(self, attr: str) -> Any:
raise AttributeError(f"Invalid attribute: {attr}")

def _next_anonymous(self) -> str:
name = f"anonymous_{self._anonymous_count}"
name = f"__anonymous_{self._anonymous_count}__"
self._anonymous_count += 1
return name

Expand Down Expand Up @@ -364,8 +364,8 @@ def _make_struct(
None,
attrs={
"fields": fields,
"align": align,
"anonymous": anonymous,
"__align__": align,
"__anonymous__": anonymous,
},
)

Expand Down
5 changes: 4 additions & 1 deletion dissect/cstruct/types/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ class EnumMetaType(EnumMeta, MetaType):

def __call__(
cls,
value: Union[cstruct, int, BinaryIO, bytes],
value: Union[cstruct, int, BinaryIO, bytes] = None,
name: Optional[str] = None,
type_: Optional[MetaType] = None,
*args,
**kwargs,
):
if name is None:
if value is None:
value = cls.type()

if not isinstance(value, int):
# value is a parsable value
value = cls.type(value)
Expand Down
Loading

0 comments on commit 961fc80

Please sign in to comment.