ifcviewer: extract pure buffer-based sidecar parse + read-plan helpers

Splits the v13 metadata wire-format knowledge out of the FILE*-bound
streaming reader into pure, buffer-based functions so the web byte-range
path (#88) can reuse it without loading the whole sidecar into the wasm
heap:

  - parseSidecarHead  — validates the 16-byte head, yields num_vertex_bytes
  - parseSidecarTail  — parses meshes/instances/georef/elements/strings
                        from an in-memory tail buffer, bounds-checked
  - planSidecarReadRanges + SidecarReadPlan — the range-coalescing /
    scatter planner, promoted out of the anonymous namespace

readSidecarMetadataOnly and the range readers now call these; desktop
behaviour is unchanged (head + tail are small, the bulk is still skipped
via seek). The metadata tail is split from the head around the bulk
sections, so a blob-backed loader just slices those two regions and
hands the bytes to the same parsers.

Closes a coverage gap: StreamingLoader had no unit tests. Adds
test_streaming_loader.cpp (7 cases: metadata round-trip, corrupt/truncated
rejection, vertex+index range scatter, head validation, tail truncation,
read-plan coalescing). 107/107 unit tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-06-29 15:26:29 +10:00
parent fcf3a645db
commit a0ba3c0b98
4 changed files with 425 additions and 75 deletions
+9
View File
@@ -50,6 +50,15 @@ add_ifcviewer_unit_test(test_sidecar_cache
SOURCES ${IFCVIEWER_SRC}/SidecarCache.cpp
)
# StreamingLoader: metadata-only read + range readers + the pure buffer-based
# parse / read-plan helpers shared with the web (Blob.slice) path. Needs
# SidecarCache.cpp for writeSidecar (to lay down on-disk fixtures).
add_ifcviewer_unit_test(test_streaming_loader
SOURCES
${IFCVIEWER_SRC}/StreamingLoader.cpp
${IFCVIEWER_SRC}/SidecarCache.cpp
)
add_ifcviewer_unit_test(test_instanced_geometry)
# ChunkPlanner: Morton sort + greedy-pack — pure CPU, no Qt / no wgpu.