|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +import copy |
3 | 4 | import ctypes as _ctypes |
4 | 5 | import struct |
5 | 6 | import sys |
|
25 | 26 | Void, |
26 | 27 | Wchar, |
27 | 28 | ) |
| 29 | +from dissect.cstruct.types.base import MetaType |
28 | 30 |
|
29 | 31 | if TYPE_CHECKING: |
30 | 32 | from collections.abc import Iterable |
@@ -205,6 +207,24 @@ def __getattr__(self, attr: str) -> Any: |
205 | 207 |
|
206 | 208 | raise AttributeError(f"Invalid attribute: {attr}") |
207 | 209 |
|
| 210 | + def __copy__(self) -> cstruct: |
| 211 | + cs = cstruct(endian=self.endian, pointer=self.pointer.__name__) |
| 212 | + cs._anonymous_count = self._anonymous_count |
| 213 | + cs.consts = self.consts.copy() |
| 214 | + cs.includes = self.includes.copy() |
| 215 | + |
| 216 | + # Update typedefs to point to the new cstruct instance |
| 217 | + for name, type in self.typedefs.items(): |
| 218 | + if name in cs.typedefs: |
| 219 | + continue |
| 220 | + |
| 221 | + if isinstance(type, MetaType): |
| 222 | + new_type = copy.copy(type) |
| 223 | + new_type.cs = cs |
| 224 | + cs.typedefs[name] = new_type |
| 225 | + |
| 226 | + return cs |
| 227 | + |
208 | 228 | def _next_anonymous(self) -> str: |
209 | 229 | name = f"__anonymous_{self._anonymous_count}__" |
210 | 230 | self._anonymous_count += 1 |
@@ -323,6 +343,14 @@ def resolve(self, name: type[BaseType] | str) -> type[BaseType]: |
323 | 343 |
|
324 | 344 | raise ResolveError(f"Recursion limit exceeded while resolving type {name}") |
325 | 345 |
|
| 346 | + def copy(self) -> cstruct: |
| 347 | + """Create a copy of this cstruct instance. |
| 348 | +
|
| 349 | + Returns: |
| 350 | + A new cstruct instance with the same types and settings as this one. |
| 351 | + """ |
| 352 | + return copy.copy(self) |
| 353 | + |
326 | 354 | def _make_type( |
327 | 355 | self, |
328 | 356 | name: str, |
|
0 commit comments