dissect.cstruct 5.0.dev6__tar.gz → 5.0.dev8__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.
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/PKG-INFO +1 -1
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/__init__.py +12 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/compiler.py +3 -5
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/base.py +5 -24
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/char.py +10 -4
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/packed.py +1 -7
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/structure.py +2 -2
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/wchar.py +7 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/util.py +90 -1
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/PKG-INFO +1 -1
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/scm_file_list.json +52 -52
- dissect_cstruct-5.0.dev8/dissect.cstruct.egg-info/scm_version.json +8 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_base.py +19 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_char.py +34 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_wchar.py +29 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_utils.py +30 -0
- dissect_cstruct-5.0.dev6/dissect.cstruct.egg-info/scm_version.json +0 -8
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/.git-blame-ignore-revs +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/.gitattributes +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/CHANGELOG.md +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/COPYRIGHT +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/LICENSE +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/MANIFEST.in +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/README.md +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/bitbuffer.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/cstruct.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/exception.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/expression.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/lexer.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/parser.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/tools/__init__.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/tools/stubgen.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/__init__.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/enum.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/flag.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/int.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/leb128.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/pointer.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect/cstruct/types/void.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/SOURCES.txt +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/dependency_links.txt +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/entry_points.txt +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/requires.txt +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/top_level.txt +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/examples/disk.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/examples/mirai.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/examples/pe.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/examples/protobuf.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/examples/secdesc.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/pyproject.toml +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/setup.cfg +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/__init__.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/_data/testdef.txt +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/_docs/Makefile +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/_docs/__init__.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/_docs/conf.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/_docs/index.rst +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/conftest.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_align.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_annotations.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_basic.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_benchmark.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_bitbuffer.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_bitfield.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_compiler.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_ctypes.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_expression.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_lexer.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_parser.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_tools_stubgen.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_custom.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_enum.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_flag.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_int.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_leb128.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_packed.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_pointer.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_structure.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_union.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/test_types_void.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tests/utils.py +0 -0
- {dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.cstruct
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.dev8
|
|
4
4
|
Summary: A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -30,12 +30,18 @@ from dissect.cstruct.types import (
|
|
|
30
30
|
)
|
|
31
31
|
from dissect.cstruct.util import (
|
|
32
32
|
dumpstruct,
|
|
33
|
+
f16,
|
|
34
|
+
f32,
|
|
35
|
+
f64,
|
|
33
36
|
hexdump,
|
|
34
37
|
p8,
|
|
35
38
|
p16,
|
|
36
39
|
p32,
|
|
37
40
|
p64,
|
|
38
41
|
pack,
|
|
42
|
+
pf16,
|
|
43
|
+
pf32,
|
|
44
|
+
pf64,
|
|
39
45
|
swap,
|
|
40
46
|
swap16,
|
|
41
47
|
swap32,
|
|
@@ -75,12 +81,18 @@ __all__ = [
|
|
|
75
81
|
"ctypes",
|
|
76
82
|
"ctypes_type",
|
|
77
83
|
"dumpstruct",
|
|
84
|
+
"f16",
|
|
85
|
+
"f32",
|
|
86
|
+
"f64",
|
|
78
87
|
"hexdump",
|
|
79
88
|
"p8",
|
|
80
89
|
"p16",
|
|
81
90
|
"p32",
|
|
82
91
|
"p64",
|
|
83
92
|
"pack",
|
|
93
|
+
"pf16",
|
|
94
|
+
"pf32",
|
|
95
|
+
"pf64",
|
|
84
96
|
"swap",
|
|
85
97
|
"swap16",
|
|
86
98
|
"swap32",
|
|
@@ -11,6 +11,7 @@ from typing import TYPE_CHECKING
|
|
|
11
11
|
from dissect.cstruct.bitbuffer import BitBuffer
|
|
12
12
|
from dissect.cstruct.types import (
|
|
13
13
|
Array,
|
|
14
|
+
BaseArray,
|
|
14
15
|
Char,
|
|
15
16
|
CharArray,
|
|
16
17
|
Flag,
|
|
@@ -24,18 +25,15 @@ from dissect.cstruct.types import (
|
|
|
24
25
|
Wchar,
|
|
25
26
|
WcharArray,
|
|
26
27
|
)
|
|
27
|
-
from dissect.cstruct.types.base import BaseArray
|
|
28
28
|
from dissect.cstruct.types.enum import EnumMetaType
|
|
29
|
-
from dissect.cstruct.
|
|
29
|
+
from dissect.cstruct.util import _struct
|
|
30
30
|
|
|
31
31
|
if TYPE_CHECKING:
|
|
32
32
|
from collections.abc import Iterator
|
|
33
33
|
from types import MethodType
|
|
34
34
|
|
|
35
35
|
from dissect.cstruct.cstruct import cstruct
|
|
36
|
-
from dissect.cstruct.types import
|
|
37
|
-
BaseType,
|
|
38
|
-
)
|
|
36
|
+
from dissect.cstruct.types import BaseType
|
|
39
37
|
from dissect.cstruct.types.structure import Field
|
|
40
38
|
|
|
41
39
|
SUPPORTED_TYPES = (
|
|
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar, TypeVar
|
|
|
6
6
|
|
|
7
7
|
from dissect.cstruct.exception import ArraySizeError
|
|
8
8
|
from dissect.cstruct.expression import Expression
|
|
9
|
+
from dissect.cstruct.util import normalize_endianness
|
|
9
10
|
|
|
10
11
|
if TYPE_CHECKING:
|
|
11
12
|
from collections.abc import Callable
|
|
@@ -294,8 +295,10 @@ class BaseArray(BaseType):
|
|
|
294
295
|
if cls.null_terminated:
|
|
295
296
|
return cls.type._write_0(stream, data, endian=endian)
|
|
296
297
|
|
|
297
|
-
if not cls.dynamic and cls.num_entries
|
|
298
|
-
|
|
298
|
+
if not cls.dynamic and (remaining := cls.num_entries - (actual_size := len(data))):
|
|
299
|
+
if remaining < 0:
|
|
300
|
+
raise ArraySizeError(f"Expected static array size {cls.num_entries}, got {actual_size} instead.")
|
|
301
|
+
data = data + [cls.type.__default__()] * remaining
|
|
299
302
|
|
|
300
303
|
return cls.type._write_array(stream, data, endian=endian)
|
|
301
304
|
|
|
@@ -326,27 +329,5 @@ def _is_eof(stream: BinaryIO) -> bool:
|
|
|
326
329
|
return False
|
|
327
330
|
|
|
328
331
|
|
|
329
|
-
ENDIANNESS_MAP: dict[AllowedEndianness, Endianness] = {
|
|
330
|
-
"<": "<",
|
|
331
|
-
">": ">",
|
|
332
|
-
"!": "!",
|
|
333
|
-
"@": "@",
|
|
334
|
-
"=": "=",
|
|
335
|
-
"network": "!",
|
|
336
|
-
"little": "<",
|
|
337
|
-
"big": ">",
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
def normalize_endianness(endian: AllowedEndianness) -> Endianness:
|
|
342
|
-
"""Normalize an endianness string to one of the standard format characters."""
|
|
343
|
-
try:
|
|
344
|
-
return ENDIANNESS_MAP[endian]
|
|
345
|
-
except KeyError:
|
|
346
|
-
raise ValueError(
|
|
347
|
-
f"Invalid endianness: {endian!r}, expected one of {', '.join(ENDIANNESS_MAP.keys())}"
|
|
348
|
-
) from None
|
|
349
|
-
|
|
350
|
-
|
|
351
332
|
# As mentioned in the BaseType class, we correctly set the type here
|
|
352
333
|
MetaType.ArrayType = Array
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any, BinaryIO
|
|
4
4
|
|
|
5
|
+
from dissect.cstruct.exception import ArraySizeError
|
|
5
6
|
from dissect.cstruct.types.base import EOF, BaseArray, BaseType
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
@@ -22,15 +23,20 @@ class CharArray(bytes, BaseArray):
|
|
|
22
23
|
return type.__call__(cls, super()._read(stream, context=context, endian=endian))
|
|
23
24
|
|
|
24
25
|
@classmethod
|
|
25
|
-
def _write(cls, stream: BinaryIO, data: bytes, *, endian: Endianness) -> int:
|
|
26
|
-
if isinstance(data, list)
|
|
26
|
+
def _write(cls, stream: BinaryIO, data: bytes | str | list[int], *, endian: Endianness) -> int:
|
|
27
|
+
if isinstance(data, list):
|
|
27
28
|
data = bytes(data)
|
|
28
|
-
|
|
29
29
|
elif isinstance(data, str):
|
|
30
30
|
data = data.encode("latin-1")
|
|
31
31
|
|
|
32
32
|
if cls.null_terminated:
|
|
33
|
-
|
|
33
|
+
data += b"\x00"
|
|
34
|
+
|
|
35
|
+
if not cls.dynamic and (remaining := cls.num_entries - (actual_size := len(data))):
|
|
36
|
+
if remaining < 0:
|
|
37
|
+
raise ArraySizeError(f"Expected static array size {cls.num_entries}, got {actual_size} instead.")
|
|
38
|
+
data += b"\x00" * remaining
|
|
39
|
+
|
|
34
40
|
return stream.write(data)
|
|
35
41
|
|
|
36
42
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from functools import lru_cache
|
|
4
|
-
from struct import Struct
|
|
5
3
|
from typing import TYPE_CHECKING, Any, BinaryIO, Generic, TypeVar
|
|
6
4
|
|
|
7
5
|
from dissect.cstruct.types.base import EOF, BaseType
|
|
6
|
+
from dissect.cstruct.util import _struct
|
|
8
7
|
|
|
9
8
|
if TYPE_CHECKING:
|
|
10
9
|
from typing_extensions import Self
|
|
@@ -12,11 +11,6 @@ if TYPE_CHECKING:
|
|
|
12
11
|
from dissect.cstruct.cstruct import Endianness
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
@lru_cache(1024)
|
|
16
|
-
def _struct(endian: str, packchar: str) -> Struct:
|
|
17
|
-
return Struct(f"{endian}{packchar}")
|
|
18
|
-
|
|
19
|
-
|
|
20
14
|
T = TypeVar("T", int, float)
|
|
21
15
|
|
|
22
16
|
|
|
@@ -252,7 +252,7 @@ class StructureMetaType(MetaType):
|
|
|
252
252
|
offset = stream.tell()
|
|
253
253
|
|
|
254
254
|
if field.offset is not None and offset != struct_start + field.offset:
|
|
255
|
-
# Field is at a specific offset, either
|
|
255
|
+
# Field is at a specific offset, either aligned or added that way
|
|
256
256
|
offset = struct_start + field.offset
|
|
257
257
|
stream.seek(offset)
|
|
258
258
|
|
|
@@ -318,7 +318,7 @@ class StructureMetaType(MetaType):
|
|
|
318
318
|
offset = stream.tell()
|
|
319
319
|
|
|
320
320
|
if field.offset is not None and offset < struct_start + field.offset:
|
|
321
|
-
# Field is at a specific offset, either
|
|
321
|
+
# Field is at a specific offset, either aligned or added that way
|
|
322
322
|
stream.write(b"\x00" * (struct_start + field.offset - offset))
|
|
323
323
|
offset = struct_start + field.offset
|
|
324
324
|
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import sys
|
|
4
4
|
from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar
|
|
5
5
|
|
|
6
|
+
from dissect.cstruct.exception import ArraySizeError
|
|
6
7
|
from dissect.cstruct.types.base import EOF, BaseArray, BaseType
|
|
7
8
|
|
|
8
9
|
if TYPE_CHECKING:
|
|
@@ -26,6 +27,12 @@ class WcharArray(str, BaseArray):
|
|
|
26
27
|
def _write(cls, stream: BinaryIO, data: str, *, endian: Endianness) -> int:
|
|
27
28
|
if cls.null_terminated:
|
|
28
29
|
data += "\x00"
|
|
30
|
+
|
|
31
|
+
if not cls.dynamic and (remaining := cls.num_entries - (actual_size := len(data))):
|
|
32
|
+
if remaining < 0:
|
|
33
|
+
raise ArraySizeError(f"Expected static array size {cls.num_entries}, got {actual_size} instead.")
|
|
34
|
+
data += "\x00" * remaining
|
|
35
|
+
|
|
29
36
|
return stream.write(data.encode(Wchar.__encoding_map__[endian]))
|
|
30
37
|
|
|
31
38
|
|
|
@@ -3,15 +3,17 @@ from __future__ import annotations
|
|
|
3
3
|
import os
|
|
4
4
|
import pprint
|
|
5
5
|
import string
|
|
6
|
+
import struct
|
|
6
7
|
import sys
|
|
7
8
|
from enum import Enum
|
|
9
|
+
from functools import lru_cache
|
|
8
10
|
from typing import TYPE_CHECKING
|
|
9
11
|
|
|
10
12
|
if TYPE_CHECKING:
|
|
11
13
|
from collections.abc import Iterator
|
|
12
14
|
from typing import Literal
|
|
13
15
|
|
|
14
|
-
from dissect.cstruct.cstruct import AllowedEndianness
|
|
16
|
+
from dissect.cstruct.cstruct import AllowedEndianness, Endianness
|
|
15
17
|
from dissect.cstruct.types.base import BaseType
|
|
16
18
|
from dissect.cstruct.types.structure import Structure
|
|
17
19
|
|
|
@@ -64,6 +66,28 @@ ENDIANNESS_TO_BYTEORDER_MAP: dict[AllowedEndianness, Literal["big", "little"]] =
|
|
|
64
66
|
"big": "big",
|
|
65
67
|
}
|
|
66
68
|
|
|
69
|
+
ENDIANNESS_MAP: dict[AllowedEndianness, Endianness] = {
|
|
70
|
+
"<": "<",
|
|
71
|
+
">": ">",
|
|
72
|
+
"!": "!",
|
|
73
|
+
"@": "@",
|
|
74
|
+
"=": "=",
|
|
75
|
+
"network": "!",
|
|
76
|
+
"little": "<",
|
|
77
|
+
"big": ">",
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def normalize_endianness(endian: AllowedEndianness) -> Endianness:
|
|
82
|
+
"""Normalize an endianness string to one of the standard format characters."""
|
|
83
|
+
try:
|
|
84
|
+
return ENDIANNESS_MAP[endian]
|
|
85
|
+
except KeyError:
|
|
86
|
+
raise ValueError(
|
|
87
|
+
f"Invalid endianness: {endian!r}, expected one of {', '.join(ENDIANNESS_MAP.keys())}"
|
|
88
|
+
) from None
|
|
89
|
+
|
|
90
|
+
|
|
67
91
|
Palette = list[tuple[int, str]]
|
|
68
92
|
|
|
69
93
|
|
|
@@ -327,6 +351,11 @@ def dumpstruct(
|
|
|
327
351
|
return _dumpstruct(obj, obj.dumps(), offset, color, output, autoskip)
|
|
328
352
|
|
|
329
353
|
|
|
354
|
+
@lru_cache(1024)
|
|
355
|
+
def _struct(endian: str, packchar: str) -> struct.Struct:
|
|
356
|
+
return struct.Struct(f"{endian}{packchar}")
|
|
357
|
+
|
|
358
|
+
|
|
330
359
|
def pack(value: int, size: int | None = None, endian: AllowedEndianness = "little") -> bytes:
|
|
331
360
|
"""Pack an integer value to a given bit size, endianness.
|
|
332
361
|
|
|
@@ -400,6 +429,36 @@ def p64(value: int, endian: AllowedEndianness = "little") -> bytes:
|
|
|
400
429
|
return pack(value, 64, endian)
|
|
401
430
|
|
|
402
431
|
|
|
432
|
+
def pf16(value: float, endian: AllowedEndianness = "little") -> bytes:
|
|
433
|
+
"""Pack a 16 bit float.
|
|
434
|
+
|
|
435
|
+
Arguments:
|
|
436
|
+
value: Value to pack.
|
|
437
|
+
endian: Endianness to use (little, big, network, <, >, !, @ or =).
|
|
438
|
+
"""
|
|
439
|
+
return _struct(normalize_endianness(endian), "e").pack(value)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def pf32(value: float, endian: AllowedEndianness = "little") -> bytes:
|
|
443
|
+
"""Pack a 32 bit float.
|
|
444
|
+
|
|
445
|
+
Arguments:
|
|
446
|
+
value: Value to pack.
|
|
447
|
+
endian: Endianness to use (little, big, network, <, >, !, @ or =).
|
|
448
|
+
"""
|
|
449
|
+
return _struct(normalize_endianness(endian), "f").pack(value)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def pf64(value: float, endian: AllowedEndianness = "little") -> bytes:
|
|
453
|
+
"""Pack a 64 bit float.
|
|
454
|
+
|
|
455
|
+
Arguments:
|
|
456
|
+
value: Value to pack.
|
|
457
|
+
endian: Endianness to use (little, big, network, <, >, !, @ or =).
|
|
458
|
+
"""
|
|
459
|
+
return _struct(normalize_endianness(endian), "d").pack(value)
|
|
460
|
+
|
|
461
|
+
|
|
403
462
|
def u8(value: bytes, endian: AllowedEndianness = "little", sign: bool = False) -> int:
|
|
404
463
|
"""Unpack an 8 bit integer.
|
|
405
464
|
|
|
@@ -444,6 +503,36 @@ def u64(value: bytes, endian: AllowedEndianness = "little", sign: bool = False)
|
|
|
444
503
|
return unpack(value, 64, endian, sign)
|
|
445
504
|
|
|
446
505
|
|
|
506
|
+
def f16(value: bytes, endian: AllowedEndianness = "little") -> float:
|
|
507
|
+
"""Unpack a 16 bit float.
|
|
508
|
+
|
|
509
|
+
Arguments:
|
|
510
|
+
value: Value to unpack.
|
|
511
|
+
endian: Endianness to use (little, big, network, <, >, !, @ or =).
|
|
512
|
+
"""
|
|
513
|
+
return _struct(normalize_endianness(endian), "e").unpack(value)[0]
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
def f32(value: bytes, endian: AllowedEndianness = "little") -> float:
|
|
517
|
+
"""Unpack a 32 bit float.
|
|
518
|
+
|
|
519
|
+
Arguments:
|
|
520
|
+
value: Value to unpack.
|
|
521
|
+
endian: Endianness to use (little, big, network, <, >, !, @ or =).
|
|
522
|
+
"""
|
|
523
|
+
return _struct(normalize_endianness(endian), "f").unpack(value)[0]
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
def f64(value: bytes, endian: AllowedEndianness = "little") -> float:
|
|
527
|
+
"""Unpack a 64 bit float.
|
|
528
|
+
|
|
529
|
+
Arguments:
|
|
530
|
+
value: Value to unpack.
|
|
531
|
+
endian: Endianness to use (little, big, network, <, >, !, @ or =).
|
|
532
|
+
"""
|
|
533
|
+
return _struct(normalize_endianness(endian), "d").unpack(value)[0]
|
|
534
|
+
|
|
535
|
+
|
|
447
536
|
def swap(value: int, size: int) -> int:
|
|
448
537
|
"""Swap the endianness of an integer with a given bit size.
|
|
449
538
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.cstruct
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.dev8
|
|
4
4
|
Summary: A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
{dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/scm_file_list.json
RENAMED
|
@@ -1,78 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": [
|
|
3
|
-
"
|
|
4
|
-
"tox.ini",
|
|
5
|
-
"LICENSE",
|
|
6
|
-
"pyproject.toml",
|
|
3
|
+
".gitignore",
|
|
7
4
|
"COPYRIGHT",
|
|
5
|
+
"README.md",
|
|
8
6
|
"CHANGELOG.md",
|
|
9
7
|
".git-blame-ignore-revs",
|
|
8
|
+
"tox.ini",
|
|
10
9
|
".gitattributes",
|
|
10
|
+
"pyproject.toml",
|
|
11
11
|
"MANIFEST.in",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
12
|
+
"LICENSE",
|
|
13
|
+
".github/pull_request_template.md",
|
|
14
|
+
".github/workflows/dissect-ci.yml",
|
|
15
|
+
"dissect/cstruct/parser.py",
|
|
15
16
|
"dissect/cstruct/compiler.py",
|
|
16
|
-
"dissect/cstruct/expression.py",
|
|
17
17
|
"dissect/cstruct/exception.py",
|
|
18
|
-
"dissect/cstruct/parser.py",
|
|
19
|
-
"dissect/cstruct/lexer.py",
|
|
20
|
-
"dissect/cstruct/bitbuffer.py",
|
|
21
18
|
"dissect/cstruct/util.py",
|
|
22
|
-
"dissect/cstruct/
|
|
23
|
-
"dissect/cstruct/
|
|
24
|
-
"dissect/cstruct/
|
|
25
|
-
"dissect/cstruct/
|
|
26
|
-
"dissect/cstruct/
|
|
27
|
-
"dissect/cstruct/types/
|
|
19
|
+
"dissect/cstruct/cstruct.py",
|
|
20
|
+
"dissect/cstruct/bitbuffer.py",
|
|
21
|
+
"dissect/cstruct/lexer.py",
|
|
22
|
+
"dissect/cstruct/expression.py",
|
|
23
|
+
"dissect/cstruct/__init__.py",
|
|
24
|
+
"dissect/cstruct/types/base.py",
|
|
28
25
|
"dissect/cstruct/types/pointer.py",
|
|
29
26
|
"dissect/cstruct/types/structure.py",
|
|
27
|
+
"dissect/cstruct/types/void.py",
|
|
28
|
+
"dissect/cstruct/types/int.py",
|
|
29
|
+
"dissect/cstruct/types/flag.py",
|
|
30
|
+
"dissect/cstruct/types/packed.py",
|
|
30
31
|
"dissect/cstruct/types/enum.py",
|
|
31
|
-
"dissect/cstruct/types/
|
|
32
|
+
"dissect/cstruct/types/char.py",
|
|
32
33
|
"dissect/cstruct/types/wchar.py",
|
|
33
|
-
"dissect/cstruct/types/
|
|
34
|
-
"dissect/cstruct/
|
|
34
|
+
"dissect/cstruct/types/leb128.py",
|
|
35
|
+
"dissect/cstruct/types/__init__.py",
|
|
35
36
|
"dissect/cstruct/tools/stubgen.py",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"tests/test_tools_stubgen.py",
|
|
43
|
-
"tests/test_basic.py",
|
|
44
|
-
"tests/test_lexer.py",
|
|
45
|
-
"tests/test_types_int.py",
|
|
46
|
-
"tests/test_expression.py",
|
|
47
|
-
"tests/utils.py",
|
|
48
|
-
"tests/test_align.py",
|
|
49
|
-
"tests/test_utils.py",
|
|
50
|
-
"tests/test_compiler.py",
|
|
37
|
+
"dissect/cstruct/tools/__init__.py",
|
|
38
|
+
"examples/secdesc.py",
|
|
39
|
+
"examples/pe.py",
|
|
40
|
+
"examples/mirai.py",
|
|
41
|
+
"examples/protobuf.py",
|
|
42
|
+
"examples/disk.py",
|
|
51
43
|
"tests/test_types_enum.py",
|
|
44
|
+
"tests/test_types_pointer.py",
|
|
45
|
+
"tests/test_types_leb128.py",
|
|
46
|
+
"tests/test_annotations.py",
|
|
52
47
|
"tests/test_types_wchar.py",
|
|
53
|
-
"tests/test_bitfield.py",
|
|
54
|
-
"tests/test_types_structure.py",
|
|
55
48
|
"tests/test_parser.py",
|
|
56
|
-
"tests/
|
|
49
|
+
"tests/test_ctypes.py",
|
|
50
|
+
"tests/test_bitbuffer.py",
|
|
57
51
|
"tests/conftest.py",
|
|
58
|
-
"tests/
|
|
52
|
+
"tests/test_types_packed.py",
|
|
53
|
+
"tests/test_types_structure.py",
|
|
54
|
+
"tests/test_types_union.py",
|
|
55
|
+
"tests/test_expression.py",
|
|
56
|
+
"tests/test_tools_stubgen.py",
|
|
57
|
+
"tests/test_types_custom.py",
|
|
58
|
+
"tests/utils.py",
|
|
59
|
+
"tests/test_lexer.py",
|
|
59
60
|
"tests/test_types_flag.py",
|
|
60
61
|
"tests/test_benchmark.py",
|
|
61
|
-
"tests/
|
|
62
|
-
"tests/
|
|
62
|
+
"tests/test_types_char.py",
|
|
63
|
+
"tests/test_compiler.py",
|
|
64
|
+
"tests/test_types_int.py",
|
|
65
|
+
"tests/test_types_void.py",
|
|
63
66
|
"tests/test_types_base.py",
|
|
64
|
-
"tests/
|
|
65
|
-
"tests/
|
|
66
|
-
"tests/
|
|
67
|
+
"tests/test_align.py",
|
|
68
|
+
"tests/test_basic.py",
|
|
69
|
+
"tests/test_bitfield.py",
|
|
70
|
+
"tests/test_utils.py",
|
|
71
|
+
"tests/__init__.py",
|
|
72
|
+
"tests/_docs/conf.py",
|
|
67
73
|
"tests/_docs/Makefile",
|
|
68
74
|
"tests/_docs/index.rst",
|
|
69
|
-
"tests/_docs/
|
|
70
|
-
"
|
|
71
|
-
"examples/disk.py",
|
|
72
|
-
"examples/pe.py",
|
|
73
|
-
"examples/mirai.py",
|
|
74
|
-
"examples/protobuf.py",
|
|
75
|
-
".github/pull_request_template.md",
|
|
76
|
-
".github/workflows/dissect-ci.yml"
|
|
75
|
+
"tests/_docs/__init__.py",
|
|
76
|
+
"tests/_data/testdef.txt"
|
|
77
77
|
]
|
|
78
78
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import io
|
|
3
4
|
from typing import TYPE_CHECKING, BinaryIO
|
|
4
5
|
|
|
5
6
|
import pytest
|
|
@@ -20,6 +21,24 @@ def test_array_size_mismatch(cs: cstruct) -> None:
|
|
|
20
21
|
assert cs.uint8[2]([1, 2]).dumps()
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
def test_array_write_padding(cs: cstruct) -> None:
|
|
25
|
+
buf = io.BytesIO()
|
|
26
|
+
cs.uint8[4]._write(buf, [1, 2], endian=cs.endian)
|
|
27
|
+
assert buf.getvalue() == b"\x01\x02\x00\x00"
|
|
28
|
+
|
|
29
|
+
cdef = """
|
|
30
|
+
struct point {
|
|
31
|
+
uint8 x;
|
|
32
|
+
uint8 y;
|
|
33
|
+
};
|
|
34
|
+
"""
|
|
35
|
+
cs.load(cdef)
|
|
36
|
+
|
|
37
|
+
buf = io.BytesIO()
|
|
38
|
+
cs.point[4]._write(buf, [cs.point(x=1, y=2)], endian=cs.endian)
|
|
39
|
+
assert buf.getvalue() == b"\x01\x02" + b"\x00\x00" * 3
|
|
40
|
+
|
|
41
|
+
|
|
23
42
|
def test_eof(cs: cstruct, compiled: bool) -> None:
|
|
24
43
|
cdef = """
|
|
25
44
|
struct test_char {
|
|
@@ -5,6 +5,8 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
7
|
|
|
8
|
+
from dissect.cstruct.exception import ArraySizeError
|
|
9
|
+
|
|
8
10
|
if TYPE_CHECKING:
|
|
9
11
|
from dissect.cstruct.cstruct import cstruct
|
|
10
12
|
|
|
@@ -36,6 +38,38 @@ def test_char_array_write(cs: cstruct) -> None:
|
|
|
36
38
|
assert cs.char[None](buf).dumps() == b"AAAA\x00"
|
|
37
39
|
|
|
38
40
|
|
|
41
|
+
def test_char_array_write_padding(cs: cstruct) -> None:
|
|
42
|
+
buf = io.BytesIO()
|
|
43
|
+
cs.char[8]._write(buf, "hi", endian=cs.endian)
|
|
44
|
+
assert buf.getvalue() == b"hi\x00\x00\x00\x00\x00\x00"
|
|
45
|
+
|
|
46
|
+
cdef = """
|
|
47
|
+
struct test_struct {
|
|
48
|
+
int x;
|
|
49
|
+
char y[8];
|
|
50
|
+
char z[16];
|
|
51
|
+
};
|
|
52
|
+
"""
|
|
53
|
+
cs.load(cdef)
|
|
54
|
+
|
|
55
|
+
obj = cs.test_struct()
|
|
56
|
+
obj.x = 4
|
|
57
|
+
obj.y = "hi"
|
|
58
|
+
obj.z = "bye"
|
|
59
|
+
|
|
60
|
+
assert len(obj.dumps()) == len(cs.test_struct)
|
|
61
|
+
assert (
|
|
62
|
+
obj.dumps()
|
|
63
|
+
== b"\x04\x00\x00\x00hi\x00\x00\x00\x00\x00\x00bye\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_char_array_write_size_error(cs: cstruct) -> None:
|
|
68
|
+
buf = io.BytesIO()
|
|
69
|
+
with pytest.raises(ArraySizeError):
|
|
70
|
+
cs.char[4]._write(buf, b"toolong", endian=cs.endian)
|
|
71
|
+
|
|
72
|
+
|
|
39
73
|
def test_char_eof(cs: cstruct) -> None:
|
|
40
74
|
with pytest.raises(EOFError):
|
|
41
75
|
cs.char(b"")
|
|
@@ -5,6 +5,8 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
7
|
|
|
8
|
+
from dissect.cstruct.exception import ArraySizeError
|
|
9
|
+
|
|
8
10
|
if TYPE_CHECKING:
|
|
9
11
|
from dissect.cstruct.cstruct import cstruct
|
|
10
12
|
|
|
@@ -38,6 +40,33 @@ def test_wchar_array_write(cs: cstruct) -> None:
|
|
|
38
40
|
assert cs.wchar[None](buf).dumps() == b"A\x00A\x00A\x00A\x00\x00\x00"
|
|
39
41
|
|
|
40
42
|
|
|
43
|
+
def test_wchar_array_write_padding(cs: cstruct) -> None:
|
|
44
|
+
buf = io.BytesIO()
|
|
45
|
+
cs.wchar[8]._write(buf, "hi", endian=cs.endian)
|
|
46
|
+
assert buf.getvalue() == b"h\x00i\x00" + b"\x00" * 12
|
|
47
|
+
|
|
48
|
+
cdef = """
|
|
49
|
+
struct test_struct {
|
|
50
|
+
int x;
|
|
51
|
+
wchar y[8];
|
|
52
|
+
wchar z[16];
|
|
53
|
+
};
|
|
54
|
+
"""
|
|
55
|
+
cs.load(cdef)
|
|
56
|
+
obj = cs.test_struct()
|
|
57
|
+
obj.x = 4
|
|
58
|
+
obj.y = "hi"
|
|
59
|
+
obj.z = "bye"
|
|
60
|
+
assert len(obj.dumps()) == len(cs.test_struct)
|
|
61
|
+
assert obj.dumps() == b"\x04\x00\x00\x00h\x00i\x00" + (b"\x00" * 12) + b"b\x00y\x00e\x00" + (b"\x00" * 26)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_wchar_array_write_size_error(cs: cstruct) -> None:
|
|
65
|
+
buf = io.BytesIO()
|
|
66
|
+
with pytest.raises(ArraySizeError):
|
|
67
|
+
cs.wchar[4]._write(buf, "toolong", endian=cs.endian)
|
|
68
|
+
|
|
69
|
+
|
|
41
70
|
def test_wchar_be_read(cs: cstruct) -> None:
|
|
42
71
|
cs.endian = ">"
|
|
43
72
|
|
|
@@ -259,10 +259,16 @@ def test_pack_unpack() -> None:
|
|
|
259
259
|
assert util.p16(1, endian) == b"\x01\x00"
|
|
260
260
|
assert util.p32(1, endian) == b"\x01\x00\x00\x00"
|
|
261
261
|
assert util.p64(1, endian) == b"\x01\x00\x00\x00\x00\x00\x00\x00"
|
|
262
|
+
assert util.pf16(1.0, endian) == b"\x00\x3c"
|
|
263
|
+
assert util.pf32(1.0, endian) == b"\x00\x00\x80\x3f"
|
|
264
|
+
assert util.pf64(1.0, endian) == b"\x00\x00\x00\x00\x00\x00\xf0\x3f"
|
|
262
265
|
assert util.u8(b"\x01", endian, sign) == 1
|
|
263
266
|
assert util.u16(b"\x01\x00", endian, sign) == 1
|
|
264
267
|
assert util.u32(b"\x01\x00\x00\x00", endian, sign) == 1
|
|
265
268
|
assert util.u64(b"\x01\x00\x00\x00\x00\x00\x00\x00", endian, sign) == 1
|
|
269
|
+
assert util.f16(b"\x00\x3c", endian) == 1.0
|
|
270
|
+
assert util.f32(b"\x00\x00\x80\x3f", endian) == 1.0
|
|
271
|
+
assert util.f64(b"\x00\x00\x00\x00\x00\x00\xf0\x3f", endian) == 1.0
|
|
266
272
|
|
|
267
273
|
endian = "big"
|
|
268
274
|
sign = False
|
|
@@ -270,10 +276,16 @@ def test_pack_unpack() -> None:
|
|
|
270
276
|
assert util.p16(1, endian) == b"\x00\x01"
|
|
271
277
|
assert util.p32(1, endian) == b"\x00\x00\x00\x01"
|
|
272
278
|
assert util.p64(1, endian) == b"\x00\x00\x00\x00\x00\x00\x00\x01"
|
|
279
|
+
assert util.pf16(1.0, endian) == b"\x3c\x00"
|
|
280
|
+
assert util.pf32(1.0, endian) == b"\x3f\x80\x00\x00"
|
|
281
|
+
assert util.pf64(1.0, endian) == b"\x3f\xf0\x00\x00\x00\x00\x00\x00"
|
|
273
282
|
assert util.u8(b"\x01", endian, sign) == 1
|
|
274
283
|
assert util.u16(b"\x00\x01", endian, sign) == 1
|
|
275
284
|
assert util.u32(b"\x00\x00\x00\x01", endian, sign) == 1
|
|
276
285
|
assert util.u64(b"\x00\x00\x00\x00\x00\x00\x00\x01", endian, sign) == 1
|
|
286
|
+
assert util.f16(b"\x3c\x00", endian) == 1.0
|
|
287
|
+
assert util.f32(b"\x3f\x80\x00\x00", endian) == 1.0
|
|
288
|
+
assert util.f64(b"\x3f\xf0\x00\x00\x00\x00\x00\x00", endian) == 1.0
|
|
277
289
|
|
|
278
290
|
endian = "network"
|
|
279
291
|
sign = False
|
|
@@ -281,10 +293,16 @@ def test_pack_unpack() -> None:
|
|
|
281
293
|
assert util.p16(1, endian) == b"\x00\x01"
|
|
282
294
|
assert util.p32(1, endian) == b"\x00\x00\x00\x01"
|
|
283
295
|
assert util.p64(1, endian) == b"\x00\x00\x00\x00\x00\x00\x00\x01"
|
|
296
|
+
assert util.pf16(1.0, endian) == b"\x3c\x00"
|
|
297
|
+
assert util.pf32(1.0, endian) == b"\x3f\x80\x00\x00"
|
|
298
|
+
assert util.pf64(1.0, endian) == b"\x3f\xf0\x00\x00\x00\x00\x00\x00"
|
|
284
299
|
assert util.u8(b"\x01", endian, sign) == 1
|
|
285
300
|
assert util.u16(b"\x00\x01", endian, sign) == 1
|
|
286
301
|
assert util.u32(b"\x00\x00\x00\x01", endian, sign) == 1
|
|
287
302
|
assert util.u64(b"\x00\x00\x00\x00\x00\x00\x00\x01", endian, sign) == 1
|
|
303
|
+
assert util.f16(b"\x3c\x00", endian) == 1.0
|
|
304
|
+
assert util.f32(b"\x3f\x80\x00\x00", endian) == 1.0
|
|
305
|
+
assert util.f64(b"\x3f\xf0\x00\x00\x00\x00\x00\x00", endian) == 1.0
|
|
288
306
|
|
|
289
307
|
endian = "little"
|
|
290
308
|
sign = True
|
|
@@ -292,10 +310,16 @@ def test_pack_unpack() -> None:
|
|
|
292
310
|
assert util.p16(-120, endian) == b"\x88\xff"
|
|
293
311
|
assert util.p32(-120, endian) == b"\x88\xff\xff\xff"
|
|
294
312
|
assert util.p64(-120, endian) == b"\x88\xff\xff\xff\xff\xff\xff\xff"
|
|
313
|
+
assert util.pf16(-120.0, endian) == b"\x80\xd7"
|
|
314
|
+
assert util.pf32(-120.0, endian) == b"\x00\x00\xf0\xc2"
|
|
315
|
+
assert util.pf64(-120.0, endian) == b"\x00\x00\x00\x00\x00\x00\x5e\xc0"
|
|
295
316
|
assert util.u8(b"\x88", endian, sign) == -120
|
|
296
317
|
assert util.u16(b"\x88\xff", endian, sign) == -120
|
|
297
318
|
assert util.u32(b"\x88\xff\xff\xff", endian, sign) == -120
|
|
298
319
|
assert util.u64(b"\x88\xff\xff\xff\xff\xff\xff\xff", endian, sign) == -120
|
|
320
|
+
assert util.f16(b"\x80\xd7", endian) == -120.0
|
|
321
|
+
assert util.f32(b"\x00\x00\xf0\xc2", endian) == -120.0
|
|
322
|
+
assert util.f64(b"\x00\x00\x00\x00\x00\x00\x5e\xc0", endian) == -120.0
|
|
299
323
|
|
|
300
324
|
endian = "big"
|
|
301
325
|
sign = True
|
|
@@ -303,10 +327,16 @@ def test_pack_unpack() -> None:
|
|
|
303
327
|
assert util.p16(-120, endian) == b"\xff\x88"
|
|
304
328
|
assert util.p32(-120, endian) == b"\xff\xff\xff\x88"
|
|
305
329
|
assert util.p64(-120, endian) == b"\xff\xff\xff\xff\xff\xff\xff\x88"
|
|
330
|
+
assert util.pf16(-120.0, endian) == b"\xd7\x80"
|
|
331
|
+
assert util.pf32(-120.0, endian) == b"\xc2\xf0\x00\x00"
|
|
332
|
+
assert util.pf64(-120.0, endian) == b"\xc0\x5e\x00\x00\x00\x00\x00\x00"
|
|
306
333
|
assert util.u8(b"\x88", endian, sign) == -120
|
|
307
334
|
assert util.u16(b"\xff\x88", endian, sign) == -120
|
|
308
335
|
assert util.u32(b"\xff\xff\xff\x88", endian, sign) == -120
|
|
309
336
|
assert util.u64(b"\xff\xff\xff\xff\xff\xff\xff\x88", endian, sign) == -120
|
|
337
|
+
assert util.f16(b"\xd7\x80", endian) == -120.0
|
|
338
|
+
assert util.f32(b"\xc2\xf0\x00\x00", endian) == -120.0
|
|
339
|
+
assert util.f64(b"\xc0\x5e\x00\x00\x00\x00\x00\x00", endian) == -120.0
|
|
310
340
|
|
|
311
341
|
assert util.pack(1, 24) == b"\x01\x00\x00"
|
|
312
342
|
assert util.unpack(b"\x01\x00\x00", 24) == 1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dissect_cstruct-5.0.dev6 → dissect_cstruct-5.0.dev8}/dissect.cstruct.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|