mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
Restructure footer and pak reading to make debugging custom serialization easier
This commit is contained in:
parent
a749449f8c
commit
ff3c9b265b
3 changed files with 79 additions and 69 deletions
|
@ -1,4 +1,4 @@
|
|||
use super::{ext::ReadExt, Compression, Version, VersionMajor};
|
||||
use super::{ext::BoolExt, ext::ReadExt, Compression, Version, VersionMajor};
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||
use std::io;
|
||||
|
||||
|
@ -88,7 +88,7 @@ impl Entry {
|
|||
reader: &mut R,
|
||||
version: super::Version,
|
||||
) -> Result<Self, super::Error> {
|
||||
// since i need the compression flags, i have to store these as variables which is mildly annoying
|
||||
let ver = version.version_major();
|
||||
let offset = reader.read_u64::<LE>()?;
|
||||
let compressed = reader.read_u64::<LE>()?;
|
||||
let uncompressed = reader.read_u64::<LE>()?;
|
||||
|
@ -100,32 +100,26 @@ impl Entry {
|
|||
0 => None,
|
||||
n => Some(n - 1),
|
||||
};
|
||||
let timestamp = (ver == VersionMajor::Initial).then_try(|| reader.read_u64::<LE>())?;
|
||||
let hash = Some(reader.read_guid()?);
|
||||
let blocks = (ver >= VersionMajor::CompressionEncryption && compression.is_some())
|
||||
.then_try(|| reader.read_array(Block::read))?;
|
||||
let flags = (ver >= VersionMajor::CompressionEncryption)
|
||||
.then_try(|| reader.read_u8())?
|
||||
.unwrap_or(0);
|
||||
let compression_block_size = (ver >= VersionMajor::CompressionEncryption)
|
||||
.then_try(|| reader.read_u32::<LE>())?
|
||||
.unwrap_or(0);
|
||||
Ok(Self {
|
||||
offset,
|
||||
compressed,
|
||||
uncompressed,
|
||||
compression,
|
||||
timestamp: match version.version_major() == VersionMajor::Initial {
|
||||
true => Some(reader.read_u64::<LE>()?),
|
||||
false => None,
|
||||
},
|
||||
hash: Some(reader.read_guid()?),
|
||||
blocks: match version.version_major() >= VersionMajor::CompressionEncryption
|
||||
&& compression.is_some()
|
||||
{
|
||||
true => Some(reader.read_array(Block::read)?),
|
||||
false => None,
|
||||
},
|
||||
flags: match version.version_major() >= VersionMajor::CompressionEncryption {
|
||||
true => reader.read_u8()?,
|
||||
false => 0,
|
||||
},
|
||||
compression_block_size: match version.version_major()
|
||||
>= VersionMajor::CompressionEncryption
|
||||
{
|
||||
true => reader.read_u32::<LE>()?,
|
||||
false => 0,
|
||||
},
|
||||
timestamp,
|
||||
hash,
|
||||
blocks,
|
||||
flags,
|
||||
compression_block_size,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||
|
||||
pub trait BoolExt<T, E, F: FnOnce() -> Result<T, E>> {
|
||||
fn then_try(&self, f: F) -> Result<Option<T>, E>;
|
||||
}
|
||||
|
||||
impl<T, E, F: FnOnce() -> Result<T, E>> BoolExt<T, E, F> for bool {
|
||||
fn then_try(&self, f: F) -> Result<Option<T>, E> {
|
||||
self.then(f).transpose()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ReadExt {
|
||||
fn read_bool(&mut self) -> Result<bool, super::Error>;
|
||||
fn read_guid(&mut self) -> Result<[u8; 20], super::Error>;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::ext::WriteExt;
|
||||
use crate::ext::{BoolExt, WriteExt};
|
||||
|
||||
use super::{ext::ReadExt, Compression, Version, VersionMajor};
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||
|
@ -20,22 +20,18 @@ pub struct Footer {
|
|||
|
||||
impl Footer {
|
||||
pub fn read<R: std::io::Read>(reader: &mut R, version: Version) -> Result<Self, super::Error> {
|
||||
let footer = Self {
|
||||
encryption_uuid: match version.version_major() >= VersionMajor::EncryptionKeyGuid {
|
||||
true => Some(reader.read_u128::<LE>()?),
|
||||
false => None,
|
||||
},
|
||||
encrypted: version.version_major() >= VersionMajor::IndexEncryption
|
||||
&& reader.read_bool()?,
|
||||
magic: reader.read_u32::<LE>()?,
|
||||
version,
|
||||
version_major: VersionMajor::from_repr(reader.read_u32::<LE>()?)
|
||||
.unwrap_or(version.version_major()),
|
||||
index_offset: reader.read_u64::<LE>()?,
|
||||
index_size: reader.read_u64::<LE>()?,
|
||||
hash: reader.read_guid()?,
|
||||
frozen: version.version_major() == VersionMajor::FrozenIndex && reader.read_bool()?,
|
||||
compression: {
|
||||
let encryption_uuid = (version.version_major() >= VersionMajor::EncryptionKeyGuid)
|
||||
.then_try(|| reader.read_u128::<LE>())?;
|
||||
let encrypted =
|
||||
version.version_major() >= VersionMajor::IndexEncryption && reader.read_bool()?;
|
||||
let magic = reader.read_u32::<LE>()?;
|
||||
let version_major =
|
||||
VersionMajor::from_repr(reader.read_u32::<LE>()?).unwrap_or(version.version_major());
|
||||
let index_offset = reader.read_u64::<LE>()?;
|
||||
let index_size = reader.read_u64::<LE>()?;
|
||||
let hash = reader.read_guid()?;
|
||||
let frozen = version.version_major() == VersionMajor::FrozenIndex && reader.read_bool()?;
|
||||
let compression = {
|
||||
let mut compression = Vec::with_capacity(match version {
|
||||
ver if ver < Version::V8A => 0,
|
||||
ver if ver < Version::V8B => 4,
|
||||
|
@ -60,18 +56,28 @@ impl Footer {
|
|||
compression.push(Compression::Oodle);
|
||||
}
|
||||
compression
|
||||
},
|
||||
};
|
||||
if super::MAGIC != footer.magic {
|
||||
return Err(super::Error::Magic(footer.magic));
|
||||
if super::MAGIC != magic {
|
||||
return Err(super::Error::Magic(magic));
|
||||
}
|
||||
if version.version_major() != footer.version_major {
|
||||
if version.version_major() != version_major {
|
||||
return Err(super::Error::Version {
|
||||
used: version.version_major(),
|
||||
version: footer.version_major,
|
||||
version: version_major,
|
||||
});
|
||||
}
|
||||
Ok(footer)
|
||||
Ok(Self {
|
||||
encryption_uuid,
|
||||
encrypted,
|
||||
magic,
|
||||
version,
|
||||
version_major,
|
||||
index_offset,
|
||||
index_size,
|
||||
hash,
|
||||
frozen,
|
||||
compression,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn write<W: std::io::Write>(&self, writer: &mut W) -> Result<(), super::Error> {
|
||||
|
|
Loading…
Reference in a new issue