//! Scratch analysis: inventory one UI screen's pak — every entry, and for RATC //! entries the children they bundle. Optionally write an entry's decompressed //! bytes out for hex inspection. //! //! Run: cargo run -p sylpheed-formats --example ui_screen -- [--dump 0xHASH out.bin] use sylpheed_formats::pak::{self, PakArchive}; use sylpheed_formats::ratc; fn main() { let mut args = std::env::args().skip(1); let pak = args.next().expect("usage: ui_screen [--dump 0xHASH out.bin]"); let arc = PakArchive::open(&pak).expect("open pak"); let rest: Vec = args.collect(); if rest.first().map(|s| s == "--dump").unwrap_or(false) { let h = u32::from_str_radix(rest[1].trim_start_matches("0x"), 16).unwrap(); let bytes = arc.read_by_hash(h).expect("entry present").expect("decompress"); std::fs::write(&rest[2], &bytes).unwrap(); println!("wrote {} bytes to {}", bytes.len(), rest[2]); return; } if rest.first().map(|s| s == "--child").unwrap_or(false) { // --child 0xHASH : carve one RATC child out by its // listed offset/size, so a 165-byte layout record can be hexdumped alone. let h = u32::from_str_radix(rest[1].trim_start_matches("0x"), 16).unwrap(); let bytes = arc.read_by_hash(h).expect("entry present").expect("decompress"); let kids = ratc::parse(&bytes).expect("ratc"); let k = kids.iter().find(|k| k.name == rest[2]).expect("child not found"); std::fs::write(&rest[3], &bytes[k.offset..k.offset + k.size]).unwrap(); println!("wrote {} B ({} @ {:#x}) to {}", k.size, k.name, k.offset, rest[3]); return; } println!("{pak}: {} entries", arc.len()); for e in arc.entries() { let Ok(bytes) = arc.read(e) else { println!(" {:08x} ", e.name_hash); continue; }; let label = pak::inner_format_label(&bytes); println!(" {:08x} {:>9} B {}", e.name_hash, bytes.len(), label); if ratc::is_ratc(&bytes) { if let Some(kids) = ratc::parse(&bytes) { for k in &kids { println!(" - {:<40} {:>9} B {}", k.name, k.size, k.kind); } if kids.is_empty() { println!(" (no children found)"); } } } } }