diff --git a/bff-cli/src/main.rs b/bff-cli/src/main.rs index af2c204..6ee20ba 100644 --- a/bff-cli/src/main.rs +++ b/bff-cli/src/main.rs @@ -23,6 +23,7 @@ mod stdio_or_path; use shadow_rs::shadow; +use crate::psc::PscAlgorithm; use crate::stdio_or_path::StdioOrPath; shadow!(build); @@ -119,9 +120,21 @@ enum Commands { key: u8, }, #[clap(alias = "xpsc")] - ExtractPsc { psc: PathBuf, directory: PathBuf }, + ExtractPsc { + psc: PathBuf, + directory: PathBuf, + #[clap(value_enum)] + #[arg(short, long, default_value_t = PscAlgorithm::Lz4)] + algorithm: PscAlgorithm, + }, #[clap(alias = "cpsc")] - CreatePsc { directory: PathBuf, psc: PathBuf }, + CreatePsc { + directory: PathBuf, + psc: PathBuf, + #[clap(value_enum)] + #[arg(short, long, default_value_t = PscAlgorithm::Lz4)] + algorithm: PscAlgorithm, + }, #[clap(alias = "xfl")] ExtractFatLin { fat: PathBuf, @@ -196,8 +209,8 @@ fn main() -> BffCliResult<()> { ), Commands::RoundTrip { bigfile } => round_trip::round_trip(bigfile), Commands::Csc { input, output, key } => csc::csc(input, output, key), - Commands::ExtractPsc { psc, directory } => psc::extract_psc(psc, directory), - Commands::CreatePsc { directory, psc } => psc::create_psc(directory, psc), + Commands::ExtractPsc { psc, directory, algorithm } => psc::extract_psc(psc, directory, algorithm), + Commands::CreatePsc { directory, psc, algorithm } => psc::create_psc(directory, psc, algorithm), Commands::ExtractFatLin { fat, lin, diff --git a/bff-cli/src/psc.rs b/bff-cli/src/psc.rs index b816eee..c33d57e 100644 --- a/bff-cli/src/psc.rs +++ b/bff-cli/src/psc.rs @@ -4,12 +4,32 @@ use std::path::Path; use bff::tsc::Psc; use bff::BufReader; +use clap::ValueEnum; use crate::error::BffCliResult; -pub fn extract_psc(psc: &Path, directory: &Path) -> BffCliResult<()> { +#[derive(ValueEnum, Clone, Copy)] +pub enum PscAlgorithm { + None, + Lz4, +} + +impl From for bff::tsc::PscAlgorithm { + fn from(algorithm: PscAlgorithm) -> Self { + match algorithm { + PscAlgorithm::None => Self::None, + PscAlgorithm::Lz4 => Self::Lz4, + } + } +} + +pub fn extract_psc( + psc: &Path, + directory: &Path, + algorithm: &PscAlgorithm, +) -> BffCliResult<()> { let mut psc_reader = BufReader::new(File::open(psc)?); - let psc = Psc::read(&mut psc_reader)?; + let psc = Psc::read(&mut psc_reader, (*algorithm).into())?; for (path, data) in psc.tscs { let tsc_path = directory.join(path); @@ -43,13 +63,17 @@ fn read_files_into_psc_recursively( Ok(()) } -pub fn create_psc(directory: &Path, psc_path: &Path) -> BffCliResult<()> { +pub fn create_psc( + directory: &Path, + psc_path: &Path, + algorithm: &PscAlgorithm, +) -> BffCliResult<()> { let mut psc = Psc::default(); read_files_into_psc_recursively(&mut psc, directory, directory)?; let mut psc_writer = BufWriter::new(File::create(psc_path)?); - psc.write(&mut psc_writer)?; + psc.write(&mut psc_writer, (*algorithm).into())?; Ok(()) } diff --git a/bff/src/tsc/psc.rs b/bff/src/tsc/psc.rs index fb0db29..48ed09c 100644 --- a/bff/src/tsc/psc.rs +++ b/bff/src/tsc/psc.rs @@ -82,26 +82,53 @@ impl BinWrite for Psc { } } +#[derive(Clone, Copy)] +pub enum PscAlgorithm { + None, + Lz4, +} + impl Psc { - pub fn read(reader: &mut R) -> BffResult { - let mut psc_data = Cursor::new(lz4_decompress_data_with_header_parser_internal( - reader, - Endian::Little, - (), - )?); - - Ok(::read(&mut psc_data)?) + pub fn read( + reader: &mut R, + psc_compression: PscAlgorithm, + ) -> BffResult { + match psc_compression { + PscAlgorithm::None => Ok(::read(reader)?), + PscAlgorithm::Lz4 => { + let mut psc_data = Cursor::new(lz4_decompress_data_with_header_parser_internal( + reader, + Endian::Little, + (), + )?); + + Ok(::read(&mut psc_data)?) + } + } } - pub fn write(&self, writer: &mut W) -> BffResult<()> { + pub fn write( + &self, + writer: &mut W, + psc_compression: PscAlgorithm, + ) -> BffResult<()> { let mut psc_data = Cursor::new(Vec::new()); ::write(self, &mut psc_data)?; - lz4_compress_data_with_header_writer_internal( - &psc_data.into_inner(), - writer, - Endian::Little, - (), - )?; + + match psc_compression { + PscAlgorithm::None => { + writer.write_all(&psc_data.into_inner())?; + } + PscAlgorithm::Lz4 => { + lz4_compress_data_with_header_writer_internal( + &psc_data.into_inner(), + writer, + Endian::Little, + (), + )?; + } + } + Ok(()) } }