Finish refactor from previous commit, unifying Header
and Node
structures
This commit is contained in:
parent
bdbcd41617
commit
f93374c70a
64
src/lib.rs
64
src/lib.rs
@ -292,17 +292,16 @@ impl FileType {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Header {
|
||||
pub struct Node {
|
||||
pub name: String,
|
||||
pub filetype: FileType,
|
||||
pub mode: u32,
|
||||
pub uid: u32,
|
||||
pub gid: u32,
|
||||
pub size: u64,
|
||||
pub mtime: u64,
|
||||
pub filetype: FileType,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
impl Node {
|
||||
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||||
let mut len = [0; 8];
|
||||
reader.read_exact(&mut len)?;
|
||||
@ -310,22 +309,20 @@ impl Header {
|
||||
let mut name = Vec::with_capacity(len.try_into()?);
|
||||
let mut handle = reader.take(len);
|
||||
handle.read_exact(&mut name)?;
|
||||
let filetype = FileType::read(reader)?;
|
||||
let mut buf = [0; 28];
|
||||
let mut buf = [0; 20];
|
||||
reader.read_exact(&mut buf)?;
|
||||
let mode: [u8; 4] = buf[..4].try_into()?;
|
||||
let uid: [u8; 4] = buf[4..8].try_into()?;
|
||||
let gid: [u8; 4] = buf[8..12].try_into()?;
|
||||
let size: [u8; 8] = buf[12..20].try_into()?;
|
||||
let mtime: [u8; 8] = buf[20..].try_into()?;
|
||||
let mtime: [u8; 8] = buf[12..].try_into()?;
|
||||
let filetype = FileType::read(reader)?;
|
||||
Ok(Self {
|
||||
name: String::from_utf8(name)?,
|
||||
filetype,
|
||||
mode: u32::from_le_bytes(mode),
|
||||
uid: u32::from_le_bytes(uid),
|
||||
gid: u32::from_le_bytes(gid),
|
||||
size: u64::from_le_bytes(size),
|
||||
mtime: u64::from_le_bytes(mtime),
|
||||
filetype,
|
||||
})
|
||||
}
|
||||
|
||||
@ -333,54 +330,11 @@ impl Header {
|
||||
let len = self.name.len() as u64;
|
||||
writer.write_all(&len.to_le_bytes())?;
|
||||
writer.write_all(self.name.as_bytes())?;
|
||||
self.filetype.write(writer)?;
|
||||
[self.mode, self.uid, self.gid]
|
||||
.iter()
|
||||
.try_for_each(|f| writer.write_all(&f.to_le_bytes()))?;
|
||||
[self.size, self.mtime]
|
||||
.iter()
|
||||
.try_for_each(|f| writer.write_all(&f.to_le_bytes()))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Node {
|
||||
pub header: Header,
|
||||
pub data: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||||
let header = Header::read(reader)?;
|
||||
let data = match header.filetype {
|
||||
FileType::Normal => {
|
||||
let mut data = Vec::with_capacity(header.size.try_into()?);
|
||||
let mut handle = reader.take(header.size);
|
||||
handle.read_exact(&mut data)?;
|
||||
Some(data)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
Ok(Self { header, data })
|
||||
}
|
||||
|
||||
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
||||
self.header.write(writer)?;
|
||||
match self.header.filetype {
|
||||
FileType::Normal => {
|
||||
if let Some(ref data) = self.data {
|
||||
writer.write_all(data)?;
|
||||
} else {
|
||||
return Err(Error::MissingData);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if self.data.is_some() {
|
||||
return Err(Error::UnexpectedData);
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.write_all(&self.mtime.to_le_bytes())?;
|
||||
self.filetype.write(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user