use super::record::EscherRecord;
use super::container::{EscherContainer, EscherChildIterator};
use super::types::EscherRecordType;
use crate::ole::ppt::package::Result;
pub struct EscherParser<'data> {
data: &'data [u8],
}
impl<'data> EscherParser<'data> {
#[inline]
pub fn new(data: &'data [u8]) -> Self {
Self { data }
}
pub fn root_container(&self) -> Option<Result<EscherContainer<'data>>> {
if self.data.len() < 8 {
return None;
}
match EscherRecord::parse(self.data, 0) {
Ok((record, _)) if record.is_container() => {
Some(Ok(EscherContainer::new(record)))
}
Ok(_) => None,
Err(e) => Some(Err(e)),
}
}
#[inline]
pub fn records(&self) -> EscherChildIterator<'data> {
EscherChildIterator::new(self.data)
}
pub fn find_all_shapes(&self) -> Result<Vec<EscherRecord<'data>>> {
let mut shapes = Vec::new();
if let Some(root_result) = self.root_container() {
let root = root_result?;
shapes.extend(root.find_recursive(EscherRecordType::SpContainer));
}
Ok(shapes)
}
pub fn find_all_textboxes(&self) -> Result<Vec<EscherRecord<'data>>> {
let mut textboxes = Vec::new();
if let Some(root_result) = self.root_container() {
let root = root_result?;
textboxes.extend(root.find_recursive(EscherRecordType::ClientTextbox));
}
Ok(textboxes)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parser_creation() {
let data = vec![
0x0F, 0x00, 0x02, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, ];
let parser = EscherParser::new(&data);
let root = parser.root_container().unwrap().unwrap();
assert_eq!(root.record().record_type, EscherRecordType::DgContainer);
}
}