mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
Allow converting PakReader into PakWriter to append files to an existing pak
This commit is contained in:
parent
02307378b2
commit
17ddf22e73
2 changed files with 60 additions and 3 deletions
|
@ -22,6 +22,7 @@ pub struct PakWriter<W: Write + Seek> {
|
||||||
pub struct Pak {
|
pub struct Pak {
|
||||||
version: Version,
|
version: Version,
|
||||||
mount_point: String,
|
mount_point: String,
|
||||||
|
index_offset: Option<u64>,
|
||||||
index: Index,
|
index: Index,
|
||||||
compression: Vec<super::Compression>,
|
compression: Vec<super::Compression>,
|
||||||
}
|
}
|
||||||
|
@ -31,6 +32,7 @@ impl Pak {
|
||||||
Pak {
|
Pak {
|
||||||
version,
|
version,
|
||||||
mount_point,
|
mount_point,
|
||||||
|
index_offset: None,
|
||||||
index: Index::new(path_hash_seed),
|
index: Index::new(path_hash_seed),
|
||||||
compression: vec![],
|
compression: vec![],
|
||||||
}
|
}
|
||||||
|
@ -121,6 +123,18 @@ impl PakReader {
|
||||||
pub fn files(&self) -> Vec<String> {
|
pub fn files(&self) -> Vec<String> {
|
||||||
self.pak.index.entries().keys().cloned().collect()
|
self.pak.index.entries().keys().cloned().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_pakwriter<W: Write + Seek>(
|
||||||
|
self,
|
||||||
|
mut writer: W,
|
||||||
|
) -> Result<PakWriter<W>, super::Error> {
|
||||||
|
writer.seek(io::SeekFrom::Start(self.pak.index_offset.unwrap()))?;
|
||||||
|
Ok(PakWriter {
|
||||||
|
pak: self.pak,
|
||||||
|
key: self.key,
|
||||||
|
writer,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write + Seek> PakWriter<W> {
|
impl<W: Write + Seek> PakWriter<W> {
|
||||||
|
@ -311,6 +325,7 @@ impl Pak {
|
||||||
Ok(Pak {
|
Ok(Pak {
|
||||||
version,
|
version,
|
||||||
mount_point,
|
mount_point,
|
||||||
|
index_offset: Some(footer.index_offset),
|
||||||
index,
|
index,
|
||||||
compression: footer.compression,
|
compression: footer.compression,
|
||||||
})
|
})
|
||||||
|
|
|
@ -82,7 +82,7 @@ mod test {
|
||||||
|
|
||||||
static AES_KEY: &str = "lNJbw660IOC+kU7cnVQ1oeqrXyhk4J6UAZrCBbcnp94=";
|
static AES_KEY: &str = "lNJbw660IOC+kU7cnVQ1oeqrXyhk4J6UAZrCBbcnp94=";
|
||||||
|
|
||||||
fn test_read(version: repak::Version, bytes: &[u8]) {
|
fn test_read(version: repak::Version, _file_name: &str, bytes: &[u8]) {
|
||||||
use aes::cipher::KeyInit;
|
use aes::cipher::KeyInit;
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
let key = general_purpose::STANDARD
|
let key = general_purpose::STANDARD
|
||||||
|
@ -148,7 +148,7 @@ fn test_read(version: repak::Version, bytes: &[u8]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_write(_version: repak::Version, bytes: &[u8]) {
|
fn test_write(_version: repak::Version, _file_name: &str, bytes: &[u8]) {
|
||||||
use aes::cipher::KeyInit;
|
use aes::cipher::KeyInit;
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
let key = general_purpose::STANDARD
|
let key = general_purpose::STANDARD
|
||||||
|
@ -183,6 +183,29 @@ fn test_write(_version: repak::Version, bytes: &[u8]) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_rewrite_index(_version: repak::Version, _file_name: &str, bytes: &[u8]) {
|
||||||
|
use aes::cipher::KeyInit;
|
||||||
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
|
let key = general_purpose::STANDARD
|
||||||
|
.decode(AES_KEY)
|
||||||
|
.as_ref()
|
||||||
|
.map_err(|_| repak::Error::Base64)
|
||||||
|
.and_then(|bytes| aes::Aes256::new_from_slice(bytes).map_err(|_| repak::Error::Aes))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut buf = std::io::Cursor::new(bytes.to_vec());
|
||||||
|
let pak_reader = repak::PakReader::new_any(&mut buf, Some(key)).unwrap();
|
||||||
|
|
||||||
|
let rewrite = pak_reader
|
||||||
|
.into_pakwriter(buf)
|
||||||
|
.unwrap()
|
||||||
|
.write_index()
|
||||||
|
.unwrap()
|
||||||
|
.into_inner();
|
||||||
|
|
||||||
|
assert_eq!(bytes, rewrite);
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! matrix_test {
|
macro_rules! matrix_test {
|
||||||
( $name:literal, ($($version:literal $exp_version:expr),* $(,)?), $compress:tt, $encrypt:tt, $encryptindex:tt, $body:tt ) => {
|
( $name:literal, ($($version:literal $exp_version:expr),* $(,)?), $compress:tt, $encrypt:tt, $encryptindex:tt, $body:tt ) => {
|
||||||
$( matrix_test_compress!($name, $version, $exp_version, $compress, $encrypt, $encryptindex, $body); )*
|
$( matrix_test_compress!($name, $version, $exp_version, $compress, $encrypt, $encryptindex, $body); )*
|
||||||
|
@ -212,7 +235,10 @@ macro_rules! matrix_test_body {
|
||||||
paste! {
|
paste! {
|
||||||
#[test]
|
#[test]
|
||||||
fn [< test_ $name _version_ $version $compress $encrypt $encryptindex >]() {
|
fn [< test_ $name _version_ $version $compress $encrypt $encryptindex >]() {
|
||||||
$body($exp_version, include_bytes!(concat!("packs/pack_", $version, $compress, $encrypt, $encryptindex, ".pak")));
|
$body(
|
||||||
|
$exp_version,
|
||||||
|
concat!("pack_", $version, $compress, $encrypt, $encryptindex, ".pak"),
|
||||||
|
include_bytes!(concat!("packs/pack_", $version, $compress, $encrypt, $encryptindex, ".pak")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -249,3 +275,19 @@ matrix_test!(
|
||||||
("", /*"_encryptindex"*/),
|
("", /*"_encryptindex"*/),
|
||||||
test_write
|
test_write
|
||||||
);
|
);
|
||||||
|
|
||||||
|
matrix_test!(
|
||||||
|
"rewrite_index",
|
||||||
|
(
|
||||||
|
"v5" repak::Version::V5,
|
||||||
|
"v7" repak::Version::V7,
|
||||||
|
"v8a" repak::Version::V8A,
|
||||||
|
"v8b" repak::Version::V8B,
|
||||||
|
"v9" repak::Version::V9,
|
||||||
|
"v11" repak::Version::V11,
|
||||||
|
),
|
||||||
|
("", "_compress"),
|
||||||
|
("", "_encrypt"),
|
||||||
|
("", /*"_encryptindex"*/),
|
||||||
|
test_rewrite_index
|
||||||
|
);
|
||||||
|
|
Loading…
Reference in a new issue