Module express_id

Module express_id 

Source
Expand description

The single place in this crate that decides whether a digit run read from a raw IFC byte slice fits an express id.

ISO 10303-21 writes an instance name (#<digits>) with no upper bound, so a file MAY legally contain #4294967297. Nothing downstream of this crate can hold one: every store that keys on an express id narrows it to u32. Accumulating with wrapping_mul/wrapping_add does not error on an oversized run, it silently maps it onto a real low-numbered id — a value collision, not a missing value (issue #3395, split for the reference readers in #3421).

parse_express_id and the internal prefix reader serve both sides: the definition scanner ([crate::parser::scanner::EntityScanner]) and every #<digits> reference reader in crate::fast_parse and crate::decoder, and — now that it is pub — the REFERENCE readers in ifc-lite-geometry, ifc-lite-export and ifc-lite-processing that read raw STEP bytes outside this crate. A second, independently-written copy of this accumulation is exactly the drift #3395 was careful to avoid. New callers reuse these canonical readers, which share the digit arithmetic.

The bound is inclusive: u32::MAX is a legitimate express id and parses successfully. Refusal (None) is the only outcome for anything past it — there is no saturating variant here. A caller that saturated an oversized reference to u32::MAX would risk binding it to a real entity that legitimately holds that id, which is the same collision this function exists to prevent, just relocated to the sentinel value. Contrast crate::fast_parse::parse_indices_direct, which deliberately saturates an out-of-range vertex index to u32::MAX: that value is a sentinel a downstream bounds check drops, not a key another value could collide with, so saturation is safe there and is not safe here.

Functions§

parse_express_id
Parse digits — an already-validated, non-empty run of ASCII digit bytes — into a u32 express id, or None if the value does not fit.