haggis-rs/src/file.rs

87 lines
2.5 KiB
Rust
Raw Normal View History

2023-07-04 00:51:47 -04:00
use {
crate::{Checksum, Error},
md5::{Digest, Md5},
sha1::Sha1,
sha2::Sha256,
std::io::{Read, Write},
};
/// A representation of a regular file as an archive member
2023-07-04 00:51:47 -04:00
#[derive(Debug)]
pub struct File {
/// The length of this file
2023-07-04 00:51:47 -04:00
pub len: u64,
/// The optional checksum of this file
2023-07-04 00:51:47 -04:00
pub checksum: Checksum,
/// The bytes making up this file
2023-07-04 00:51:47 -04:00
pub data: Vec<u8>,
}
impl File {
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
let mut len = [0; 8];
reader.read_exact(&mut len)?;
let len = u64::from_le_bytes(len);
let checksum = Checksum::read(reader)?;
let mut data = Vec::with_capacity(len.try_into()?);
let mut handle = reader.take(len);
handle.read_exact(&mut data)?;
match checksum {
Checksum::Md5(sum) => {
let mut hasher = Md5::new();
hasher.update(&data);
let res = hasher.finalize();
if res == sum.into() {
Ok(Self {
len,
checksum,
data,
})
} else {
Err(Error::InvalidChecksum)
}
}
Checksum::Sha1(sum) => {
let mut hasher = Sha1::new();
hasher.update(&data);
let res = hasher.finalize();
if res == sum.into() {
Ok(Self {
len,
checksum,
data,
})
} else {
Err(Error::InvalidChecksum)
}
}
Checksum::Sha256(sum) => {
let mut hasher = Sha256::new();
hasher.update(&data);
let res = hasher.finalize();
if res == sum.into() {
Ok(Self {
len,
checksum,
data,
})
} else {
Err(Error::InvalidChecksum)
}
}
_ => Ok(Self {
len,
checksum,
data,
}),
}
}
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
writer.write_all(&self.len.to_be_bytes())?;
Checksum::write(&self.checksum, writer)?;
writer.write_all(&self.data)?;
Ok(())
}
}