mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 10:54:38 +00:00
use builder pattern
This commit is contained in:
parent
564c4f6a45
commit
e2edd97d6e
4 changed files with 47 additions and 131 deletions
|
@ -20,6 +20,7 @@ zstd = { version = "0.12", optional = true }
|
|||
thiserror = "1.0"
|
||||
sha1 = { workspace = true }
|
||||
strum = { workspace = true }
|
||||
once_cell = "1.18"
|
||||
|
||||
[dev-dependencies]
|
||||
base64 = { workspace = true }
|
||||
|
|
|
@ -307,7 +307,6 @@ impl Entry {
|
|||
compression: &[Compression],
|
||||
#[allow(unused)] key: &super::Key,
|
||||
buf: &mut W,
|
||||
#[allow(unused)] oodle: super::Oodle,
|
||||
) -> Result<(), super::Error> {
|
||||
reader.seek(io::SeekFrom::Start(self.offset))?;
|
||||
Entry::read(reader, version)?;
|
||||
|
@ -377,7 +376,7 @@ impl Entry {
|
|||
}
|
||||
#[cfg(feature = "oodle")]
|
||||
Some(Compression::Oodle) => unsafe {
|
||||
let super::Oodle::Some(oodle) = oodle else {
|
||||
let Some(ref oodle) = super::OODLE else {
|
||||
return Err(super::Error::OodleFailed);
|
||||
};
|
||||
let mut decompressed = vec![0; self.uncompressed as usize];
|
||||
|
|
|
@ -10,7 +10,10 @@ pub use {error::*, pak::*};
|
|||
pub const MAGIC: u32 = 0x5A6F12E1;
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
pub type DECOMPRESS = unsafe extern "C" fn(
|
||||
static mut OODLE: Option<once_cell::sync::Lazy<Decompress>> = None;
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
pub type Decompress = unsafe extern "C" fn(
|
||||
compBuf: *mut u8,
|
||||
compBufSize: usize,
|
||||
rawBuf: *mut u8,
|
||||
|
@ -155,7 +158,7 @@ impl From<aes::Aes256> for Key {
|
|||
|
||||
#[cfg(feature = "oodle")]
|
||||
pub(crate) enum Oodle<'func> {
|
||||
Some(&'func DECOMPRESS),
|
||||
Some(&'func Decompress),
|
||||
None,
|
||||
}
|
||||
|
||||
|
|
167
repak/src/pak.rs
167
repak/src/pak.rs
|
@ -4,6 +4,46 @@ use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
|||
use std::collections::BTreeMap;
|
||||
use std::io::{self, Read, Seek, Write};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PakBuilder {
|
||||
key: super::Key,
|
||||
}
|
||||
|
||||
impl PakBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
key: super::Key::None,
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn key(&mut self, key: aes::Aes256) {
|
||||
self.key = super::Key::Some(key)
|
||||
}
|
||||
#[cfg(feature = "oodle")]
|
||||
pub fn oodle(&mut self, oodle: fn() -> super::Decompress) {
|
||||
unsafe { super::OODLE = Some(once_cell::sync::Lazy::new(oodle)) }
|
||||
}
|
||||
pub fn reader<R: Read + Seek>(self, reader: &mut R) -> Result<PakReader, super::Error> {
|
||||
PakReader::new_any_inner(reader, self.key)
|
||||
}
|
||||
pub fn reader_with_version<R: Read + Seek>(
|
||||
self,
|
||||
reader: &mut R,
|
||||
version: super::Version,
|
||||
) -> Result<PakReader, super::Error> {
|
||||
PakReader::new_inner(reader, version, self.key)
|
||||
}
|
||||
pub fn writer<W: Write + Seek>(
|
||||
self,
|
||||
writer: W,
|
||||
version: super::Version,
|
||||
mount_point: String,
|
||||
path_hash_seed: Option<u64>,
|
||||
) -> PakWriter<W> {
|
||||
PakWriter::new_inner(writer, self.key, version, mount_point, path_hash_seed)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PakReader {
|
||||
pak: Pak,
|
||||
|
@ -83,29 +123,6 @@ fn decrypt(key: &super::Key, bytes: &mut [u8]) -> Result<(), super::Error> {
|
|||
}
|
||||
|
||||
impl PakReader {
|
||||
pub fn new_any<R: Read + Seek>(reader: &mut R) -> Result<Self, super::Error> {
|
||||
Self::new_any_inner(reader, super::Key::None)
|
||||
}
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn new_any_with_key<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
key: aes::Aes256,
|
||||
) -> Result<Self, super::Error> {
|
||||
Self::new_any_inner(reader, key.into())
|
||||
}
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn new_any_with_optional_key<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
key: Option<aes::Aes256>,
|
||||
) -> Result<Self, super::Error> {
|
||||
match key {
|
||||
Some(key) => Self::new_any_with_key(reader, key),
|
||||
None => Self::new_any(reader),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_any_inner<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
key: super::Key,
|
||||
|
@ -122,34 +139,6 @@ impl PakReader {
|
|||
Err(super::Error::UnsupportedOrEncrypted(log))
|
||||
}
|
||||
|
||||
pub fn new<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
version: super::Version,
|
||||
) -> Result<Self, super::Error> {
|
||||
Self::new_inner(reader, version, super::Key::None)
|
||||
}
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn new_with_key<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
version: super::Version,
|
||||
key: aes::Aes256,
|
||||
) -> Result<Self, super::Error> {
|
||||
Self::new_inner(reader, version, key.into())
|
||||
}
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn new_with_optional_key<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
version: super::Version,
|
||||
key: Option<aes::Aes256>,
|
||||
) -> Result<Self, super::Error> {
|
||||
match key {
|
||||
Some(key) => Self::new_with_key(reader, version, key),
|
||||
None => Self::new(reader, version),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_inner<R: Read + Seek>(
|
||||
reader: &mut R,
|
||||
version: super::Version,
|
||||
|
@ -180,18 +169,6 @@ impl PakReader {
|
|||
Ok(data)
|
||||
}
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
pub fn get_with_oodle<R: Read + Seek>(
|
||||
&self,
|
||||
path: &str,
|
||||
reader: &mut R,
|
||||
oodle: &super::DECOMPRESS,
|
||||
) -> Result<Vec<u8>, super::Error> {
|
||||
let mut data = Vec::new();
|
||||
self.read_file_with_oodle(path, reader, &mut data, oodle)?;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub fn read_file<R: Read + Seek, W: Write>(
|
||||
&self,
|
||||
path: &str,
|
||||
|
@ -205,28 +182,6 @@ impl PakReader {
|
|||
&self.pak.compression,
|
||||
&self.key,
|
||||
writer,
|
||||
super::Oodle::None,
|
||||
),
|
||||
None => Err(super::Error::MissingEntry(path.to_owned())),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "oodle")]
|
||||
pub fn read_file_with_oodle<R: Read + Seek, W: Write>(
|
||||
&self,
|
||||
path: &str,
|
||||
reader: &mut R,
|
||||
writer: &mut W,
|
||||
oodle: &super::DECOMPRESS,
|
||||
) -> Result<(), super::Error> {
|
||||
match self.pak.index.entries().get(path) {
|
||||
Some(entry) => entry.read_file(
|
||||
reader,
|
||||
self.pak.version,
|
||||
&self.pak.compression,
|
||||
&self.key,
|
||||
writer,
|
||||
super::Oodle::Some(oodle),
|
||||
),
|
||||
None => Err(super::Error::MissingEntry(path.to_owned())),
|
||||
}
|
||||
|
@ -250,48 +205,6 @@ impl PakReader {
|
|||
}
|
||||
|
||||
impl<W: Write + Seek> PakWriter<W> {
|
||||
pub fn new(
|
||||
writer: W,
|
||||
version: Version,
|
||||
mount_point: String,
|
||||
path_hash_seed: Option<u64>,
|
||||
) -> Self {
|
||||
PakWriter {
|
||||
pak: Pak::new(version, mount_point, path_hash_seed),
|
||||
writer,
|
||||
key: super::Key::None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn new_with_key(
|
||||
writer: W,
|
||||
key: aes::Aes256,
|
||||
version: Version,
|
||||
mount_point: String,
|
||||
path_hash_seed: Option<u64>,
|
||||
) -> Self {
|
||||
PakWriter {
|
||||
pak: Pak::new(version, mount_point, path_hash_seed),
|
||||
writer,
|
||||
key: key.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn new_with_optional_key(
|
||||
writer: W,
|
||||
key: Option<aes::Aes256>,
|
||||
version: Version,
|
||||
mount_point: String,
|
||||
path_hash_seed: Option<u64>,
|
||||
) -> Self {
|
||||
match key {
|
||||
Some(key) => Self::new_with_key(writer, key, version, mount_point, path_hash_seed),
|
||||
None => Self::new(writer, version, mount_point, path_hash_seed),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
writer: W,
|
||||
key: super::Key,
|
||||
|
|
Loading…
Reference in a new issue