diff options
author | Omer Ben-Amram <omerbenamram@gmail.com> | 2019-05-13 17:33:03 +0300 |
---|---|---|
committer | Omer Ben-Amram <omerbenamram@gmail.com> | 2019-05-13 17:33:03 +0300 |
commit | 27776a804e5647c87853d124b8b97eaa2e2af5a8 (patch) | |
tree | 8e079d67f0780f899911bf3402d1b66fd31f2103 | |
parent | 95696563d2dded325e828ee8eb4b5da948a71a0a (diff) |
allow usage from buffer
-rw-r--r-- | src/benches/benchmark.rs | 16 | ||||
-rw-r--r-- | src/bin/mft_dump.rs | 2 | ||||
-rw-r--r-- | src/mft.rs | 52 |
3 files changed, 31 insertions, 39 deletions
diff --git a/src/benches/benchmark.rs b/src/benches/benchmark.rs index 8d66229..8e23b5d 100644 --- a/src/benches/benchmark.rs +++ b/src/benches/benchmark.rs @@ -6,25 +6,17 @@ use criterion::Criterion; use mft::MftParser; use std::path::{Path, PathBuf}; -fn process_90_mft_records(sample: impl AsRef<Path>) { - let parser = MftParser::from_path(sample).unwrap(); +fn process_90_mft_records(sample: &[u8]) { + let mut parser = MftParser::from_buffer(sample.to_vec()).unwrap(); let _: Vec<_> = parser.iter_entries().take(90).collect(); } fn criterion_benchmark(c: &mut Criterion) { - let sample = PathBuf::from(file!()) - .parent() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap() - .join("samples") - .join("MFT"); + let sample = include_bytes!("../../samples/MFT"); c.bench_function("read 90 records", move |b| { - b.iter(|| process_90_mft_records(&sample)) + b.iter(|| process_90_mft_records(sample)) }); } diff --git a/src/bin/mft_dump.rs b/src/bin/mft_dump.rs index 2e61257..620174a 100644 --- a/src/bin/mft_dump.rs +++ b/src/bin/mft_dump.rs @@ -20,7 +20,7 @@ impl MftDump { pub fn parse_file(&self) { info!("Opening file {:?}", &self.filepath); - let mft_handler = match MftParser::from_path(&self.filepath) { + let mut mft_handler = match MftParser::from_path(&self.filepath) { Ok(mft_handler) => mft_handler, Err(error) => { eprintln!( @@ -5,21 +5,20 @@ use crate::err::{self, Result}; use crate::ReadSeek; use log::debug; use snafu::ResultExt; -use std::borrow::Borrow; + use std::fs::{self, File}; use std::io::{BufReader, Cursor, Read, Seek, SeekFrom}; -use std::ops::Deref; use std::path::Path; -pub struct MftParser { - data: File, +pub struct MftParser<T: ReadSeek> { + data: T, /// Entry size is present in the volume header, but this is not available to us. /// Instead this will be guessed by the entry size of the first entry. entry_size: u32, size: u64, } -impl MftParser { +impl MftParser<BufReader<File>> { /// Instantiates an instance of the parser from a file path. /// Does not mutate the file contents in any way. pub fn from_path(filename: impl AsRef<Path>) -> Result<Self> { @@ -29,33 +28,32 @@ impl MftParser { let size = fs::metadata(f)?.len(); Ok(MftParser { - data: mft_fh, + data: BufReader::with_capacity(4096, mft_fh), + entry_size: 1024, + size, + }) + } +} + +impl MftParser<Cursor<Vec<u8>>> { + pub fn from_buffer(buffer: Vec<u8>) -> Result<Self> { + let size = buffer.len() as u64; + let cursor = Cursor::new(buffer); + + Ok(MftParser { + data: cursor, entry_size: 1024, size, }) } } -// -//impl MftParser<Cursor<Vec<u8>>> { -// pub fn from_buffer(buffer: Vec<u8>) -> Result<Self> { -// let size = buffer.len() as u64; -// let cursor = Cursor::new(buffer); -// -// Ok(MftParser { -// data: cursor, -// entry_size: 1024, -// size, -// }) -// } -//} - -impl MftParser { + +impl<T: Read + Seek> MftParser<T> { pub fn get_entry_count(&self) -> u64 { self.size / u64::from(self.entry_size) } - pub fn iter_entries(&self) -> impl Iterator<Item = Result<MftEntry>> + '_ { - let mut file = BufReader::with_capacity(4096, &self.data); + pub fn iter_entries(&mut self) -> impl Iterator<Item = Result<MftEntry>> + '_ { let total_entries = self.get_entry_count(); let mut count = 0; @@ -67,7 +65,8 @@ impl MftParser { count += 1; debug!("Reading entry {}", count); - if let Err(e) = file + if let Err(e) = self + .data .seek(SeekFrom::Start(count * u64::from(self.entry_size))) .eager_context(err::IoError) { @@ -76,7 +75,8 @@ impl MftParser { let mut entry_buffer = vec![0; self.entry_size as usize]; - if let Err(e) = file + if let Err(e) = self + .data .read_exact(&mut entry_buffer) .eager_context(err::IoError) { @@ -161,7 +161,7 @@ mod tests { .join("samples") .join("MFT"); - let parser = MftParser::from_path(sample).unwrap(); + let mut parser = MftParser::from_path(sample).unwrap(); let _: Vec<_> = parser.iter_entries().take(90).collect(); } |