"""The MyIni2CK container: magic, XOR scrambling, A2F compression. Boxsim uses one container for project files (`.bpj`) and driver files (`.bch`). """ from __future__ import annotations from . import a2f from .krypt import unscramble MAGIC = b"MyIni2CK" class ContainerError(ValueError): pass def is_container(raw: bytes) -> bool: return raw[: len(MAGIC)] == MAGIC def decode(raw: bytes) -> bytes: """Decode a Boxsim container to its raw INI payload.""" if not is_container(raw): raise ContainerError( f"not a MyIni2CK file (magic {raw[:8]!r}, expected {MAGIC!r})" ) # The compressed layer reads its own 8 byte header back, so hand it the # magic followed by the descrambled body exactly as Boxsim does. return a2f.expand(MAGIC + unscramble(raw[len(MAGIC) :])) def decode_text(raw: bytes) -> str: """Decode to text. Boxsim writes Windows-1252 with CRLF line ends.""" return decode(raw).decode("cp1252")