use crate::ole::util::FromSlice;
impl<'ole> super::ole::Reader<'ole> {
pub(crate) fn build_sat(&mut self) -> Result<(), super::error::Error> {
let sector_size = self.sec_size.unwrap();
let mut sec_ids = vec![super::constants::FREE_SECID_U32; sector_size / 4];
if self.msat.as_ref().unwrap().is_empty() {
Err(super::error::Error::EmptyMasterSectorAllocationTable)
} else {
for i in 0..self.msat.as_ref().unwrap().len() {
let sector_index = self.msat.as_ref().unwrap()[i];
self.read_sat_sector(sector_index as usize, &mut sec_ids)?;
self.sat.as_mut().unwrap().extend_from_slice(&sec_ids);
}
self.build_ssat()?;
self.build_dsat()?;
Ok(())
}
}
pub(crate) fn read_sat_sector(
&mut self,
sector_index: usize,
sec_ids: &mut std::vec::Vec<u32>,
) -> Result<(), super::error::Error> {
let sector = self.read_sector(sector_index)?;
for i in 0..sec_ids.capacity() {
sec_ids[i] = u32::from_slice(§or[i * 4..i * 4 + 4]);
}
Ok(())
}
pub(crate) fn build_chain_from_sat(&mut self, start: u32) -> std::vec::Vec<u32> {
let mut chain = std::vec::Vec::new();
let mut sector_index = start;
let sat = self.sat.as_mut().unwrap();
while sector_index != super::constants::END_OF_CHAIN_SECID_U32 {
chain.push(sector_index);
sector_index = sat[sector_index as usize];
}
chain
}
pub(crate) fn build_chain_from_ssat(&mut self, start: u32) -> std::vec::Vec<u32> {
let mut chain = std::vec::Vec::new();
let mut sector_index = start;
let sat = self.ssat.as_mut().unwrap();
while sector_index != super::constants::END_OF_CHAIN_SECID_U32
&& sector_index != super::constants::FREE_SECID_U32
{
chain.push(sector_index);
sector_index = sat[sector_index as usize];
}
chain
}
pub(crate) fn build_ssat(&mut self) -> Result<(), super::error::Error> {
let mut sec_ids =
vec![super::constants::FREE_SECID_U32; self.sec_size.as_ref().unwrap() / 4];
let sector_index = self.ssat.as_mut().unwrap().remove(0);
let chain = self.build_chain_from_sat(sector_index);
for sector_index in chain {
self.read_sat_sector(sector_index as usize, &mut sec_ids)?;
self.ssat.as_mut().unwrap().extend_from_slice(&sec_ids);
}
Ok(())
}
pub(crate) fn build_dsat(&mut self) -> Result<(), super::error::Error> {
let sector_index = self.dsat.as_mut().unwrap().remove(0);
let chain = self.build_chain_from_sat(sector_index);
for sector_index in chain {
self.dsat.as_mut().unwrap().push(sector_index);
}
Ok(())
}
}