use argh::FromArgs;
use assembly_pack::pk::file::PKEntry;
use assembly_pack::pk::reader::{PackEntryAccessor, PackFile};
use std::cmp::Ordering;
use std::fs::File;
use std::io::{self, BufRead, BufReader, Seek};
use std::path::PathBuf;
fn print_entry<'b, 'a, T>(
entries: &'b mut PackEntryAccessor<'b, 'a, T>,
entry: Option<io::Result<PKEntry>>,
crc: u32,
) where
T: BufRead + Seek,
{
match entry {
Some(Ok(data)) => {
match data.crc.cmp(&crc) {
Ordering::Less => {
let right = entries.get_entry(data.right);
print_entry(entries, right, crc);
}
Ordering::Greater => {
let left = entries.get_entry(data.left);
print_entry(entries, left, crc);
}
Ordering::Equal => {
let mut stream = entries.get_file_mut().get_file_data(data).unwrap();
let mut stdout = std::io::stdout();
std::io::copy(&mut stream, &mut stdout).unwrap();
}
}
}
Some(Err(e)) => println!("{:?}", e),
None => {}
}
}
#[derive(FromArgs)]
struct Args {
#[argh(positional)]
path: PathBuf,
#[argh(positional)]
crc: u32,
}
fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
let args: Args = argh::from_env();
let file = File::open(args.path)?;
let mut reader = BufReader::new(file);
let mut pack = PackFile::open(&mut reader);
let header = pack.get_header()?;
let mut entries = pack.get_entry_accessor(header.file_list_base_addr)?;
let root = entries.get_root_entry();
print_entry(&mut entries, root, args.crc);
Ok(())
}