dissect.cstruct 5.0.dev9__py3-none-any.whl → 5.0.dev11__py3-none-any.whl

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.
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING, Any, BinaryIO
4
4
 
5
- from dissect.cstruct.types.base import BaseType
5
+ from dissect.cstruct.types.base import EOF, BaseType, MetaType
6
6
  from dissect.cstruct.util import ENDIANNESS_TO_BYTEORDER_MAP
7
7
 
8
8
  if TYPE_CHECKING:
@@ -23,7 +23,26 @@ class Int(int, BaseType):
23
23
  if len(data) != cls.__size__:
24
24
  raise EOFError(f"Read {len(data)} bytes, but expected {cls.__size__}")
25
25
 
26
- return cls.from_bytes(data, ENDIANNESS_TO_BYTEORDER_MAP[endian], signed=cls.signed)
26
+ return type.__call__(cls, int.from_bytes(data, ENDIANNESS_TO_BYTEORDER_MAP[endian], signed=cls.signed))
27
+
28
+ @classmethod
29
+ def _read_array(
30
+ cls, stream: BinaryIO, count: int, *, context: dict[str, Any] | None = None, endian: Endianness
31
+ ) -> list[Self]:
32
+ if count == EOF:
33
+ return MetaType._read_array(cls, stream, count, context=context, endian=endian)
34
+
35
+ size = cls.__size__
36
+ length = size * count
37
+ data = stream.read(length)
38
+ if len(data) != length:
39
+ raise EOFError(f"Read {len(data) % size} bytes, but expected {size}")
40
+
41
+ byteorder = ENDIANNESS_TO_BYTEORDER_MAP[endian]
42
+ return [
43
+ type.__call__(cls, int.from_bytes(data[i : i + size], byteorder, signed=cls.signed))
44
+ for i in range(0, length, size)
45
+ ]
27
46
 
28
47
  @classmethod
29
48
  def _read_0(cls, stream: BinaryIO, *, context: dict[str, Any] | None = None, endian: Endianness) -> Self:
@@ -1,9 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import warnings
4
+ from itertools import repeat
4
5
  from typing import TYPE_CHECKING, Any, BinaryIO, Generic, TypeVar
5
6
 
6
- from dissect.cstruct.types.base import EOF, BaseType
7
+ from dissect.cstruct.types.base import EOF, BaseType, MetaType, _is_buffer_type
7
8
  from dissect.cstruct.util import _struct, classproperty
8
9
 
9
10
  if TYPE_CHECKING:
@@ -15,7 +16,35 @@ if TYPE_CHECKING:
15
16
  T = TypeVar("T", int, float)
16
17
 
17
18
 
18
- class Packed(BaseType, Generic[T]):
19
+ class PackedMetaType(MetaType):
20
+ """Metaclass for packed types."""
21
+
22
+ def __call__(cls, *args, **kwargs) -> Packed:
23
+ if len(args) == 1 and not kwargs:
24
+ # Handle a few fast path cases
25
+ obj = args[0]
26
+ if (tp := type(obj)) is bytes or tp is bytearray or (tp is memoryview and obj.c_contiguous):
27
+ data = obj.cast("B") if tp is memoryview else obj
28
+ if len(data) < cls.__size__:
29
+ raise EOFError(f"Read {len(data)} bytes, but expected {cls.__size__}")
30
+
31
+ return cls.__new__(cls, _struct(cls.__cs__.endian, cls.__fmt__).unpack_from(data)[0])
32
+
33
+ if hasattr(obj, "read") and not isinstance(obj, cls):
34
+ return cls._read(obj, endian=cls.__cs__.endian)
35
+
36
+ if not _is_buffer_type(obj):
37
+ # E.g. initializing with a value
38
+ return type.__call__(cls, obj)
39
+
40
+ elif not args and not kwargs:
41
+ # Default value
42
+ return type.__call__(cls)
43
+
44
+ return MetaType.__call__(cls, *args, **kwargs)
45
+
46
+
47
+ class Packed(BaseType, Generic[T], metaclass=PackedMetaType):
19
48
  """Packed type for Python struct (un)packing."""
20
49
 
21
50
  __fmt__: str
@@ -46,7 +75,7 @@ class Packed(BaseType, Generic[T]):
46
75
  if len(data) != length:
47
76
  raise EOFError(f"Read {len(data)} bytes, but expected {length}")
48
77
 
49
- return [cls.__new__(cls, value) for value in fmt.unpack(data)]
78
+ return list(map(cls.__new__, repeat(cls), fmt.unpack(data)))
50
79
 
51
80
  @classmethod
52
81
  def _read_0(cls, stream: BinaryIO, context: dict[str, Any] | None = None, *, endian: Endianness) -> Self:
@@ -17,11 +17,11 @@ from dissect.cstruct.bitbuffer import BitBuffer
17
17
  from dissect.cstruct.expression import Expression
18
18
  from dissect.cstruct.lexer import IDENTIFIER_TYPES
19
19
  from dissect.cstruct.types.base import (
20
+ _BUFFER_TYPES,
20
21
  BaseArray,
21
22
  BaseType,
22
23
  MetaType,
23
24
  _is_buffer_type,
24
- _is_readable_type,
25
25
  )
26
26
  from dissect.cstruct.types.enum import EnumMetaType
27
27
  from dissect.cstruct.types.pointer import Pointer
@@ -75,6 +75,15 @@ class StructureMetaType(MetaType):
75
75
  return super().__new__(metacls, name, bases, classdict)
76
76
 
77
77
  def __call__(cls, *args, **kwargs) -> Self: # type: ignore
78
+ if len(args) == 1 and not kwargs:
79
+ # Fast paths for the most common cases
80
+ obj = args[0]
81
+ if type(obj) in _BUFFER_TYPES:
82
+ return cls._read(io.BytesIO(obj), endian=cls.__cs__.endian)
83
+
84
+ if hasattr(obj, "read") and not isinstance(obj, cls):
85
+ return cls._read(obj, endian=cls.__cs__.endian)
86
+
78
87
  if not args and not kwargs:
79
88
  obj = type.__call__(cls)
80
89
  object.__setattr__(obj, "__dynamic_sizes__", {})
@@ -132,20 +141,6 @@ class StructureMetaType(MetaType):
132
141
  else:
133
142
  size, alignment = cls._calculate_size_and_offsets(fields, align)
134
143
 
135
- if cls.__compiled__:
136
- # If the previous class was compiled try to compile this too
137
- from dissect.cstruct import compiler
138
-
139
- try:
140
- classdict["_read"] = compiler.Compiler(cls.__cs__).compile_read(
141
- fields, cls.__name__, align=cls.__align__
142
- )
143
- classdict["__compiled__"] = True
144
- except Exception:
145
- # Revert _read to the slower loop based method
146
- classdict["_read"] = classmethod(Structure._read.__func__)
147
- classdict["__compiled__"] = False
148
-
149
144
  # TODO: compile _write
150
145
  # TODO: generate cached_property for lazy reading
151
146
 
@@ -244,7 +239,7 @@ class StructureMetaType(MetaType):
244
239
  return offset, alignment
245
240
 
246
241
  def _read(cls, stream: BinaryIO, *, context: dict[str, Any] | None = None, endian: Endianness) -> Self: # type: ignore
247
- bit_buffer = BitBuffer(stream, endian=endian)
242
+ bit_buffer = None
248
243
  struct_start = stream.tell()
249
244
 
250
245
  result = {}
@@ -263,6 +258,9 @@ class StructureMetaType(MetaType):
263
258
  stream.seek(offset)
264
259
 
265
260
  if field.bits:
261
+ if bit_buffer is None:
262
+ bit_buffer = BitBuffer(stream, endian=endian)
263
+
266
264
  if isinstance(field.type, EnumMetaType):
267
265
  value = field.type(bit_buffer.read(field.type.__type__, field.bits))
268
266
  else:
@@ -271,7 +269,8 @@ class StructureMetaType(MetaType):
271
269
  result[field._name] = value
272
270
  continue
273
271
 
274
- bit_buffer.reset()
272
+ if bit_buffer is not None:
273
+ bit_buffer.reset()
275
274
 
276
275
  value = field.type._read(stream, context=result, endian=endian)
277
276
 
@@ -298,23 +297,24 @@ class StructureMetaType(MetaType):
298
297
  return result
299
298
 
300
299
  def _write(cls, stream: BinaryIO, data: Structure, *, endian: Endianness) -> int:
301
- bit_buffer = BitBuffer(stream, endian=endian)
300
+ bit_buffer = None
302
301
  struct_start = stream.tell()
303
302
  num = 0
304
303
 
305
304
  for field in cls.__fields__:
306
305
  field_type = field.type
307
306
 
308
- bit_field_type = (
309
- (field_type.__type__ if isinstance(field_type, EnumMetaType) else field_type) if field.bits else None
310
- )
311
- # Current field is not a bit field, but previous was
312
- # Or, moved to a bit field of another type, e.g. uint16 f1 : 8, uint32 f2 : 8;
313
- if (not field.bits and bit_buffer._type is not None) or (
314
- bit_buffer._type and bit_buffer._type != bit_field_type
315
- ):
316
- # Flush the current bit buffer so we can process alignment properly
317
- bit_buffer.flush()
307
+ if bit_buffer is not None and bit_buffer._type is not None:
308
+ bit_field_type = (
309
+ (field_type.__type__ if isinstance(field_type, EnumMetaType) else field_type)
310
+ if field.bits
311
+ else None
312
+ )
313
+ # Current field is not a bit field, but previous was
314
+ # Or, moved to a bit field of another type, e.g. uint16 f1 : 8, uint32 f2 : 8;
315
+ if bit_buffer._type != bit_field_type:
316
+ # Flush the current bit buffer so we can process alignment properly
317
+ bit_buffer.flush()
318
318
 
319
319
  offset = stream.tell()
320
320
 
@@ -324,10 +324,8 @@ class StructureMetaType(MetaType):
324
324
  offset = struct_start + field.offset
325
325
 
326
326
  if cls.__align__ and field.offset is None:
327
- is_bitbuffer_boundary = bit_buffer._type and (
328
- bit_buffer._remaining == 0 or bit_buffer._type != field_type
329
- )
330
- if not bit_buffer._type or is_bitbuffer_boundary:
327
+ bit_type = bit_buffer._type if bit_buffer is not None else None
328
+ if bit_type is None or bit_buffer._remaining == 0 or bit_type != field_type:
331
329
  # Previous field was dynamically sized and we need to align
332
330
  align_pad = -offset & (field.alignment - 1)
333
331
  stream.write(b"\x00" * align_pad)
@@ -338,6 +336,9 @@ class StructureMetaType(MetaType):
338
336
  value = field_type.__default__()
339
337
 
340
338
  if field.bits:
339
+ if bit_buffer is None:
340
+ bit_buffer = BitBuffer(stream, endian=endian)
341
+
341
342
  if isinstance(field_type, EnumMetaType):
342
343
  bit_buffer.write(field_type.__type__, value.value, field.bits)
343
344
  else:
@@ -346,7 +347,7 @@ class StructureMetaType(MetaType):
346
347
  field_type._write(stream, value, endian=endian)
347
348
  num += stream.tell() - offset
348
349
 
349
- if bit_buffer._type is not None:
350
+ if bit_buffer is not None and bit_buffer._type is not None:
350
351
  bit_buffer.flush()
351
352
 
352
353
  if cls.__align__:
@@ -377,6 +378,12 @@ class StructureMetaType(MetaType):
377
378
  for key, value in classdict.items():
378
379
  setattr(cls, key, value)
379
380
 
381
+ if cls.__compiled__:
382
+ # If the previous class was compiled try to compile this too
383
+ from dissect.cstruct import compiler
384
+
385
+ compiler.compile_structure(cls)
386
+
380
387
  def cdef(cls, *, recursive: bool = False) -> str:
381
388
  """Render this structure (or union) back to its C-style definition.
382
389
 
@@ -579,7 +586,7 @@ class UnionMetaType(StructureMetaType):
579
586
  object.__setattr__(obj, "_endian", cls.__cs__.endian)
580
587
 
581
588
  # Calling with non-stream args or kwargs means we are initializing with values
582
- if (args and not (len(args) == 1 and (_is_readable_type(args[0]) or _is_buffer_type(args[0])))) or kwargs:
589
+ if (args and not (len(args) == 1 and (hasattr(args[0], "read") or _is_buffer_type(args[0])))) or kwargs:
583
590
  # We don't support user initialization of dynamic unions yet
584
591
  if cls.__dynamic__:
585
592
  raise NotImplementedError("Initializing a dynamic union is not yet supported")
@@ -656,6 +663,18 @@ class UnionMetaType(StructureMetaType):
656
663
  size = stream.tell() - start
657
664
  stream.seek(start)
658
665
  buf = stream.read(size)
666
+ elif "__init__" in cls.__dict__ and cls.__new__ is object.__new__:
667
+ # Fast path for static unions
668
+ buf = stream.read(cls.__size__)
669
+ result, sizes = cls._read_fields(io.BytesIO(buf), endian=endian)
670
+
671
+ obj: Union = object.__new__(cls)
672
+ obj.__dict__.update(result)
673
+ object.__setattr__(obj, "__dynamic_sizes__", sizes)
674
+ object.__setattr__(obj, "_buf", buf)
675
+ object.__setattr__(obj, "_endian", endian)
676
+ obj._proxify()
677
+ return obj
659
678
  else:
660
679
  result = {}
661
680
  sizes = {}
@@ -4,7 +4,7 @@ import sys
4
4
  from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar
5
5
 
6
6
  from dissect.cstruct.exception import ArraySizeError
7
- from dissect.cstruct.types.base import EOF, BaseArray, BaseType
7
+ from dissect.cstruct.types.base import EOF, BaseArray, BaseType, _is_seekable, _read_null_terminated
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from dissect.cstruct.cstruct import Endianness
@@ -72,10 +72,13 @@ class Wchar(str, BaseType):
72
72
  if count != EOF and len(data) != count:
73
73
  raise EOFError(f"Read {len(data)} bytes, but expected {count}")
74
74
 
75
- return type.__call__(cls, data.decode(cls.__encoding_map__[endian]))
75
+ return type.__call__(cls, str(data, cls.__encoding_map__[endian]))
76
76
 
77
77
  @classmethod
78
78
  def _read_0(cls, stream: BinaryIO, *, context: dict[str, Any] | None = None, endian: Endianness) -> Wchar:
79
+ if _is_seekable(stream):
80
+ return type.__call__(cls, _read_null_terminated(stream, 2).decode(cls.__encoding_map__[endian]))
81
+
79
82
  buf = []
80
83
  while True:
81
84
  point = stream.read(2)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dissect.cstruct
3
- Version: 5.0.dev9
3
+ Version: 5.0.dev11
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
@@ -0,0 +1,30 @@
1
+ dissect/cstruct/__init__.py,sha256=KOyNeUvu4c0JaAiyOfj7iftGwUIjTmD8MwHtFsLPLSU,1504
2
+ dissect/cstruct/bitbuffer.py,sha256=aNzY4lkWe8ffAc8j7FODXzwZc8gZwbey77UosyoYCsw,2711
3
+ dissect/cstruct/compiler.py,sha256=hhX1bxZFsPOcs6BUO82YHNtWqhKsiOb-H-d18Aa1Q6E,35148
4
+ dissect/cstruct/cstruct.py,sha256=VQDgGF7OUaPKQ_Wsy_2fUHL9Jlims6R2JOh-1_bgiZ8,26550
5
+ dissect/cstruct/exception.py,sha256=RqD08LuBkbMqa3iQ1A05DNN8XgEmQR_SUnguwe9LGo8,316
6
+ dissect/cstruct/expression.py,sha256=Y27-N48BomBoRFozbWhGDF_DS2lfklRwWVUbCzGnxHE,10873
7
+ dissect/cstruct/lexer.py,sha256=NDUfAWgyxgRNRuVO8ExXQ51LqQXS2mv9bywVa_M7tFQ,19665
8
+ dissect/cstruct/parser.py,sha256=5vz1frbenevKyn-CobKyp9_22dnEbFej_nUXQeL5W8U,21368
9
+ dissect/cstruct/util.py,sha256=vAf-kdOkk3zprW_gD6QmQeN3VIRgQqhPS4B_ha1jEpQ,18040
10
+ dissect/cstruct/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ dissect/cstruct/tools/stubgen.py,sha256=MeZkLmSeNSLNcAEwlAdIGv1lKvlvK3UQ4WN85ovsxTM,7672
12
+ dissect/cstruct/types/__init__.py,sha256=6P71Pu94Dv7RNjZpDZ19pqzx-G0QzmQw4q0-3zWALso,911
13
+ dissect/cstruct/types/base.py,sha256=10HLF2SDeWUMVc6ISMv8xKdEggqrxLPHnJMwI03DEFg,17216
14
+ dissect/cstruct/types/char.py,sha256=Rzjn2-pXbn-fV_UnNRGgQugFZ50mPuXQhcmgHvY5PR0,3172
15
+ dissect/cstruct/types/enum.py,sha256=nOdI6vGtqTfPMhOBkKuiuOriIB2YHSt8Q9ruri37s3U,9177
16
+ dissect/cstruct/types/flag.py,sha256=YxQHix8ZhK1qQX3J_Og7GJp_4JAxCwzUbUibuJeDaWQ,3479
17
+ dissect/cstruct/types/int.py,sha256=9RbdrkvAI28zATM97VVORQnras0XhLaVMtdPjJwpTH4,2089
18
+ dissect/cstruct/types/leb128.py,sha256=V97XTJT_Xbw1LpTwTN1OkjPHuQQAQUxd8OGuA6yEDmE,2387
19
+ dissect/cstruct/types/packed.py,sha256=NgCX0YWX8SH8z47atq0f39w9MBjU_eBFJtUisUWdO-M,3867
20
+ dissect/cstruct/types/pointer.py,sha256=FNuB9bfENWRebbKX-R6Vs6xWPMHepjvOhhomeUhr7I8,3985
21
+ dissect/cstruct/types/structure.py,sha256=WDMmfhP2XE5p1Bn-WgFFstfaWC709AU7_y-SGi3TyDw,39116
22
+ dissect/cstruct/types/void.py,sha256=fV4hKk50uop_EKbR1nfy1cdtAzvUYrSymXsdakCyFk8,1222
23
+ dissect/cstruct/types/wchar.py,sha256=qUbX6auj0qHWSOkgvaI7ZW_f7RGgwa-Hf_d_mDpntlM,3410
24
+ dissect_cstruct-5.0.dev11.dist-info/licenses/COPYRIGHT,sha256=H-18RXfshdH9AdHwW2eO1Xa-5s6tY5eipHh5c0whDu4,316
25
+ dissect_cstruct-5.0.dev11.dist-info/licenses/LICENSE,sha256=PhUqiw6jAh2KbBdVRPBq_hfAvfcTBin7nZ3CK7NQbTM,11341
26
+ dissect_cstruct-5.0.dev11.dist-info/METADATA,sha256=Wxf65kgjGnT9csqu2go1YVpp4RKcnFu_8smscSoywe8,9256
27
+ dissect_cstruct-5.0.dev11.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
28
+ dissect_cstruct-5.0.dev11.dist-info/entry_points.txt,sha256=z53zqZqwD2OLrAkRwrP4wTeiU9CQe7xrMly0T2c0_wQ,71
29
+ dissect_cstruct-5.0.dev11.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
30
+ dissect_cstruct-5.0.dev11.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (83.0.0)
2
+ Generator: setuptools (84.2.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,30 +0,0 @@
1
- dissect/cstruct/__init__.py,sha256=KOyNeUvu4c0JaAiyOfj7iftGwUIjTmD8MwHtFsLPLSU,1504
2
- dissect/cstruct/bitbuffer.py,sha256=aNzY4lkWe8ffAc8j7FODXzwZc8gZwbey77UosyoYCsw,2711
3
- dissect/cstruct/compiler.py,sha256=zcrO5CWCF2vWo2es-pFGn-Mvt-RTMh8W9bntK-hn85k,14343
4
- dissect/cstruct/cstruct.py,sha256=wC4Xd8MBxTCyl-IC1I2c3etI8M6C6D5yXVfELbfQk6c,25656
5
- dissect/cstruct/exception.py,sha256=RqD08LuBkbMqa3iQ1A05DNN8XgEmQR_SUnguwe9LGo8,316
6
- dissect/cstruct/expression.py,sha256=MEwqHGgqA2fUk4kYk4lRLDWNTAMhB4-saJ5BgTxl7OA,7956
7
- dissect/cstruct/lexer.py,sha256=NDUfAWgyxgRNRuVO8ExXQ51LqQXS2mv9bywVa_M7tFQ,19665
8
- dissect/cstruct/parser.py,sha256=xCK-1O8c86sVFvjaXXSRgTsJWWd0ncKM6KJf2wbyGG8,21348
9
- dissect/cstruct/util.py,sha256=vAf-kdOkk3zprW_gD6QmQeN3VIRgQqhPS4B_ha1jEpQ,18040
10
- dissect/cstruct/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- dissect/cstruct/tools/stubgen.py,sha256=MeZkLmSeNSLNcAEwlAdIGv1lKvlvK3UQ4WN85ovsxTM,7672
12
- dissect/cstruct/types/__init__.py,sha256=6P71Pu94Dv7RNjZpDZ19pqzx-G0QzmQw4q0-3zWALso,911
13
- dissect/cstruct/types/base.py,sha256=vJUgrnsPg2ZA9Mel2P9JBBstI9z9oMxqi5Pnx9FlBIA,15023
14
- dissect/cstruct/types/char.py,sha256=zsRMlcZGW1cHYH_xQBNORDnM_a5CXcuZLGly1N1i_Ms,3029
15
- dissect/cstruct/types/enum.py,sha256=j2U6oE_80c4H2505YMddHPnF99az2K5IuDhX40Q7OEI,8590
16
- dissect/cstruct/types/flag.py,sha256=7xxQjFEDPHSQOxBHgcc75WzPiAxflOquwr7Z7c3erLE,2347
17
- dissect/cstruct/types/int.py,sha256=RCT3YjrajqRqh8cyeM-zaqzCmBfeJrXkD5W1FcRzXag,1340
18
- dissect/cstruct/types/leb128.py,sha256=V97XTJT_Xbw1LpTwTN1OkjPHuQQAQUxd8OGuA6yEDmE,2387
19
- dissect/cstruct/types/packed.py,sha256=QF1mAqgxLbgiibRZLhn6cp6SnuH2IxjGr9DsQdXCCSE,2713
20
- dissect/cstruct/types/pointer.py,sha256=FNuB9bfENWRebbKX-R6Vs6xWPMHepjvOhhomeUhr7I8,3985
21
- dissect/cstruct/types/structure.py,sha256=QZBVCCERu9eoXLqrumF7Kqy0gudywl12-cSZx6n3tPI,38402
22
- dissect/cstruct/types/void.py,sha256=fV4hKk50uop_EKbR1nfy1cdtAzvUYrSymXsdakCyFk8,1222
23
- dissect/cstruct/types/wchar.py,sha256=X-dRu6ujjQIIsBfzKbujwMO5skKdARtptF6P7R5v8Jo,3232
24
- dissect_cstruct-5.0.dev9.dist-info/licenses/COPYRIGHT,sha256=H-18RXfshdH9AdHwW2eO1Xa-5s6tY5eipHh5c0whDu4,316
25
- dissect_cstruct-5.0.dev9.dist-info/licenses/LICENSE,sha256=PhUqiw6jAh2KbBdVRPBq_hfAvfcTBin7nZ3CK7NQbTM,11341
26
- dissect_cstruct-5.0.dev9.dist-info/METADATA,sha256=1TPbiY0D5dnQscZ0QDgEJvsSjlguJxBNXgqM3_Xf0V4,9255
27
- dissect_cstruct-5.0.dev9.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
28
- dissect_cstruct-5.0.dev9.dist-info/entry_points.txt,sha256=z53zqZqwD2OLrAkRwrP4wTeiU9CQe7xrMly0T2c0_wQ,71
29
- dissect_cstruct-5.0.dev9.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
30
- dissect_cstruct-5.0.dev9.dist-info/RECORD,,