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 au32express id, orNoneif the value does not fit.