46 lines
1.1 KiB
Rust
46 lines
1.1 KiB
Rust
use std::{
|
|
collections::HashMap,
|
|
sync::Arc,
|
|
cell::RefCell,
|
|
};
|
|
|
|
use crate::btrfs_structs::{Node, ParseError, ParseBin};
|
|
use crate::addrmap::{LogToPhys, AddressMap};
|
|
|
|
pub struct NodeReader<'a> {
|
|
image: &'a [u8],
|
|
addr_map: AddressMap,
|
|
cache: RefCell<HashMap<u64, Arc<Node>>>,
|
|
}
|
|
|
|
impl<'a> NodeReader<'a> {
|
|
pub fn new(image: &'a [u8]) -> Result<NodeReader<'a>, ParseError> {
|
|
let addr_map = AddressMap::new(image)?;
|
|
Ok(NodeReader {image, addr_map, cache: RefCell::new(HashMap::new())})
|
|
}
|
|
|
|
pub fn with_addrmap(image: &'a [u8], addr_map: AddressMap) -> Result<NodeReader<'a>, ParseError> {
|
|
Ok(NodeReader {image, addr_map, cache: RefCell::new(HashMap::new())})
|
|
}
|
|
|
|
/// Read a node given its logical address
|
|
pub fn get_node(&self, addr: u64) -> Result<Arc<Node>, ParseError> {
|
|
if let Some(node) = self.cache.borrow().get(&addr) {
|
|
return Ok(Arc::clone(node))
|
|
}
|
|
|
|
println!("Reading node at {:X}", addr);
|
|
|
|
let node_data = self.addr_map.node_at_log(self.image, addr)?;
|
|
let node = Arc::new(Node::parse(node_data)?);
|
|
|
|
self.cache.borrow_mut().insert(addr, Arc::clone(&node));
|
|
|
|
Ok(node)
|
|
}
|
|
|
|
pub fn addr_map(&self) -> &AddressMap {
|
|
&self.addr_map
|
|
}
|
|
}
|