use super::*;
pub struct MemoryReader {
blocks: Vec<Block>,
directory: Directory,
}
impl MemoryReader {
pub fn from_bytes(bytes: &[u8], key: &Key) -> Result<MemoryReader, ErrorKind> {
if bytes.len() % BLOCK_SIZE != 0 {
return Err(ErrorKind::InvalidInput);
}
let mut blocks = vec![Block::default(); bytes.len() / BLOCK_SIZE];
dataview::bytes_mut(blocks.as_mut_slice())[..bytes.len()].copy_from_slice(bytes);
match from_blocks(blocks, key) {
Ok((blocks, directory)) => Ok(MemoryReader { blocks, directory }),
Err(_) => return Err(ErrorKind::InvalidData),
}
}
pub fn from_blocks(blocks: Vec<Block>, key: &Key) -> Result<MemoryReader, Vec<Block>> {
from_blocks(blocks, key).map(|(blocks, directory)| MemoryReader { blocks, directory })
}
}
impl ops::Deref for MemoryReader {
type Target = Directory;
#[inline]
fn deref(&self) -> &Directory {
&self.directory
}
}
impl MemoryReader {
pub fn read(&self, path: &[u8], key: &Key) -> Result<Vec<u8>, ErrorKind> {
let desc = match self.find_file(path) {
Some(desc) => desc,
None => return Err(ErrorKind::NotFound),
};
self.read_data(desc, key)
}
pub fn read_to_string(&self, path: &[u8], key: &Key) -> Result<String, ErrorKind> {
let desc = match self.find_file(path) {
Some(desc) => desc,
None => return Err(ErrorKind::NotFound),
};
let data = self.read_data(desc, key)?;
String::from_utf8(data).map_err(|_| ErrorKind::InvalidData)
}
#[inline]
pub fn read_section(&self, section: &Section, key: &Key) -> Result<Vec<Block>, ErrorKind> {
read_section(&self.blocks, section, key)
}
#[inline]
pub fn read_data(&self, desc: &Descriptor, key: &Key) -> Result<Vec<u8>, ErrorKind> {
read_data(&self.blocks, desc, key)
}
#[inline]
pub fn read_data_into(&self, desc: &Descriptor, key: &Key, byte_offset: usize, dest: &mut [u8]) -> Result<(), ErrorKind> {
read_data_into(&self.blocks, desc, key, byte_offset, dest)
}
}