83 lines
2.3 KiB
Rust
83 lines
2.3 KiB
Rust
|
use {
|
||
|
crate::{Checksum, Error},
|
||
|
md5::{Digest, Md5},
|
||
|
sha1::Sha1,
|
||
|
sha2::Sha256,
|
||
|
std::io::{Read, Write},
|
||
|
};
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct File {
|
||
|
pub len: u64,
|
||
|
pub checksum: Checksum,
|
||
|
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(())
|
||
|
}
|
||
|
}
|