建立 MAG160C 逆向工程交接仓库
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
from typing import IO, TYPE_CHECKING
|
||||
|
||||
from .binary import encode_bin, decode_bin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Buffer # 3.12+
|
||||
from typing_extensions import Self # 3.11+
|
||||
|
||||
|
||||
class BitStream(io.RawIOBase, IO[bytes]):
|
||||
|
||||
__slots__ = ("substream",)
|
||||
|
||||
def __init__(self, substream: IO[bytes]) -> None:
|
||||
self.substream = substream
|
||||
|
||||
def __enter__(self) -> Self:
|
||||
return self
|
||||
|
||||
|
||||
class BitStreamReader(BitStream):
|
||||
|
||||
__slots__ = ("buffer", "total_size")
|
||||
|
||||
def __init__(self, substream: IO[bytes]) -> None:
|
||||
super().__init__(substream)
|
||||
self.total_size = 0
|
||||
self.buffer = b""
|
||||
|
||||
def close(self) -> None:
|
||||
if self.total_size % 8 != 0:
|
||||
raise ValueError("total size of read data must be a multiple of 8",
|
||||
self.total_size)
|
||||
|
||||
def tell(self) -> int:
|
||||
return self.substream.tell()
|
||||
|
||||
def seek(self, pos: int, whence: int = 0) -> int:
|
||||
self.buffer = b""
|
||||
self.total_size = 0
|
||||
self.substream.seek(pos, whence)
|
||||
return 0
|
||||
|
||||
def read(self, count: int = -1) -> bytes:
|
||||
if count < 0:
|
||||
raise ValueError("count cannot be negative")
|
||||
|
||||
l = len(self.buffer)
|
||||
if count == 0:
|
||||
data = b""
|
||||
elif count <= l:
|
||||
data = self.buffer[:count]
|
||||
self.buffer = self.buffer[count:]
|
||||
else:
|
||||
data = self.buffer
|
||||
count -= l
|
||||
bytes = count // 8
|
||||
if count & 7:
|
||||
bytes += 1
|
||||
buf = encode_bin(self.substream.read(bytes))
|
||||
data += buf[:count]
|
||||
self.buffer = buf[count:]
|
||||
self.total_size += len(data)
|
||||
return data
|
||||
|
||||
|
||||
class BitStreamWriter(BitStream):
|
||||
|
||||
__slots__ = ("buffer", "pos")
|
||||
|
||||
def __init__(self, substream: IO[bytes]) -> None:
|
||||
super().__init__(substream)
|
||||
self.buffer: list[bytes] = []
|
||||
self.pos = 0
|
||||
|
||||
def close(self) -> None:
|
||||
self.flush()
|
||||
|
||||
def flush(self) -> None:
|
||||
bytes = decode_bin(b"".join(self.buffer))
|
||||
self.substream.write(bytes)
|
||||
self.buffer = []
|
||||
self.pos = 0
|
||||
|
||||
def tell(self) -> int:
|
||||
return self.substream.tell() + self.pos // 8
|
||||
|
||||
def seek(self, pos: int, whence: int = 0) -> int:
|
||||
self.flush()
|
||||
return self.substream.seek(pos, whence)
|
||||
|
||||
def write(self, data: Buffer) -> int:
|
||||
if not data:
|
||||
return 0
|
||||
if type(data) is not bytes:
|
||||
raise TypeError("data must be a bytes, not %r" % (type(data),))
|
||||
self.buffer.append(data)
|
||||
return len(data)
|
||||
Reference in New Issue
Block a user