Setup to replace separate header/node idiom with unified Node. Enum
`Filetype` with now have `Normal(File)` (todo) which will include the size, checksum and data, removing the `size` field from `Header`. The `Header` struct will become the new `Node`.
This commit is contained in:
parent
85e55dc456
commit
bdbcd41617
108
Cargo.lock
generated
108
Cargo.lock
generated
@ -2,6 +2,114 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar-ng"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"md-5",
|
||||
"sha1",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
@ -6,3 +6,6 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
md-5 = "0.10"
|
||||
sha1 = "0.10"
|
||||
sha2 = "0.10"
|
||||
|
134
src/lib.rs
134
src/lib.rs
@ -1,9 +1,14 @@
|
||||
use std::{
|
||||
array::TryFromSliceError,
|
||||
fmt,
|
||||
io::{self, Read, Write},
|
||||
num::TryFromIntError,
|
||||
string::FromUtf8Error,
|
||||
use {
|
||||
md5::{Digest, Md5},
|
||||
sha1::Sha1,
|
||||
sha2::Sha256,
|
||||
std::{
|
||||
array::TryFromSliceError,
|
||||
fmt,
|
||||
io::{self, Read, Write},
|
||||
num::TryFromIntError,
|
||||
string::FromUtf8Error,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -12,6 +17,7 @@ pub enum Error {
|
||||
Io(io::Error),
|
||||
Utf8(FromUtf8Error),
|
||||
Slice(TryFromSliceError),
|
||||
InvalidChecksum,
|
||||
MissingData,
|
||||
UnexpectedData,
|
||||
UnknownFileType,
|
||||
@ -24,6 +30,7 @@ impl fmt::Display for Error {
|
||||
Self::Utf8(e) => write!(f, "{e}"),
|
||||
Self::Slice(e) => write!(f, "{e}"),
|
||||
Self::Io(e) => write!(f, "{e}"),
|
||||
Self::InvalidChecksum => write!(f, "invalid checksum"),
|
||||
Self::MissingData => write!(f, "missing data"),
|
||||
Self::UnexpectedData => write!(f, "unexpected data"),
|
||||
Self::UnknownFileType => write!(f, "unknown file type"),
|
||||
@ -91,6 +98,117 @@ impl Special {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Checksum {
|
||||
Md5([u8; 16]),
|
||||
Sha1([u8; 20]),
|
||||
Sha256([u8; 32]),
|
||||
Skip,
|
||||
}
|
||||
|
||||
impl Checksum {
|
||||
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||||
let mut buf = [0; 1];
|
||||
reader.read_exact(&mut buf)?;
|
||||
match buf[0] {
|
||||
0 => {
|
||||
let mut sum = [0; 16];
|
||||
reader.read_exact(&mut sum)?;
|
||||
Ok(Self::Md5(sum))
|
||||
},
|
||||
1 => {
|
||||
let mut sum = [0; 20];
|
||||
reader.read_exact(&mut sum)?;
|
||||
Ok(Self::Sha1(sum))
|
||||
},
|
||||
2 => {
|
||||
let mut sum = [0; 32];
|
||||
reader.read_exact(&mut sum)?;
|
||||
Ok(Self::Sha256(sum))
|
||||
},
|
||||
_ => Ok(Self::Skip),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
||||
match self {
|
||||
Self::Md5(sum) => {
|
||||
writer.write_all(&[b'0'])?;
|
||||
writer.write_all(&sum[..])?;
|
||||
},
|
||||
Self::Sha1(sum) => {
|
||||
writer.write_all(&[b'1'])?;
|
||||
writer.write_all(&sum[..])?;
|
||||
},
|
||||
Self::Sha256(sum) => {
|
||||
writer.write_all(&[b'2'])?;
|
||||
writer.write_all(&sum[..])?;
|
||||
},
|
||||
Self::Skip => writer.write_all(&[b'3'])?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[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(())
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug)]
|
||||
pub enum FileType {
|
||||
@ -256,12 +374,12 @@ impl Node {
|
||||
} else {
|
||||
return Err(Error::MissingData);
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
if self.data.is_some() {
|
||||
return Err(Error::UnexpectedData);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user