extraction works

This commit is contained in:
lif 2018-09-30 17:45:58 -07:00
parent 1ae3f882a6
commit 46f01f262f
2 changed files with 58 additions and 5 deletions

8
src/main.rs Normal file
View File

@ -0,0 +1,8 @@
use std::fs::File;
pub mod one;
fn main() {
let mut infile = File::open("foo.one").unwrap();
one::OneJod::from_archive(&mut infile).extract();
}

View File

@ -1,20 +1,23 @@
extern crate byteorder;
extern crate prs_rust;
use std::io::{Read, Seek};
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};
use self::byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};
use self::prs_rust::prs;
use std::str;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom, Write};
struct OneJod<R: Read + Seek> {
pub struct OneJod<R: Read + Seek> {
read_handle: R,
header: OneJodHead,
entries: Vec<OneJodEntry>,
}
impl<R> OneJod<R>
where
R: Read + Seek,
{
fn from_archive(mut input: R) -> OneJod<R> {
pub fn from_archive(mut input: R) -> OneJod<R> {
let mut head = OneJodHead {
magic: [0; 16],
_unknown1: 0,
@ -23,13 +26,52 @@ where
reserved: [0; 128],
};
input.read_exact(&mut head.magic);
assert_eq!(head.magic(), b"ThisIsOneFile\0\0\0");
head._unknown1 = input.read_u32::<byteorder::LittleEndian>().unwrap();
input.read_exact(&mut head.category);
head.file_count = input.read_u32::<byteorder::LittleEndian>().unwrap();
input.read_exact(&mut head.reserved);
let mut entries = Vec::new();
for i in 0..head.file_count() {
let mut entry = OneJodEntry {
_unknown1: 0,
id: 0,
size_cmp: 0,
_unknown2: 0,
size_dec: 0,
id_again: 0,
offset: 0,
file_name: [0; 188],
};
entry._unknown1 = input.read_u32::<byteorder::LittleEndian>().unwrap();
entry.id = input.read_u32::<byteorder::LittleEndian>().unwrap();
entry.size_cmp = input.read_u32::<byteorder::LittleEndian>().unwrap();
entry._unknown2 = input.read_u32::<byteorder::LittleEndian>().unwrap();
entry.size_dec = input.read_u32::<byteorder::LittleEndian>().unwrap();
entry.id_again = input.read_u32::<byteorder::LittleEndian>().unwrap();
entry.offset = input.read_u32::<byteorder::LittleEndian>().unwrap();
input.read_exact(&mut entry.file_name);
assert_eq!(entry.id(), i);
entries.push(entry);
}
OneJod{
read_handle: input,
header: head,
entries,
}
}
pub fn extract(&mut self) {
for entry in &self.entries {
let mut cmp_buf = vec![0u8; entry.size_cmp() as usize];
self.read_handle.seek(SeekFrom::Start(entry.offset() as u64));
self.read_handle.read_exact(cmp_buf.as_mut_slice());
let mut dec_buf = prs::decompress::Decompressor::new(&cmp_buf).decompress();
println!("{}", entry.file_name());
let mut file_out = File::create(entry.file_name()).unwrap();
file_out.write_all(&dec_buf);
}
}
}
@ -91,7 +133,10 @@ impl OneJodEntry {
fn offset(&self) -> u32 { self.offset }
fn set_offset(&mut self, n: u32) { self.offset = n; }
fn file_name(&self) -> &str { str::from_utf8(&self.file_name).unwrap() }
fn file_name(&self) -> &str {
let idx = self.file_name.iter().position(|x| *x == 0u8).unwrap();
str::from_utf8(&self.file_name[0..idx]).unwrap()
}
fn file_name_mut(&mut self) -> &mut str { str::from_utf8_mut(&mut self.file_name).unwrap() }
fn set_file_name(&mut self, n: &str) { self.file_name.copy_from_slice(n.as_bytes()); }
}