repak/src/footer.rs

68 lines
2.4 KiB
Rust
Raw Normal View History

use std::str::FromStr;
2023-01-03 10:33:42 +00:00
use byteorder::{ReadBytesExt, LE};
use super::{Compression, ReadExt, Version};
#[derive(Debug)]
2023-01-03 10:33:42 +00:00
pub struct Footer {
pub encryption_uuid: Option<u128>,
2023-01-10 22:29:20 +00:00
pub encrypted: bool,
2023-01-03 10:33:42 +00:00
pub magic: u32,
pub version: Version,
pub offset: u64,
pub size: u64,
pub hash: [u8; 20],
2023-01-10 22:29:20 +00:00
pub frozen: bool,
2023-01-03 10:33:42 +00:00
pub compression: Option<Vec<Compression>>,
}
impl Footer {
2023-01-07 21:10:11 +00:00
pub fn new<R: std::io::Read>(reader: &mut R, version: Version) -> Result<Self, super::Error> {
let footer = Self {
encryption_uuid: match version >= Version::EncryptionKeyGuid {
true => Some(reader.read_u128::<LE>()?),
false => None,
},
2023-01-10 22:29:20 +00:00
encrypted: version >= Version::IndexEncryption && reader.read_bool()?,
2023-01-03 10:33:42 +00:00
magic: reader.read_u32::<LE>()?,
2023-01-07 21:10:11 +00:00
version: Version::from_repr(reader.read_u32::<LE>()?).unwrap_or(version),
2023-01-03 10:33:42 +00:00
offset: reader.read_u64::<LE>()?,
size: reader.read_u64::<LE>()?,
hash: reader.read_guid()?,
2023-01-10 22:29:20 +00:00
frozen: version == Version::FrozenIndex && reader.read_bool()?,
2023-01-07 21:10:11 +00:00
compression: match version >= Version::FNameBasedCompression {
true => {
let mut compression =
Vec::with_capacity(match version == Version::FNameBasedCompression {
true => 4,
false => 5,
});
for _ in 0..compression.capacity() {
compression.push(
Compression::from_str(
&reader
.read_len(32)?
.iter()
// filter out whitespace and convert to char
.filter_map(|&ch| (ch != 0).then_some(ch as char))
.collect::<String>(),
)
.unwrap_or_default(),
)
2023-01-07 21:10:11 +00:00
}
Some(compression)
2023-01-03 10:33:42 +00:00
}
2023-01-07 21:10:11 +00:00
false => None,
},
2023-01-03 10:33:42 +00:00
};
if super::MAGIC != footer.magic {
return Err(super::Error::WrongMagic(footer.magic));
2023-01-03 10:33:42 +00:00
}
2023-01-07 21:10:11 +00:00
if version != footer.version {
return Err(super::Error::WrongVersion(version, footer.version));
2023-01-03 10:33:42 +00:00
}
Ok(footer)
}
}