Skip to main content

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}