mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
use Key enum to reduce cfg attributes used
This commit is contained in:
parent
7004e1c203
commit
50f54837ca
4 changed files with 50 additions and 62 deletions
|
@ -3,13 +3,13 @@ use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
pub enum EntryLocation {
|
pub(crate) enum EntryLocation {
|
||||||
Data,
|
Data,
|
||||||
Index,
|
Index,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Block {
|
pub(crate) struct Block {
|
||||||
pub start: u64,
|
pub start: u64,
|
||||||
pub end: u64,
|
pub end: u64,
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ fn align(offset: u64) -> u64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Entry {
|
pub(crate) struct Entry {
|
||||||
pub offset: u64,
|
pub offset: u64,
|
||||||
pub compressed: u64,
|
pub compressed: u64,
|
||||||
pub uncompressed: u64,
|
pub uncompressed: u64,
|
||||||
|
@ -311,7 +311,7 @@ impl Entry {
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
version: Version,
|
version: Version,
|
||||||
compression: &[Compression],
|
compression: &[Compression],
|
||||||
#[cfg(feature = "encryption")] key: Option<&aes::Aes256>,
|
key: &super::Key,
|
||||||
buf: &mut W,
|
buf: &mut W,
|
||||||
) -> Result<(), super::Error> {
|
) -> Result<(), super::Error> {
|
||||||
reader.seek(io::SeekFrom::Start(self.offset))?;
|
reader.seek(io::SeekFrom::Start(self.offset))?;
|
||||||
|
@ -328,7 +328,7 @@ impl Entry {
|
||||||
return Err(super::Error::Encryption);
|
return Err(super::Error::Encryption);
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
{
|
{
|
||||||
let Some(key) = key else {
|
let super::Key::Some(key) = key else {
|
||||||
return Err(super::Error::Encrypted);
|
return Err(super::Error::Encrypted);
|
||||||
};
|
};
|
||||||
use aes::cipher::BlockDecrypt;
|
use aes::cipher::BlockDecrypt;
|
||||||
|
@ -423,6 +423,7 @@ impl Entry {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
let OodleLZ_Decompress: libloading::Symbol<
|
let OodleLZ_Decompress: libloading::Symbol<
|
||||||
extern "C" fn(
|
extern "C" fn(
|
||||||
compBuf: *mut u8,
|
compBuf: *mut u8,
|
||||||
|
|
|
@ -122,3 +122,21 @@ pub enum Compression {
|
||||||
Oodle,
|
Oodle,
|
||||||
Zstd,
|
Zstd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum Key {
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
Some(aes::Aes256),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Option<aes::Aes256>> for Key {
|
||||||
|
fn from(value: Option<aes::Aes256>) -> Self {
|
||||||
|
match value {
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
Some(key) => Self::Some(key),
|
||||||
|
_ => Self::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use super::ext::{ReadExt, WriteExt};
|
use super::ext::{ReadExt, WriteExt};
|
||||||
use super::{Version, VersionMajor};
|
use super::{Version, VersionMajor};
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
use aes::Aes256;
|
|
||||||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::io::{self, Read, Seek, Write};
|
use std::io::{self, Read, Seek, Write};
|
||||||
|
@ -9,20 +7,18 @@ use std::io::{self, Read, Seek, Write};
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PakReader {
|
pub struct PakReader {
|
||||||
pak: Pak,
|
pak: Pak,
|
||||||
#[cfg(feature = "encryption")]
|
key: super::Key,
|
||||||
key: Option<aes::Aes256>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PakWriter<W: Write + Seek> {
|
pub struct PakWriter<W: Write + Seek> {
|
||||||
pak: Pak,
|
pak: Pak,
|
||||||
writer: W,
|
writer: W,
|
||||||
#[cfg(feature = "encryption")]
|
key: super::Key,
|
||||||
key: Option<aes::Aes256>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pak {
|
pub(crate) struct Pak {
|
||||||
version: Version,
|
version: Version,
|
||||||
mount_point: String,
|
mount_point: String,
|
||||||
index_offset: Option<u64>,
|
index_offset: Option<u64>,
|
||||||
|
@ -47,7 +43,7 @@ impl Pak {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Index {
|
pub(crate) struct Index {
|
||||||
path_hash_seed: Option<u64>,
|
path_hash_seed: Option<u64>,
|
||||||
entries: BTreeMap<String, super::entry::Entry>,
|
entries: BTreeMap<String, super::entry::Entry>,
|
||||||
}
|
}
|
||||||
|
@ -74,8 +70,8 @@ impl Index {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
fn decrypt(key: Option<&aes::Aes256>, bytes: &mut [u8]) -> Result<(), super::Error> {
|
fn decrypt(key: &super::Key, bytes: &mut [u8]) -> Result<(), super::Error> {
|
||||||
if let Some(key) = key {
|
if let super::Key::Some(key) = key {
|
||||||
use aes::cipher::BlockDecrypt;
|
use aes::cipher::BlockDecrypt;
|
||||||
for chunk in bytes.chunks_mut(16) {
|
for chunk in bytes.chunks_mut(16) {
|
||||||
key.decrypt_block(aes::Block::from_mut_slice(chunk))
|
key.decrypt_block(aes::Block::from_mut_slice(chunk))
|
||||||
|
@ -89,7 +85,7 @@ fn decrypt(key: Option<&aes::Aes256>, bytes: &mut [u8]) -> Result<(), super::Err
|
||||||
impl PakReader {
|
impl PakReader {
|
||||||
#[cfg(not(feature = "encryption"))]
|
#[cfg(not(feature = "encryption"))]
|
||||||
pub fn new_any<R: Read + Seek>(reader: &mut R) -> Result<Self, super::Error> {
|
pub fn new_any<R: Read + Seek>(reader: &mut R) -> Result<Self, super::Error> {
|
||||||
Self::new_any_inner(reader)
|
Self::new_any_inner(reader, super::Key::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
|
@ -97,30 +93,19 @@ impl PakReader {
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
key: Option<aes::Aes256>,
|
key: Option<aes::Aes256>,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
Self::new_any_inner(reader, key)
|
Self::new_any_inner(reader, key.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_any_inner<R: Read + Seek>(
|
fn new_any_inner<R: Read + Seek>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
#[cfg(feature = "encryption")] key: Option<aes::Aes256>,
|
key: super::Key,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
let mut log = "\n".to_owned();
|
let mut log = "\n".to_owned();
|
||||||
|
|
||||||
for ver in Version::iter() {
|
for ver in Version::iter() {
|
||||||
match Pak::read(
|
match Pak::read(&mut *reader, ver, &key) {
|
||||||
&mut *reader,
|
Ok(pak) => return Ok(Self { pak, key }),
|
||||||
ver,
|
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
key.as_ref(),
|
|
||||||
) {
|
|
||||||
Ok(pak) => {
|
|
||||||
return Ok(Self {
|
|
||||||
pak,
|
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
key,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?,
|
Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,25 +126,15 @@ impl PakReader {
|
||||||
version: super::Version,
|
version: super::Version,
|
||||||
key: Option<aes::Aes256>,
|
key: Option<aes::Aes256>,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
Self::new_inner(reader, version, key)
|
Self::new_inner(reader, version, key.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner<R: Read + Seek>(
|
fn new_inner<R: Read + Seek>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
version: super::Version,
|
version: super::Version,
|
||||||
#[cfg(feature = "encryption")] key: Option<aes::Aes256>,
|
key: super::Key,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
Pak::read(
|
Pak::read(reader, version, &key).map(|pak| Self { pak, key })
|
||||||
reader,
|
|
||||||
version,
|
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
key.as_ref(),
|
|
||||||
)
|
|
||||||
.map(|pak| Self {
|
|
||||||
pak,
|
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
key,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn version(&self) -> super::Version {
|
pub fn version(&self) -> super::Version {
|
||||||
|
@ -195,8 +170,7 @@ impl PakReader {
|
||||||
reader,
|
reader,
|
||||||
self.pak.version,
|
self.pak.version,
|
||||||
&self.pak.compression,
|
&self.pak.compression,
|
||||||
#[cfg(feature = "encryption")]
|
&self.key,
|
||||||
self.key.as_ref(),
|
|
||||||
writer,
|
writer,
|
||||||
),
|
),
|
||||||
None => Err(super::Error::MissingEntry(path.to_owned())),
|
None => Err(super::Error::MissingEntry(path.to_owned())),
|
||||||
|
@ -214,7 +188,6 @@ impl PakReader {
|
||||||
writer.seek(io::SeekFrom::Start(self.pak.index_offset.unwrap()))?;
|
writer.seek(io::SeekFrom::Start(self.pak.index_offset.unwrap()))?;
|
||||||
Ok(PakWriter {
|
Ok(PakWriter {
|
||||||
pak: self.pak,
|
pak: self.pak,
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
key: self.key,
|
key: self.key,
|
||||||
writer,
|
writer,
|
||||||
})
|
})
|
||||||
|
@ -232,6 +205,7 @@ impl<W: Write + Seek> PakWriter<W> {
|
||||||
PakWriter {
|
PakWriter {
|
||||||
pak: Pak::new(version, mount_point, path_hash_seed),
|
pak: Pak::new(version, mount_point, path_hash_seed),
|
||||||
writer,
|
writer,
|
||||||
|
key: super::Key::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,13 +220,13 @@ impl<W: Write + Seek> PakWriter<W> {
|
||||||
PakWriter {
|
PakWriter {
|
||||||
pak: Pak::new(version, mount_point, path_hash_seed),
|
pak: Pak::new(version, mount_point, path_hash_seed),
|
||||||
writer,
|
writer,
|
||||||
key,
|
key: key.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
writer: W,
|
writer: W,
|
||||||
#[cfg(feature = "encryption")] key: Option<aes::Aes256>,
|
key: super::Key,
|
||||||
version: Version,
|
version: Version,
|
||||||
mount_point: String,
|
mount_point: String,
|
||||||
path_hash_seed: Option<u64>,
|
path_hash_seed: Option<u64>,
|
||||||
|
@ -260,7 +234,6 @@ impl<W: Write + Seek> PakWriter<W> {
|
||||||
PakWriter {
|
PakWriter {
|
||||||
pak: Pak::new(version, mount_point, path_hash_seed),
|
pak: Pak::new(version, mount_point, path_hash_seed),
|
||||||
writer,
|
writer,
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
key,
|
key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,11 +278,7 @@ impl<W: Write + Seek> PakWriter<W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_index(mut self) -> Result<W, super::Error> {
|
pub fn write_index(mut self) -> Result<W, super::Error> {
|
||||||
self.pak.write(
|
self.pak.write(&mut self.writer, &self.key)?;
|
||||||
&mut self.writer,
|
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
self.key,
|
|
||||||
)?;
|
|
||||||
Ok(self.writer)
|
Ok(self.writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,7 +287,7 @@ impl Pak {
|
||||||
fn read<R: Read + Seek>(
|
fn read<R: Read + Seek>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
version: super::Version,
|
version: super::Version,
|
||||||
#[cfg(feature = "encryption")] key: Option<&aes::Aes256>,
|
key: &super::Key,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
// read footer to get index, encryption & compression info
|
// read footer to get index, encryption & compression info
|
||||||
reader.seek(io::SeekFrom::End(-version.size()))?;
|
reader.seek(io::SeekFrom::End(-version.size()))?;
|
||||||
|
@ -468,7 +437,7 @@ impl Pak {
|
||||||
fn write<W: Write + Seek>(
|
fn write<W: Write + Seek>(
|
||||||
&self,
|
&self,
|
||||||
writer: &mut W,
|
writer: &mut W,
|
||||||
#[cfg(feature = "encryption")] _key: Option<aes::Aes256>,
|
_key: &super::Key,
|
||||||
) -> Result<(), super::Error> {
|
) -> Result<(), super::Error> {
|
||||||
let index_offset = writer.stream_position()?;
|
let index_offset = writer.stream_position()?;
|
||||||
|
|
||||||
|
@ -696,7 +665,7 @@ fn pad_zeros_to_alignment(v: &mut Vec<u8>, alignment: usize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
fn encrypt(key: Aes256, bytes: &mut [u8]) {
|
fn encrypt(key: aes::Aes256, bytes: &mut [u8]) {
|
||||||
use aes::cipher::BlockEncrypt;
|
use aes::cipher::BlockEncrypt;
|
||||||
for chunk in bytes.chunks_mut(16) {
|
for chunk in bytes.chunks_mut(16) {
|
||||||
key.encrypt_block(aes::Block::from_mut_slice(chunk))
|
key.encrypt_block(aes::Block::from_mut_slice(chunk))
|
||||||
|
|
|
@ -96,7 +96,7 @@ fn test_read(version: repak::Version, _file_name: &str, bytes: &[u8]) {
|
||||||
let len = inner_reader.seek(SeekFrom::End(0)).unwrap();
|
let len = inner_reader.seek(SeekFrom::End(0)).unwrap();
|
||||||
let mut reader = ReadCounter::new_size(inner_reader, len as usize);
|
let mut reader = ReadCounter::new_size(inner_reader, len as usize);
|
||||||
|
|
||||||
let pak = repak::PakReader::new_any(&mut reader, Some(key)).unwrap();
|
let pak = repak::PakReader::new_any_with_key(&mut reader, Some(key)).unwrap();
|
||||||
|
|
||||||
assert_eq!(pak.mount_point(), "../mount/point/root/");
|
assert_eq!(pak.mount_point(), "../mount/point/root/");
|
||||||
assert_eq!(pak.version(), version);
|
assert_eq!(pak.version(), version);
|
||||||
|
@ -159,10 +159,10 @@ fn test_write(_version: repak::Version, _file_name: &str, bytes: &[u8]) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut reader = std::io::Cursor::new(bytes);
|
let mut reader = std::io::Cursor::new(bytes);
|
||||||
let pak_reader = repak::PakReader::new_any(&mut reader, Some(key)).unwrap();
|
let pak_reader = repak::PakReader::new_any_with_key(&mut reader, Some(key)).unwrap();
|
||||||
|
|
||||||
let writer = Cursor::new(vec![]);
|
let writer = Cursor::new(vec![]);
|
||||||
let mut pak_writer = repak::PakWriter::new(
|
let mut pak_writer = repak::PakWriter::new_with_key(
|
||||||
writer,
|
writer,
|
||||||
None,
|
None,
|
||||||
pak_reader.version(),
|
pak_reader.version(),
|
||||||
|
@ -191,7 +191,7 @@ fn test_rewrite_index(_version: repak::Version, _file_name: &str, bytes: &[u8])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut buf = std::io::Cursor::new(bytes.to_vec());
|
let mut buf = std::io::Cursor::new(bytes.to_vec());
|
||||||
let pak_reader = repak::PakReader::new_any(&mut buf, Some(key)).unwrap();
|
let pak_reader = repak::PakReader::new_any_with_key(&mut buf, Some(key)).unwrap();
|
||||||
|
|
||||||
let rewrite = pak_reader
|
let rewrite = pak_reader
|
||||||
.into_pakwriter(buf)
|
.into_pakwriter(buf)
|
||||||
|
|
Loading…
Reference in a new issue