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 byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ impl Entry {
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
version: super::Version,
|
version: super::Version,
|
||||||
) -> Result<Self, super::Error> {
|
) -> 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 offset = reader.read_u64::<LE>()?;
|
||||||
let compressed = reader.read_u64::<LE>()?;
|
let compressed = reader.read_u64::<LE>()?;
|
||||||
let uncompressed = reader.read_u64::<LE>()?;
|
let uncompressed = reader.read_u64::<LE>()?;
|
||||||
|
@ -100,32 +100,26 @@ impl Entry {
|
||||||
0 => None,
|
0 => None,
|
||||||
n => Some(n - 1),
|
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 {
|
Ok(Self {
|
||||||
offset,
|
offset,
|
||||||
compressed,
|
compressed,
|
||||||
uncompressed,
|
uncompressed,
|
||||||
compression,
|
compression,
|
||||||
timestamp: match version.version_major() == VersionMajor::Initial {
|
timestamp,
|
||||||
true => Some(reader.read_u64::<LE>()?),
|
hash,
|
||||||
false => None,
|
blocks,
|
||||||
},
|
flags,
|
||||||
hash: Some(reader.read_guid()?),
|
compression_block_size,
|
||||||
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,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
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 {
|
pub trait ReadExt {
|
||||||
fn read_bool(&mut self) -> Result<bool, super::Error>;
|
fn read_bool(&mut self) -> Result<bool, super::Error>;
|
||||||
fn read_guid(&mut self) -> Result<[u8; 20], 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 super::{ext::ReadExt, Compression, Version, VersionMajor};
|
||||||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||||
|
@ -20,58 +20,64 @@ pub struct Footer {
|
||||||
|
|
||||||
impl Footer {
|
impl Footer {
|
||||||
pub fn read<R: std::io::Read>(reader: &mut R, version: Version) -> Result<Self, super::Error> {
|
pub fn read<R: std::io::Read>(reader: &mut R, version: Version) -> Result<Self, super::Error> {
|
||||||
let footer = Self {
|
let encryption_uuid = (version.version_major() >= VersionMajor::EncryptionKeyGuid)
|
||||||
encryption_uuid: match version.version_major() >= VersionMajor::EncryptionKeyGuid {
|
.then_try(|| reader.read_u128::<LE>())?;
|
||||||
true => Some(reader.read_u128::<LE>()?),
|
let encrypted =
|
||||||
false => None,
|
version.version_major() >= VersionMajor::IndexEncryption && reader.read_bool()?;
|
||||||
},
|
let magic = reader.read_u32::<LE>()?;
|
||||||
encrypted: version.version_major() >= VersionMajor::IndexEncryption
|
let version_major =
|
||||||
&& reader.read_bool()?,
|
VersionMajor::from_repr(reader.read_u32::<LE>()?).unwrap_or(version.version_major());
|
||||||
magic: reader.read_u32::<LE>()?,
|
let index_offset = reader.read_u64::<LE>()?;
|
||||||
version,
|
let index_size = reader.read_u64::<LE>()?;
|
||||||
version_major: VersionMajor::from_repr(reader.read_u32::<LE>()?)
|
let hash = reader.read_guid()?;
|
||||||
.unwrap_or(version.version_major()),
|
let frozen = version.version_major() == VersionMajor::FrozenIndex && reader.read_bool()?;
|
||||||
index_offset: reader.read_u64::<LE>()?,
|
let compression = {
|
||||||
index_size: reader.read_u64::<LE>()?,
|
let mut compression = Vec::with_capacity(match version {
|
||||||
hash: reader.read_guid()?,
|
ver if ver < Version::V8A => 0,
|
||||||
frozen: version.version_major() == VersionMajor::FrozenIndex && reader.read_bool()?,
|
ver if ver < Version::V8B => 4,
|
||||||
compression: {
|
_ => 5,
|
||||||
let mut compression = Vec::with_capacity(match version {
|
});
|
||||||
ver if ver < Version::V8A => 0,
|
for _ in 0..compression.capacity() {
|
||||||
ver if ver < Version::V8B => 4,
|
compression.push(
|
||||||
_ => 5,
|
Compression::from_str(
|
||||||
});
|
&reader
|
||||||
for _ in 0..compression.capacity() {
|
.read_len(32)?
|
||||||
compression.push(
|
.iter()
|
||||||
Compression::from_str(
|
// filter out whitespace and convert to char
|
||||||
&reader
|
.filter_map(|&ch| (ch != 0).then_some(ch as char))
|
||||||
.read_len(32)?
|
.collect::<String>(),
|
||||||
.iter()
|
|
||||||
// filter out whitespace and convert to char
|
|
||||||
.filter_map(|&ch| (ch != 0).then_some(ch as char))
|
|
||||||
.collect::<String>(),
|
|
||||||
)
|
|
||||||
.unwrap_or_default(),
|
|
||||||
)
|
)
|
||||||
}
|
.unwrap_or_default(),
|
||||||
if version < Version::V8A {
|
)
|
||||||
compression.push(Compression::Zlib);
|
}
|
||||||
compression.push(Compression::Gzip);
|
if version < Version::V8A {
|
||||||
compression.push(Compression::Oodle);
|
compression.push(Compression::Zlib);
|
||||||
}
|
compression.push(Compression::Gzip);
|
||||||
compression
|
compression.push(Compression::Oodle);
|
||||||
},
|
}
|
||||||
|
compression
|
||||||
};
|
};
|
||||||
if super::MAGIC != footer.magic {
|
if super::MAGIC != magic {
|
||||||
return Err(super::Error::Magic(footer.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 {
|
return Err(super::Error::Version {
|
||||||
used: version.version_major(),
|
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> {
|
pub fn write<W: std::io::Write>(&self, writer: &mut W) -> Result<(), super::Error> {
|
||||||
|
|
Loading…
Reference in a new issue