pub mod container;
pub mod decode;
pub mod geometry;
pub mod nurbs;
pub mod parasolid;
pub mod topology;
use std::collections::BTreeMap;
use cadmpeg_ir::codec::{
Codec, CodecError, Confidence, ContainerEntry, ContainerSummary, DecodeOptions, DecodeResult,
ReadSeek,
};
#[derive(Debug, Default, Clone, Copy)]
pub struct NxCodec;
impl Codec for NxCodec {
fn id(&self) -> &'static str {
"nx"
}
fn detect(&self, prefix: &[u8]) -> Confidence {
if container::looks_like_nx(prefix) {
Confidence::High
} else {
Confidence::No
}
}
fn inspect(&self, reader: &mut dyn ReadSeek) -> Result<ContainerSummary, CodecError> {
let scan = decode::scan(reader)?;
Ok(summarize(&scan))
}
fn decode(
&self,
reader: &mut dyn ReadSeek,
options: &DecodeOptions,
) -> Result<DecodeResult, CodecError> {
decode::decode(reader, options)
}
}
fn summarize(scan: &decode::Scan) -> ContainerSummary {
let mut entries = Vec::new();
for entry in &scan.container.entries {
let mut attributes = BTreeMap::new();
attributes.insert("region".to_string(), entry.region.label().to_string());
let (compressed, uncompressed) = match entry.file_span {
Some((off, size)) => {
attributes.insert("file_offset".to_string(), off.to_string());
(size, size)
}
None => {
attributes.insert("kind".to_string(), "directory".to_string());
(0, 0)
}
};
entries.push(ContainerEntry {
name: entry.name.clone(),
role: "stream".to_string(),
compression: "none".to_string(),
compressed_size: compressed,
uncompressed_size: uncompressed,
attributes,
});
}
for (si, stream) in scan.streams.iter().enumerate() {
let mut attributes = BTreeMap::new();
attributes.insert("file_offset".to_string(), stream.file_offset.to_string());
attributes.insert("kind".to_string(), stream.kind.label().to_string());
if let Some(schema) = &stream.schema {
attributes.insert("schema".to_string(), schema.clone());
}
entries.push(ContainerEntry {
name: format!("parasolid#{si}"),
role: if stream.kind.is_parasolid() {
"parasolid-stream".to_string()
} else {
"preview".to_string()
},
compression: "zlib".to_string(),
compressed_size: 0,
uncompressed_size: stream.inflated.len() as u64,
attributes,
});
}
ContainerSummary {
format: "nx".to_string(),
container_kind: "splmsstr".to_string(),
entries,
notes: decode::summary_notes(scan),
}
}
#[cfg(test)]
mod tests;