use byteorder::{ReadBytesExt, LE}; use super::{Compression, ReadExt, Version}; #[derive(Debug)] pub struct Entry { pub name: String, pub offset: u64, pub compressed: u64, pub uncompressed: u64, pub compression_method: Compression, pub timestamp: Option, pub hash: [u8; 20], pub compression_blocks: Option>, } impl Entry { pub fn new( reader: &mut R, version: &super::Version, ) -> Result { let name = reader.read_string()?; let offset = reader.read_u64::()?; let compressed = reader.read_u64::()?; let uncompressed = reader.read_u64::()?; let compression_method = match reader.read_u32::()? { 0x01 => Compression::Zlib, 0x10 => Compression::ZlibBiasMemory, 0x20 => Compression::ZlibBiasMemory, _ => Compression::None, }; Ok(Self { name, offset, compressed, uncompressed, compression_method, timestamp: (version == &Version::Initial).then_some(reader.read_u64::()?), hash: reader.read_guid()?, compression_blocks: (version >= &Version::CompressionEncryption && compression_method != Compression::None) .then_some(reader.read_array(Block::new)?), }) } } #[derive(Debug)] pub struct Block { /// start offset relative to the start of the entry header pub offset: u64, /// size of the compressed block pub size: u64, } impl Block { pub fn new(reader: &mut R) -> Result { Ok(Self { offset: reader.read_u64::()?, size: reader.read_u64::()?, }) } }