ifc_lite_wasm/api/export_step.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! WASM API: export_step — re-serialize the parsed model to STEP/IFC (ISO-10303-21).
6
7use super::IfcAPI;
8use wasm_bindgen::prelude::*;
9
10#[wasm_bindgen]
11impl IfcAPI {
12 /// Re-serialize the model in `content` to STEP/IFC UTF-8 bytes.
13 ///
14 /// Returned as UTF-8 bytes (`Uint8Array`) so output is not capped by the
15 /// V8 max-string ceiling (~512 MB); decode with `TextDecoder` when a string
16 /// is genuinely needed.
17 ///
18 /// `schema` is the FILE_SCHEMA label to write (empty ⇒ preserve the source schema).
19 /// `included` is an express-id allowlist (empty ⇒ whole model); when set, the forward
20 /// `#`-reference closure is added so the subset never dangles a reference.
21 /// `mutations_json` carries `MutablePropertyView` edits (attribute updates +
22 /// property-set synthesis); empty ⇒ none. See `export_step_json` for the shape.
23 #[wasm_bindgen(js_name = exportStep)]
24 pub fn export_step(
25 &self,
26 content: &[u8],
27 schema: String,
28 included: &[u32],
29 mutations_json: String,
30 ) -> Vec<u8> {
31 ifc_lite_export::export_step_json(
32 content,
33 if schema.is_empty() { None } else { Some(schema) },
34 if included.is_empty() { None } else { Some(included.to_vec()) },
35 &mutations_json,
36 )
37 .into_bytes()
38 }
39
40 /// Merge several IFC models into one STEP/IFC UTF-8 byte buffer (`Uint8Array`).
41 /// `concatenated` is every model's
42 /// bytes laid end-to-end; `lengths[i]` is the byte length of model `i`. The first model
43 /// keeps its ids; later models are id-offset and their project unified to the first.
44 #[wasm_bindgen(js_name = exportMerged)]
45 pub fn export_merged(&self, concatenated: &[u8], lengths: &[u32], schema: String) -> Vec<u8> {
46 // Strict segmentation: a malformed `lengths` (overflow, out-of-bounds, or not
47 // summing to the buffer) must surface an error rather than silently dropping a
48 // model and returning a partial merge.
49 let mut models: Vec<&[u8]> = Vec::with_capacity(lengths.len());
50 let mut off = 0usize;
51 for &len in lengths {
52 let end = off.checked_add(len as usize).unwrap_or_else(|| {
53 wasm_bindgen::throw_str("exportMerged: segment length overflow")
54 });
55 if end > concatenated.len() {
56 wasm_bindgen::throw_str("exportMerged: segment lengths exceed concatenated buffer");
57 }
58 models.push(&concatenated[off..end]);
59 off = end;
60 }
61 if off != concatenated.len() {
62 wasm_bindgen::throw_str("exportMerged: segment lengths do not cover the whole buffer");
63 }
64 let opts = ifc_lite_export::MergedOptions {
65 schema: if schema.is_empty() { None } else { Some(schema) },
66 ..Default::default()
67 };
68 ifc_lite_export::export_merged(&models, &opts).into_bytes()
69 }
70}