use std::collections::HashMap;
use std::fs::File;
use std::io::{Read, Seek};
use std::path::Path;
use crate::api::cfb::{AltiumCfb, AltiumFileType};
use crate::api::generic::{BinaryContainer, ParamsContainer};
use crate::error::Result;
pub struct AltiumDocument<R: Read + Seek> {
cfb: AltiumCfb<R>,
params_containers: HashMap<String, ParamsContainer>,
binary_containers: HashMap<String, BinaryContainer>,
}
impl AltiumDocument<File> {
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
let cfb = AltiumCfb::open_file(path)?;
Ok(AltiumDocument {
cfb,
params_containers: HashMap::new(),
binary_containers: HashMap::new(),
})
}
}
impl<R: Read + Seek> AltiumDocument<R> {
pub fn from_reader(reader: R) -> Result<Self> {
let cfb = AltiumCfb::open(reader)?;
Ok(AltiumDocument {
cfb,
params_containers: HashMap::new(),
binary_containers: HashMap::new(),
})
}
pub fn cfb(&mut self) -> &mut AltiumCfb<R> {
&mut self.cfb
}
pub fn file_type(&self) -> AltiumFileType {
self.cfb.file_type()
}
pub fn params(&mut self, stream_path: &str) -> Result<&ParamsContainer> {
if !self.params_containers.contains_key(stream_path) {
let blocks = self.cfb.read_blocks(stream_path)?;
let container = ParamsContainer::from_blocks(stream_path, &blocks);
self.params_containers
.insert(stream_path.to_string(), container);
}
Ok(self.params_containers.get(stream_path).unwrap())
}
pub fn params_mut(&mut self, stream_path: &str) -> Result<&mut ParamsContainer> {
if !self.params_containers.contains_key(stream_path) {
let blocks = self.cfb.read_blocks(stream_path)?;
let container = ParamsContainer::from_blocks(stream_path, &blocks);
self.params_containers
.insert(stream_path.to_string(), container);
}
Ok(self.params_containers.get_mut(stream_path).unwrap())
}
pub fn binary(&mut self, stream_path: &str) -> Result<&BinaryContainer> {
if !self.binary_containers.contains_key(stream_path) {
let blocks = self.cfb.read_blocks(stream_path)?;
let container = BinaryContainer::from_blocks(stream_path, &blocks);
self.binary_containers
.insert(stream_path.to_string(), container);
}
Ok(self.binary_containers.get(stream_path).unwrap())
}
pub fn binary_mut(&mut self, stream_path: &str) -> Result<&mut BinaryContainer> {
if !self.binary_containers.contains_key(stream_path) {
let blocks = self.cfb.read_blocks(stream_path)?;
let container = BinaryContainer::from_blocks(stream_path, &blocks);
self.binary_containers
.insert(stream_path.to_string(), container);
}
Ok(self.binary_containers.get_mut(stream_path).unwrap())
}
pub fn component_names(&mut self) -> Result<Vec<String>> {
self.cfb.list_components()
}
pub fn resolve_component(&mut self, name: &str) -> Result<String> {
self.cfb.resolve_section(name)
}
pub fn clear_cache(&mut self) {
self.params_containers.clear();
self.binary_containers.clear();
}
}
#[cfg(test)]
mod tests {
}