skppy.parser_legacy.binary

Read little-endian primitives and MFC-style object tags from legacy SKP.

Pre-ZIP files use one ordered index namespace for both runtime classes and objects. ArchiveIndexTable preserves that identity model, while LegacyArchiveReader decodes scalar values, legacy UTF-16 strings, and compact or extended object/class tags. Higher-level legacy readers should use one shared archive session rather than constructing independent tables.

Example

import io

reader = LegacyArchiveReader(io.BytesIO(b"*"))
assert reader.read_u32() == 42
class skppy.parser_legacy.binary.ArchiveIndexEntry[source]

Bases: object

One entry in the shared CArchive class/object index table.

__init__(index: int, kind: Literal['class', 'object'], class_name: str | None, schema: int | None) None
class skppy.parser_legacy.binary.ArchiveIndexTable[source]

Bases: object

Shared CArchive index table for runtime classes and object instances.

MFC uses one monotonically increasing index space for both entry kinds. Splitting this into independent class and object counters shifts every subsequent back-reference and usually corrupts face topology much later.

__init__() None[source]

Create an empty table with index zero reserved for null objects.

property entries: tuple[ArchiveIndexEntry, ...]

Return entries in archive-index order.

register_class(class_name: str | None, schema: int | None) int[source]

Append a runtime-class entry and return its archive index.

register_implicit_object(class_name: str, schema: int | None = None) ArchiveObjectRegistration[source]

Register an implicit root-like object not preceded by an archive tag.

register_new_object_tag(tag: ArchiveObjectTag) ArchiveObjectRegistration | None[source]

Register table entries implied by an object-context archive tag.

register_object(class_name: str | None, schema: int | None) int[source]

Append an object-instance entry and return its archive index.

resolve_class(index: int | None) ArchiveIndexEntry | None[source]

Return a class entry by index, or None when it is unknown.

resolve_object(index: int | None) ArchiveIndexEntry | None[source]

Return an object entry by index, or None when it is unknown.

resolve_or_register_object_tag(tag: ArchiveObjectTag) ArchiveObjectHandle[source]

Resolve an object tag, registering new entries in archive order.

class skppy.parser_legacy.binary.ArchiveObjectHandle[source]

Bases: object

Object-context tag resolved against the archive index table.

__init__(kind: Literal['null', 'object_ref', 'new_object'], tag: ArchiveObjectTag, object_index: int | None, class_index: int | None, class_name: str | None, schema: int | None) None
class skppy.parser_legacy.binary.ArchiveObjectRegistration[source]

Bases: object

Indices allocated while reading one new object payload.

__init__(class_index: int | None, object_index: int, class_name: str | None, schema: int | None) None
class skppy.parser_legacy.binary.ArchiveObjectTag[source]

Bases: object

Decoded object/class tag from an old MFC-style archive.

__init__(kind: Literal['null', 'object_ref', 'new_class', 'class_ref'], raw_tag: int, index: int | None = None, schema: int | None = None, class_name: str | None = None) None
class skppy.parser_legacy.binary.LegacyArchiveBuffer[source]

Bases: RawIOBase

Seekable in-memory stream with allocation-free scalar decoding.

__init__(data: bytes) None[source]

Wrap immutable archive bytes and start at offset zero.

read(size: int = -1) bytes[source]

Read at most size bytes and advance the cursor.

readable() bool[source]

Return whether this stream supports reading.

seek(offset: int, whence: int = 0) int[source]

Move the cursor using standard binary-stream seek semantics.

seekable() bool[source]

Return whether this stream supports random access.

tell() int[source]

Return the current byte offset.

unpack_scalar(fmt: str, size: int) Any[source]

Decode one scalar at the cursor without allocating a byte slice.

class skppy.parser_legacy.binary.LegacyArchiveReader[source]

Bases: object

Cursor for primitive values and CArchive object/class tags.

__init__(stream: BinaryIO) None[source]

Store the binary stream used by this reader.

read_bool() bool[source]

Read the one-byte boolean representation used by CArchive.

read_exact(size: int, label: str) bytes[source]

Read an exact byte span from the current stream position.

read_f32() float[source]

Read one little-endian 32-bit float.

read_f64() float[source]

Read one little-endian 64-bit float.

read_i32() int[source]

Read one little-endian signed 32-bit integer.

read_legacy_utf16_string(label: str) str[source]

Read the old BOM-prefixed SketchUp UTF-16 string format.

read_object_tag() ArchiveObjectTag[source]

Read a CArchive object/class marker without consuming payload data.

read_rgba() tuple[int, int, int, int][source]

Read a four-byte CColor payload as RGBA bytes.

read_u16() int[source]

Read one little-endian unsigned 16-bit integer.

read_u32() int[source]

Read one little-endian unsigned 32-bit integer.

read_u64() int[source]

Read one little-endian unsigned 64-bit integer.

read_u8() int[source]

Read one unsigned byte.

read_vec3_f64() tuple[float, float, float][source]

Read a point/vector/unit-vector triple of doubles.

read_vec4_f64() tuple[float, float, float, float][source]

Read four doubles such as a SketchUp plane equation.

tell() int[source]

Return the current stream offset.