From ebf6eb198ede5fb66320c22b3dee2188106c89ff Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 8 Nov 2020 18:43:50 +0200 Subject: feat(src/chunker.rs): add abstraction for chunking live data This is very rudimentary for now --- src/chunker.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/chunker.rs (limited to 'src') diff --git a/src/chunker.rs b/src/chunker.rs new file mode 100644 index 0000000..f4ca74c --- /dev/null +++ b/src/chunker.rs @@ -0,0 +1,60 @@ +use crate::chunk::DataChunk; +use crate::chunkmeta::ChunkMeta; +use sha2::{Digest, Sha256}; +use std::io::prelude::*; + +pub struct Chunker { + chunk_size: usize, + buf: Vec, + handle: std::fs::File, +} + +impl Chunker { + pub fn new(chunk_size: usize, handle: std::fs::File) -> Self { + let mut buf = vec![]; + buf.resize(chunk_size, 0); + Self { + chunk_size, + buf, + handle, + } + } + + pub fn read_chunk(&mut self) -> anyhow::Result> { + let mut used = 0; + + loop { + let n = self.handle.read(&mut self.buf.as_mut_slice()[used..])?; + used += n; + if n == 0 || used == self.chunk_size { + break; + } + } + + if used == 0 { + return Ok(None); + } + + let buffer = &self.buf.as_slice()[..used]; + let mut hasher = Sha256::new(); + hasher.update(buffer); + let hash = hasher.finalize(); + let hash = format!("{:x}", hash); + let meta = ChunkMeta::new(&hash); + + let chunk = DataChunk::new(buffer.to_vec()); + Ok(Some((meta, chunk))) + } +} + +impl Iterator for Chunker { + type Item = anyhow::Result<(ChunkMeta, DataChunk)>; + + fn next(&mut self) -> Option> { + match self.read_chunk() { + Ok(None) => None, + Ok(Some((meta, chunk))) => Some(Ok((meta, chunk))), + Err(e) => Some(Err(e)), + } + } +} -- cgit v1.2.1