use std::io::Cursor;
use std::sync::Arc;
#[derive(Clone)]
pub struct SevenZPasswordVerifier {
archive_data: Arc<[u8]>,
file_name: String,
expected_crc: u32,
original_size: u64,
}
unsafe impl Send for SevenZPasswordVerifier {}
unsafe impl Sync for SevenZPasswordVerifier {}
impl SevenZPasswordVerifier {
pub fn new(archive_data: Vec<u8>, file_name: String, expected_crc: u32, original_size: u64) -> Self {
Self {
archive_data: Arc::from(archive_data.into_boxed_slice()),
file_name,
expected_crc,
original_size,
}
}
pub fn entry_name(&self) -> &str {
&self.file_name
}
pub fn original_size(&self) -> u64 {
self.original_size
}
pub fn verify(&self, password: &str) -> bool {
let mut cursor = Cursor::new(&*self.archive_data);
let pwd = sevenz_rust2::Password::from(password);
let mut archive = match sevenz_rust2::ArchiveReader::new(&mut cursor, pwd) {
Ok(a) => a,
Err(_) => return false,
};
let data = match archive.read_file(&self.file_name) {
Ok(d) => d,
Err(_) => return false,
};
if data.len() != self.original_size as usize {
return false;
}
let crc = crc32fast::hash(&data);
crc == self.expected_crc
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_verifier_is_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<SevenZPasswordVerifier>();
}
}