diff --git a/src/entry.rs b/src/entry.rs index 4f6fe27..13b1a28 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -7,7 +7,7 @@ pub struct Entry { pub offset: u64, pub compressed: u64, pub uncompressed: u64, - pub compression_method: Compression, + pub compression: Compression, pub timestamp: Option, pub hash: [u8; 20], pub compression_blocks: Option>, @@ -23,7 +23,7 @@ impl Entry { let offset = reader.read_u64::()?; let compressed = reader.read_u64::()?; let uncompressed = reader.read_u64::()?; - let compression_method = match reader.read_u32::()? { + let compression = match reader.read_u32::()? { 0x01 | 0x10 | 0x20 => Compression::Zlib, _ => Compression::None, }; @@ -31,14 +31,14 @@ impl Entry { offset, compressed, uncompressed, - compression_method, + compression, timestamp: match version == Version::Initial { true => Some(reader.read_u64::()?), false => None, }, hash: reader.read_guid()?, compression_blocks: match version >= Version::CompressionEncryption - && compression_method != Compression::None + && compression != Compression::None { true => Some(reader.read_array(Block::new)?), false => None, diff --git a/src/footer.rs b/src/footer.rs index 50ba5f5..0f56416 100644 --- a/src/footer.rs +++ b/src/footer.rs @@ -14,7 +14,7 @@ pub struct Footer { pub size: u64, pub hash: [u8; 20], pub frozen: bool, - pub compression: Option>, + pub compression: Vec, } impl Footer { @@ -31,29 +31,26 @@ impl Footer { size: reader.read_u64::()?, hash: reader.read_guid()?, frozen: version == Version::FrozenIndex && reader.read_bool()?, - 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::(), - ) - .unwrap_or_default(), + compression: { + let mut compression = Vec::with_capacity(match version { + ver if ver < Version::FNameBasedCompression => 0, + Version::FNameBasedCompression => 4, + _ => 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::(), ) - } - Some(compression) + .unwrap_or_default(), + ) } - false => None, + compression }, }; if super::MAGIC != footer.magic { diff --git a/src/lib.rs b/src/lib.rs index c8f70d7..11af6c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,7 +24,6 @@ pub enum Version { EncryptionKeyGuid, // include key GUID FNameBasedCompression, // compression names included FrozenIndex, // frozen index byte included - PathHashIndex, // more compression methods } // strum shouldn't need to be installed by users @@ -32,6 +31,32 @@ impl Version { pub fn iter() -> VersionIter { ::iter() } + + pub fn size(self) -> i64 { + // (magic + version): u32 + (offset + size): u64 + hash: [u8; 20] + let mut size = 4 + 4 + 8 + 8 + 20; + if self >= Version::EncryptionKeyGuid { + // encryption uuid: u128 + size += 16; + } + if self >= Version::IndexEncryption { + // encrypted: bool + size += 1; + } + if self == Version::FrozenIndex { + // frozen index: bool + size += 1; + } + if self >= Version::FNameBasedCompression { + // compression names: [[u8; 32]; 4] + size += 32 * 4; + } + if self >= Version::FrozenIndex { + // extra compression name: [u8; 32] + size += 32 + } + size + } } #[derive(Default, Clone, Copy, PartialEq, Eq, Debug, strum::Display, strum::EnumString)] diff --git a/src/pak.rs b/src/pak.rs index 06f8417..e0fe0f5 100644 --- a/src/pak.rs +++ b/src/pak.rs @@ -17,15 +17,15 @@ impl Pak { version: super::Version, mut reader: R, ) -> Result { - reader.seek(io::SeekFrom::End(-footer_size(&version)))?; + reader.seek(io::SeekFrom::End(-version.size()))?; let footer = super::Footer::new(&mut reader, version)?; reader.seek(io::SeekFrom::Start(footer.offset))?; let mount_point = reader.read_string()?; let mut entries = hashbrown::HashMap::with_capacity(reader.read_u32::()? as usize); for _ in 0..entries.capacity() { entries.insert( - reader.read_string()?, - super::Entry::new(&mut reader, version)?, + dbg!(reader.read_string()?), + dbg!(super::Entry::new(&mut reader, version)?), ); } Ok(Self { @@ -35,29 +35,3 @@ impl Pak { }) } } - -fn footer_size(version: &Version) -> i64 { - // (magic + version): u32 + (offset + size): u64 + hash: [u8; 20] - let mut size = 4 + 4 + 8 + 8 + 20; - if version >= &Version::EncryptionKeyGuid { - // encryption uuid: u128 - size += 16; - } - if version >= &Version::IndexEncryption { - // encrypted: bool - size += 1; - } - if version == &Version::FrozenIndex { - // frozen index: bool - size += 1; - } - if version >= &Version::FNameBasedCompression { - // compression names: [[u8; 32]; 4] - size += 32 * 4; - } - if version >= &Version::FrozenIndex { - // extra compression name: [u8; 32] - size += 32 - } - size -}