cadmpeg-asm
cadmpeg-asm parses Autodesk Shape Manager binary model streams. It reads
BinaryFile4 and BinaryFile8 headers, frames SAB token streams, locates the
boundary between solved records and construction history, and reports byte
locations for payload fields. Format codecs import its asm_header and sab
modules directly.
Install
Parse ASM headers
asm_header::has_asm_magic recognizes the 15-byte ASM BinaryFile4 and
ASM BinaryFile8 prefixes. asm_header::parse returns an AsmHeader
with width, save_format_version, record_count, entity_count, flags,
product strings, and tolerance fields that the input provides. A missing magic
returns None; a recognized but incomplete header returns an AsmHeader with
unavailable fields set to None.
BinaryFile4 stores the save-format version, record count, entity count, and
flags as little-endian u32 words at offsets 15, 19, 23, and 27. Its string
region begins at byte 31. BinaryFile8 stores the save-format version at byte
15, the entity count as a little-endian u64 at byte 31, and flags as a
little-endian u64 at byte 39. Its string region begins at byte 47. Both
layouts carry three 0x07-tagged strings followed by three 0x06-tagged
little-endian f64 values. The values populate product_family,
product_version, save_date, scale, linear (resabs), and angular
(resnor).
AsmHeader::save_format_major and save_format_minor split the encoded
save-format version, where 100 * major + minor is the stored value.
AsmHeader::has_history_partition reads HISTORY_PARTITION_FLAG
from flags. FORMAT_REVISION_FLAGS identifies bits 1 through 7;
AsmHeader::format_revision reads them. AsmHeader::unassigned_flags preserves
the remaining flag bits.
asm_header::record_stream_start returns the byte after the fixed words, the
three strings, and the three tolerance values. asm_header::solved_record_limit
attempts to locate the history partition's first record when the header
declares HISTORY_PARTITION_FLAG. It recognizes the
Begin-of-ASM-History-Data preamble and the earlier delta_state boundary.
asm_header::stream_ref_width returns the declared integer/reference width in
bytes and uses 8 when the header is unreadable.
Frame SAB records
sab::frame(bytes, start, limit, ref_width) returns a Vec<Record> for the
requested byte range. ref_width is the stream's integer and reference width,
usually 4 or 8. A 0x11 tag terminates a record at subtype depth zero.
frame stops at the supplied limit, at the end of bytes, or at the
delta_state history boundary. sab::frame_history accepts a final history
record that ends at the supplied limit without a 0x11 terminator.
An unknown tag or truncated payload returns FrameError, which
stores the byte offset and a reason string. Framing preserves recognized
payload tokens, record names, and record extents. A Record contains
the zero-based index, the hyphen-joined name, its leading head, the
retained tokens in an Arc<[Token]>, the starting offset, and the byte
len including the record terminator when present.
Record names use 0x0e sub-identifiers followed by a 0x0d identifier. Those
tags become Token::SubIdent and Token::Ident when they occur in a payload.
Token::is_payload_ident identifies those payload identifiers.
Record::chunks, Record::chunk, and Record::chunk_len index value tokens
and skip them. Record::ref_at returns a non-null Token::Ref value at a
chunk index; the -1 null reference produces None.
The framer maps SAB tags to Token variants as follows:
| Tags | Variants |
|---|---|
0x02, 0x03, 0x04, 0x05, 0x06 |
Char(u8), Short(i16), Long(i64), Float(f32), Double(f64) |
0x07, 0x08, 0x09, 0x12 |
Str(String) with one-byte, two-byte, or ref_width length prefixes |
0x0a, 0x0b, 0x0c |
True, False, Ref(i64) |
0x0f, 0x10 |
SubtypeOpen, SubtypeClose |
0x13, 0x14, 0x16 |
Position([f64; 3]), Vector3([f64; 3]), Vector2([f64; 2]) |
0x15, 0x17 |
Enum(i64), Int64(i64) |
payload 0x0d, 0x0e |
Ident(String), SubIdent(String) |
Long, Ref, and Enum use ref_width. Int64 always uses eight bytes.
The 0x11 record terminator is a framing control tag and has no Token
variant.
Locate payload bytes
sab::payload_token_offset returns the absolute byte offset for a value token
at a record's chunk index. sab::payload_token_offsets returns all absolute
offsets for a selected payload tag and reports a FrameError
when the record cannot be lexed. Both helpers use the same value-token indexing
as Record::chunk.
sab::payload_subtype_range returns the absolute byte range inside the subtype
at a chunk index when its following identifier matches the requested name. The
range starts after that identifier and ends before the matching
Token::SubtypeClose; nested subtype scopes remain in the range.
Frame a synthetic SAB record:
use ;
Documentation
Requires Rust 1.88 or later. Licensed under Apache-2.0.