use std;
use std::io::Read;
use crate::ole::util::FromSlice;
impl<'ole> super::ole::Reader<'ole> {
pub(crate) fn parse_header(&mut self) -> Result<(), super::error::Error> {
let mut header: std::vec::Vec<u8>
= vec![0u8; super::constants::HEADER_SIZE];
self.read(&mut header)?;
let result: Result<(), super::error::Error>;
if &super::constants::IDENTIFIER != &header[0..8] {
result = Err(super::error::Error::InvalidOLEFile);
} else {
self.uid = header[8..24].to_vec();
let mut rv_number = usize::from_slice(&header[24..26]);
self.revision_number = Some(rv_number as u16);
rv_number = usize::from_slice(&header[26..28]);
self.version_number = Some(rv_number as u16);
if &header[28..30] == &super::constants::BIG_ENDIAN_IDENTIFIER {
result = Err(super::error::Error::NotImplementedYet);
} else if
&header[28..30] != &super::constants::LITTLE_ENDIAN_IDENTIFIER {
result = Err(super::error::Error::InvalidOLEFile);
} else {
let mut k = usize::from_slice(&header[30..32]);
if k >= 16 {
result =
Err(super::error::Error::BadSizeValue("Overflow on sector
size"));
} else {
self.sec_size = Some(2usize.pow(k as u32));
k = usize::from_slice(&header[32..34]);
if k >= 16 {
result = Err(super::error::Error::BadSizeValue(
"Overflow on short sector size"));
} else {
self.short_sec_size = Some(2usize.pow(k as u32));
let sat: std::vec::Vec<u32>;
sat = std::vec::Vec::with_capacity(
(*self.sec_size.as_ref().unwrap() / 4)
* usize::from_slice(&header[44..48]));
let mut dsat: std::vec::Vec<u32> = std::vec::Vec::new();
dsat.push(u32::from_slice(&header[48..52]));
self.minimum_standard_stream_size =
Some(usize::from_slice(&header[56..60]));
if *self.minimum_standard_stream_size.as_ref().unwrap()
< 4096usize {
result = Err(super::error::Error::InvalidOLEFile);
} else {
let mut ssat: std::vec::Vec<u32>;
let mut msat: std::vec::Vec<u32>;
ssat = std::vec::Vec::with_capacity(
usize::from_slice(&header[64..68])
* (*self.sec_size.as_ref().unwrap() / 4));
ssat.push(u32::from_slice(&header[60..64]));
msat = vec![super::constants::FREE_SECID_U32; 109];
if &header[68..72] != &super::constants::END_OF_CHAIN_SECID {
msat.resize(109usize + usize::from_slice(&header[72..76])
* (*self.sec_size.as_ref().unwrap() / 4),
super::constants::FREE_SECID_U32);
}
self.sat = Some(sat);
self.msat = Some(msat);
self.dsat = Some(dsat);
self.ssat = Some(ssat);
self.build_master_sector_allocation_table(&header)?;
result = Ok(())
}
}
}
}
}
result
}
fn build_master_sector_allocation_table(&mut self, header: &[u8])
-> Result<(), super::error::Error> {
let mut total_sec_id_read = self.read_sec_ids(&header[76 ..], 0);
if total_sec_id_read == 109 {
let sec_size = *self.sec_size.as_ref().unwrap();
let mut sec_id = usize::from_slice(&header[68..72]);
let mut buffer = vec![0u8; 0];
let mut steps_since_last_resize = 0;
while sec_id != super::constants::END_OF_CHAIN_SECID_U32 as usize {
let relative_offset = sec_id * sec_size;
if buffer.len() < relative_offset + sec_size {
let old_len = buffer.len();
let new_len = relative_offset + sec_size;
buffer.resize(new_len, 0xFFu8);
self.read(&mut buffer[old_len..new_len])?;
steps_since_last_resize = 0;
}
total_sec_id_read += self.read_sec_ids(&buffer[relative_offset
.. relative_offset + sec_size - 4], total_sec_id_read);
sec_id = usize::from_slice(&buffer[relative_offset + sec_size - 4
.. relative_offset + sec_size]);
steps_since_last_resize += 1;
if steps_since_last_resize * sec_size > buffer.len() {
return Err(super::error::Error::InvalidOLEFile);
}
}
self.body = Some(buffer);
}
self.msat.as_mut().unwrap().resize(
total_sec_id_read, super::constants::FREE_SECID_U32);
let mut buf: &mut std::vec::Vec<u8>;
if !self.body.is_some() {
self.body = Some(std::vec::Vec::new());
}
buf = self.body.as_mut().unwrap();
self.buf_reader.as_mut().unwrap().read_to_end(&mut
buf).map_err(super::error::Error::IOError)?;
Ok(())
}
fn read_sec_ids(&mut self, buffer: &[u8], msat_offset: usize) -> usize {
let mut i = 0usize;
let mut offset = 0usize;
let max_sec_ids = buffer.len() / 4;
let msat = &mut self.msat.as_mut().unwrap()[msat_offset .. ];
while i < max_sec_ids && &buffer[offset .. offset + 4]
!= &super::constants::FREE_SECID {
msat[i] = u32::from_slice(&buffer[offset .. offset + 4]);
offset += 4;
i += 1;
}
i
}
}