pass function pointer

This commit is contained in:
spuds 2023-09-19 23:11:40 +01:00
parent 6680e7871b
commit 1a79469a11
No known key found for this signature in database
GPG key ID: 0B6CA6068E827C8F
4 changed files with 53 additions and 18 deletions

View file

@ -307,6 +307,7 @@ impl Entry {
compression: &[Compression], compression: &[Compression],
#[allow(unused)] key: &super::Key, #[allow(unused)] key: &super::Key,
buf: &mut W, buf: &mut W,
#[allow(unused)] oodle: super::Oodle,
) -> Result<(), super::Error> { ) -> Result<(), super::Error> {
reader.seek(io::SeekFrom::Start(self.offset))?; reader.seek(io::SeekFrom::Start(self.offset))?;
Entry::read(reader, version)?; Entry::read(reader, version)?;
@ -376,9 +377,9 @@ impl Entry {
} }
#[cfg(feature = "oodle")] #[cfg(feature = "oodle")]
Some(Compression::Oodle) => unsafe { Some(Compression::Oodle) => unsafe {
// #[allow(non_snake_case)] let super::Oodle::Some(oodle) = oodle else {
// #[allow(clippy::type_complexity)] return Err(super::Error::OodleFailed);
// let OodleLZ_Decompress = lib.get(b"OodleLZ_Decompress").unwrap(); };
let mut decompressed = vec![0; self.uncompressed as usize]; let mut decompressed = vec![0; self.uncompressed as usize];
let mut compress_offset = 0; let mut compress_offset = 0;
@ -392,7 +393,7 @@ impl Entry {
.min(self.uncompressed as usize - compress_offset) .min(self.uncompressed as usize - compress_offset)
}; };
let buffer = &mut data[range]; let buffer = &mut data[range];
let out = OodleLZ_Decompress( let out = oodle(
buffer.as_mut_ptr(), buffer.as_mut_ptr(),
buffer.len(), buffer.len(),
decompressed.as_mut_ptr().offset(decompress_offset), decompressed.as_mut_ptr().offset(decompress_offset),
@ -415,7 +416,7 @@ impl Entry {
decompress_offset += out as isize; decompress_offset += out as isize;
} }
assert_eq!( debug_assert_eq!(
decompress_offset, self.uncompressed as isize, decompress_offset, self.uncompressed as isize,
"Oodle decompression length mismatch" "Oodle decompression length mismatch"
); );

View file

@ -16,14 +16,7 @@ pub enum Error {
#[error("enable the encryption feature to read encrypted paks")] #[error("enable the encryption feature to read encrypted paks")]
Encryption, Encryption,
#[cfg_attr( #[error("enable the oodle feature to read Oodle compressed paks")]
windows,
error("enable the oodle feature to read Oodle compressed paks")
)]
#[cfg_attr(
not(windows),
error("Oodle compression only supported on Windows (or WINE)")
)]
Oodle, Oodle,
// std errors // std errors
@ -39,10 +32,6 @@ pub enum Error {
#[error("utf16 conversion: {0}")] #[error("utf16 conversion: {0}")]
Utf16(#[from] std::string::FromUtf16Error), Utf16(#[from] std::string::FromUtf16Error),
#[cfg(feature = "oodle")]
#[error("ureq error: {0}")]
Ureq(#[from] Box<ureq::Error>), // boxed because ureq::Error is quite large
#[error("bufwriter dereference: {0}")] #[error("bufwriter dereference: {0}")]
IntoInner(#[from] std::io::IntoInnerError<std::io::BufWriter<Vec<u8>>>), IntoInner(#[from] std::io::IntoInnerError<std::io::BufWriter<Vec<u8>>>),
@ -53,7 +42,7 @@ pub enum Error {
#[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)] #[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)]
Magic(u32), Magic(u32),
#[error("Could not load oo2core_9_win64.dll")] #[error("pointer to OodleLZ_Decompress was not provided")]
OodleFailed, OodleFailed,
#[error("No entry found at {0}")] #[error("No entry found at {0}")]

View file

@ -151,3 +151,14 @@ impl From<aes::Aes256> for Key {
Self::Some(value) Self::Some(value)
} }
} }
#[cfg(feature = "oodle")]
pub(crate) enum Oodle<'func> {
Some(&'func DECOMPRESS),
None,
}
#[cfg(not(feature = "oodle"))]
pub(crate) enum Oodle {
None,
}

View file

@ -180,6 +180,18 @@ impl PakReader {
Ok(data) 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>( pub fn read_file<R: Read + Seek, W: Write>(
&self, &self,
path: &str, path: &str,
@ -193,6 +205,28 @@ impl PakReader {
&self.pak.compression, &self.pak.compression,
&self.key, &self.key,
writer, 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())), None => Err(super::Error::MissingEntry(path.to_owned())),
} }