use super::*;
pub struct MemoryEditFile<'a> {
pub(super) desc: &'a mut Descriptor,
pub(super) blocks: &'a mut Vec<Block>,
}
impl<'a> MemoryEditFile<'a> {
#[inline]
pub fn descriptor(&self) -> &Descriptor {
self.desc
}
#[inline]
pub fn set_content(&mut self, content_type: u32, content_size: u32) -> &mut MemoryEditFile<'a> {
self.desc.content_type = u32::max(1, content_type); self.desc.content_size = content_size;
return self;
}
#[inline]
pub fn set_section(&mut self, section: &Section) -> &mut MemoryEditFile<'a> {
self.desc.section = *section;
return self;
}
pub fn allocate_data(&mut self) -> &mut MemoryEditFile<'a> {
let size = bytes2blocks(self.desc.content_size);
self.desc.section.offset = self.blocks.len() as u32;
self.desc.section.size = size;
if let Some(new_len) = self.blocks.len().checked_add(size as usize) {
self.blocks.resize(new_len, Block::default());
}
return self;
}
pub fn write_data(&mut self, data: &[u8], key: &Key) -> &mut MemoryEditFile<'a> {
let blocks = &mut self.blocks[self.desc.section.range_usize()];
let len = usize::min(dataview::bytes(blocks).len(), data.len());
dataview::bytes_mut(blocks)[..len].copy_from_slice(&data[..len]);
crypt::encrypt_section(blocks, &mut self.desc.section, key);
return self;
}
pub fn zero_data(&mut self, key: &Key) -> &mut MemoryEditFile<'a> {
let blocks = &mut self.blocks[self.desc.section.range_usize()];
blocks.fill(Block::default());
crypt::encrypt_section(blocks, &mut self.desc.section, key);
return self;
}
pub fn reencrypt_data(&mut self, old_key: &Key, key: &Key) {
let blocks = &mut self.blocks[self.desc.section.range_usize()];
let old_mac = self.desc.section.mac;
let is_valid = crypt::decrypt_section(blocks, &self.desc.section, old_key);
crypt::encrypt_section(blocks, &mut self.desc.section, key);
if !is_valid {
self.desc.section.mac = old_mac;
}
}
}