X-Git-Url: https://code.octet-stream.net/hashgood/blobdiff_plain/1dec1ec82f55d639d9fad0d0933545aa509c4272..refs/heads/master:/src/calculate.rs?ds=sidebyside diff --git a/src/calculate.rs b/src/calculate.rs index 870115c..5928c52 100644 --- a/src/calculate.rs +++ b/src/calculate.rs @@ -1,14 +1,12 @@ use super::Algorithm; -use crossbeam_channel::bounded; -use crossbeam_channel::Receiver; -use crypto::digest::Digest; -use crypto::md5::Md5; -use crypto::sha1::Sha1; -use crypto::sha2::Sha256; +use md5::{Digest, Md5}; +use sha1::Sha1; +use sha2::Sha256; use std::error::Error; use std::fs::File; use std::io::prelude::*; -use std::path::PathBuf; +use std::path::Path; +use std::sync::mpsc::{channel, Receiver}; use std::sync::Arc; use std::thread; use std::thread::JoinHandle; @@ -16,12 +14,27 @@ use std::thread::JoinHandle; pub type CalculateResult = Result)>, Box>; /// For a given path to the input (may be "-" for STDIN), try to obtain a reader for the data within it. -pub fn get_input_reader(input: &PathBuf) -> Result, Box> { +pub fn get_input_reader(input: &Path) -> Result, String> { if input.to_str() == Some("-") { // Special case: standard input return Ok(Box::new(std::io::stdin())); } - Ok(Box::new(File::open(input)?)) + if !input.exists() { + return Err(format!( + "The path '{}' does not exist.", + input.to_string_lossy() + )); + } + if !input.is_file() { + return Err(format!( + "The path '{}' is not a regular file.", + input.to_string_lossy() + )); + } + match File::open(input) { + Ok(f) => Ok(Box::new(f)), + Err(e) => Err(format!("File open: {}", e)), + } } /// For the given input stream, calculate all requested digest types @@ -30,17 +43,17 @@ pub fn create_digests(algorithms: &[Algorithm], mut input: Box) -> Cal let mut handles = vec![]; if algorithms.contains(&Algorithm::Md5) { - let (s, r) = bounded::>>(1); + let (s, r) = channel(); senders.push(s); handles.push(md5_digest(r)); } if algorithms.contains(&Algorithm::Sha1) { - let (s, r) = bounded::>>(1); + let (s, r) = channel(); senders.push(s); handles.push(sha1_digest(r)); } if algorithms.contains(&Algorithm::Sha256) { - let (s, r) = bounded::>>(1); + let (s, r) = channel(); senders.push(s); handles.push(sha256_digest(r)); } @@ -71,10 +84,9 @@ fn md5_digest(rx: Receiver>>) -> JoinHandle<(Algorithm, Vec)> { thread::spawn(move || { let mut md5 = Md5::new(); while let Ok(chunk) = rx.recv() { - md5.input(&chunk); + md5.update(&*chunk); } - let mut result = [0; 16]; - md5.result(&mut result); + let result = md5.finalize(); (Algorithm::Md5, result.to_vec()) }) } @@ -84,10 +96,9 @@ fn sha1_digest(rx: Receiver>>) -> JoinHandle<(Algorithm, Vec)> { thread::spawn(move || { let mut sha1 = Sha1::new(); while let Ok(chunk) = rx.recv() { - sha1.input(&chunk); + sha1.update(&*chunk); } - let mut result = [0; 20]; - sha1.result(&mut result); + let result = sha1.finalize(); (Algorithm::Sha1, result.to_vec()) }) } @@ -97,10 +108,9 @@ fn sha256_digest(rx: Receiver>>) -> JoinHandle<(Algorithm, Vec)> thread::spawn(move || { let mut sha256 = Sha256::new(); while let Ok(chunk) = rx.recv() { - sha256.input(&chunk); + sha256.update(&*chunk); } - let mut result = [0; 32]; - sha256.result(&mut result); + let result = sha256.finalize(); (Algorithm::Sha256, result.to_vec()) }) } @@ -110,22 +120,22 @@ mod tests { use super::*; use std::io::Cursor; - const SMALL_DATA: [u8; 10] = ['A' as u8; 10]; + static SMALL_DATA: [u8; 10] = [b'A'; 10]; // python3 -c 'print ("A"*10, end="", flush=True)' | md5sum - const SMALL_DATA_MD5: &'static str = "16c52c6e8326c071da771e66dc6e9e57"; + static SMALL_DATA_MD5: &str = "16c52c6e8326c071da771e66dc6e9e57"; // python3 -c 'print ("A"*10, end="", flush=True)' | sha1sum - const SMALL_DATA_SHA1: &'static str = "c71613a7386fd67995708464bf0223c0d78225c4"; + static SMALL_DATA_SHA1: &str = "c71613a7386fd67995708464bf0223c0d78225c4"; // python3 -c 'print ("A"*10, end="", flush=True)' | sha256sum - const SMALL_DATA_SHA256: &'static str = + static SMALL_DATA_SHA256: &str = "1d65bf29403e4fb1767522a107c827b8884d16640cf0e3b18c4c1dd107e0d49d"; - const LARGE_DATA: [u8; 1_000_000] = ['B' as u8; 1_000_000]; + static LARGE_DATA: [u8; 1_000_000] = [b'B'; 1_000_000]; // python3 -c 'print ("B"*1000000, end="", flush=True)' | md5sum - const LARGE_DATA_MD5: &'static str = "9171f6d67a87ca649a702434a03458a1"; + static LARGE_DATA_MD5: &str = "9171f6d67a87ca649a702434a03458a1"; // python3 -c 'print ("B"*1000000, end="", flush=True)' | sha1sum - const LARGE_DATA_SHA1: &'static str = "cfae4cebfd01884111bdede7cf983626bb249c94"; + static LARGE_DATA_SHA1: &str = "cfae4cebfd01884111bdede7cf983626bb249c94"; // python3 -c 'print ("B"*1000000, end="", flush=True)' | sha256sum - const LARGE_DATA_SHA256: &'static str = + static LARGE_DATA_SHA256: &str = "b9193853f7798e92e2f6b82eda336fa7d6fc0fa90fdefe665f372b0bad8cdf8c"; fn verify_digest(alg: Algorithm, data: &'static [u8], hash: &str) { @@ -139,9 +149,9 @@ mod tests { /// of test data (single block). #[test] fn small_digests() { - verify_digest(Algorithm::Md5, &SMALL_DATA, &SMALL_DATA_MD5); - verify_digest(Algorithm::Sha1, &SMALL_DATA, &SMALL_DATA_SHA1); - verify_digest(Algorithm::Sha256, &SMALL_DATA, &SMALL_DATA_SHA256); + verify_digest(Algorithm::Md5, &SMALL_DATA, SMALL_DATA_MD5); + verify_digest(Algorithm::Sha1, &SMALL_DATA, SMALL_DATA_SHA1); + verify_digest(Algorithm::Sha256, &SMALL_DATA, SMALL_DATA_SHA256); } /// Assert that digests for all algorithms are calculated correctly for a large piece @@ -150,8 +160,8 @@ mod tests { /// 1 MiB means that the final block will be slightly smaller than the others. #[test] fn large_digests() { - verify_digest(Algorithm::Md5, &LARGE_DATA, &LARGE_DATA_MD5); - verify_digest(Algorithm::Sha1, &LARGE_DATA, &LARGE_DATA_SHA1); - verify_digest(Algorithm::Sha256, &LARGE_DATA, &LARGE_DATA_SHA256); + verify_digest(Algorithm::Md5, &LARGE_DATA, LARGE_DATA_MD5); + verify_digest(Algorithm::Sha1, &LARGE_DATA, LARGE_DATA_SHA1); + verify_digest(Algorithm::Sha256, &LARGE_DATA, LARGE_DATA_SHA256); } }