altium_format/api/
document.rs1use std::collections::HashMap;
4use std::fs::File;
5use std::io::{Read, Seek};
6use std::path::Path;
7
8use crate::api::cfb::{AltiumCfb, AltiumFileType};
9use crate::api::generic::{BinaryContainer, ParamsContainer};
10use crate::error::Result;
11
12pub struct AltiumDocument<R: Read + Seek> {
17 cfb: AltiumCfb<R>,
19 params_containers: HashMap<String, ParamsContainer>,
21 binary_containers: HashMap<String, BinaryContainer>,
23}
24
25impl AltiumDocument<File> {
26 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
28 let cfb = AltiumCfb::open_file(path)?;
29 Ok(AltiumDocument {
30 cfb,
31 params_containers: HashMap::new(),
32 binary_containers: HashMap::new(),
33 })
34 }
35}
36
37impl<R: Read + Seek> AltiumDocument<R> {
38 pub fn from_reader(reader: R) -> Result<Self> {
40 let cfb = AltiumCfb::open(reader)?;
41 Ok(AltiumDocument {
42 cfb,
43 params_containers: HashMap::new(),
44 binary_containers: HashMap::new(),
45 })
46 }
47
48 pub fn cfb(&mut self) -> &mut AltiumCfb<R> {
52 &mut self.cfb
53 }
54
55 pub fn file_type(&self) -> AltiumFileType {
57 self.cfb.file_type()
58 }
59
60 pub fn params(&mut self, stream_path: &str) -> Result<&ParamsContainer> {
66 if !self.params_containers.contains_key(stream_path) {
67 let blocks = self.cfb.read_blocks(stream_path)?;
68 let container = ParamsContainer::from_blocks(stream_path, &blocks);
69 self.params_containers
70 .insert(stream_path.to_string(), container);
71 }
72 Ok(self.params_containers.get(stream_path).unwrap())
73 }
74
75 pub fn params_mut(&mut self, stream_path: &str) -> Result<&mut ParamsContainer> {
77 if !self.params_containers.contains_key(stream_path) {
78 let blocks = self.cfb.read_blocks(stream_path)?;
79 let container = ParamsContainer::from_blocks(stream_path, &blocks);
80 self.params_containers
81 .insert(stream_path.to_string(), container);
82 }
83 Ok(self.params_containers.get_mut(stream_path).unwrap())
84 }
85
86 pub fn binary(&mut self, stream_path: &str) -> Result<&BinaryContainer> {
88 if !self.binary_containers.contains_key(stream_path) {
89 let blocks = self.cfb.read_blocks(stream_path)?;
90 let container = BinaryContainer::from_blocks(stream_path, &blocks);
91 self.binary_containers
92 .insert(stream_path.to_string(), container);
93 }
94 Ok(self.binary_containers.get(stream_path).unwrap())
95 }
96
97 pub fn binary_mut(&mut self, stream_path: &str) -> Result<&mut BinaryContainer> {
99 if !self.binary_containers.contains_key(stream_path) {
100 let blocks = self.cfb.read_blocks(stream_path)?;
101 let container = BinaryContainer::from_blocks(stream_path, &blocks);
102 self.binary_containers
103 .insert(stream_path.to_string(), container);
104 }
105 Ok(self.binary_containers.get_mut(stream_path).unwrap())
106 }
107
108 pub fn component_names(&mut self) -> Result<Vec<String>> {
112 self.cfb.list_components()
113 }
114
115 pub fn resolve_component(&mut self, name: &str) -> Result<String> {
117 self.cfb.resolve_section(name)
118 }
119
120 pub fn clear_cache(&mut self) {
122 self.params_containers.clear();
123 self.binary_containers.clear();
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 }