1from __future__ import annotations
2
3from typing import TYPE_CHECKING, Any, BinaryIO
4
5from dissect.cstruct.types.base import BaseType
6from dissect.cstruct.utils import ENDIANNESS_MAP
7
8if TYPE_CHECKING:
9 from typing_extensions import Self
10
11
12class Int(int, BaseType):
13 """Integer type that can span an arbitrary amount of bytes."""
14
15 signed: bool
16
17 @classmethod
18 def _read(cls, stream: BinaryIO, context: dict[str, Any] | None = None) -> Self:
19 data = stream.read(cls.size)
20
21 if len(data) != cls.size:
22 raise EOFError(f"Read {len(data)} bytes, but expected {cls.size}")
23
24 return cls.from_bytes(data, ENDIANNESS_MAP[cls.cs.endian], signed=cls.signed)
25
26 @classmethod
27 def _read_0(cls, stream: BinaryIO, context: dict[str, Any] | None = None) -> Self:
28 result = []
29
30 while True:
31 if (value := cls._read(stream, context)) == 0:
32 break
33
34 result.append(value)
35
36 return result
37
38 @classmethod
39 def _write(cls, stream: BinaryIO, data: int) -> int:
40 return stream.write(data.to_bytes(cls.size, ENDIANNESS_MAP[cls.cs.endian], signed=cls.signed))