Start parsing blocks

This commit is contained in:
widberg 2023-05-26 13:29:35 -04:00
parent 8220b58bd3
commit 1ff6b6595c
11 changed files with 65 additions and 34 deletions

View file

@ -7,3 +7,5 @@ edition = "2021"
[dependencies]
bff = { path = "../bff" }
clap = { version = "4.2.4", features = ["derive"] }
binrw = "0.11.1"
serde_json = "1.0.96"

View file

@ -1,12 +1,13 @@
use std::path::PathBuf;
use std::io::BufReader;
use std::fs::File;
use bff::bigfile::*;
use binrw::io::BufReader;
use serde_json::to_string_pretty;
use std::fs::File;
use std::path::PathBuf;
pub fn extract(bigfile: &PathBuf, _directory: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
let f = File::open(bigfile)?;
let mut reader = BufReader::new(f);
let bigfile_struct = BigFile::read(&mut reader)?;
// print!("{:?}", bigfile_struct);
println!("{}", to_string_pretty(&bigfile_struct)?);
Ok(())
}

View file

@ -7,11 +7,9 @@ mod extract;
#[derive(Subcommand)]
enum Commands {
Extract {
#[arg(short, long, required = true)]
bigfile: PathBuf,
#[arg(short, long, required = true)]
directory: PathBuf,
}
},
}
#[derive(Parser)]
@ -25,8 +23,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = Args::parse();
match &cli.command {
Commands::Extract { bigfile, directory } => {
extract::extract(bigfile, directory)
}
Commands::Extract { bigfile, directory } => extract::extract(bigfile, directory),
}
}

View file

@ -1,3 +1 @@
fn main() {
}
fn main() {}

View file

@ -8,4 +8,3 @@ edition = "2021"
ascii = { version = "1.1.0", features = ["serde"] }
binrw = "0.11.1"
serde = { version = "1.0.160", features = ["derive"] }
serde_json = "1.0.96"

View file

@ -1,8 +1,8 @@
use std::io::{Read, Seek};
use crate::{block::Block, header::*};
use binrw::*;
use serde::Serialize;
use crate::{header::*, block::Block};
#[derive(Serialize, Debug)]
pub struct BigFile {
@ -25,10 +25,15 @@ impl BinRead for BigFile {
_: Self::Args<'_>,
) -> BinResult<Self> {
let header = Header::read_options(reader, endian, ())?;
// Pool
Ok(BigFile {
header
})
let blocks = header
.block_descriptions()
.iter()
.map(|block_description| {
Block::read_options(reader, endian, (block_description.object_count(),)).unwrap()
})
.collect();
Ok(BigFile { header, blocks })
}
}

View file

@ -4,6 +4,8 @@ use serde::Serialize;
use crate::object::Object;
#[derive(BinRead, Serialize, Debug)]
#[br(import(object_count : u32))]
pub struct Block {
#[br(count = object_count, align_after = 2048)]
objects: Vec<Object>,
}

View file

@ -1,7 +1,7 @@
use binrw::*;
use binrw::io::*;
use serde::Serialize;
use crate::strings::FixedStringNULL;
use binrw::io::*;
use binrw::*;
use serde::Serialize;
#[derive(BinRead, Serialize, Debug)]
pub struct BlockDescription {
@ -13,6 +13,12 @@ pub struct BlockDescription {
zero: u32,
}
impl BlockDescription {
pub fn object_count(&self) -> u32 {
self.object_count
}
}
#[derive(BinRead, Serialize, Debug)]
pub struct Header {
version: FixedStringNULL<256>,
@ -38,3 +44,9 @@ pub struct Header {
#[brw(align_after = 2048)]
incredi_builder_string: FixedStringNULL<128>,
}
impl Header {
pub fn block_descriptions(&self) -> &Vec<BlockDescription> {
&self.block_descriptions
}
}

View file

@ -1,5 +1,5 @@
pub mod header;
pub mod bigfile;
pub mod strings;
pub mod block;
pub mod object;
pub mod header;
pub mod object;
pub mod strings;

View file

@ -1,7 +1,20 @@
use binrw::BinRead;
use binrw::binread;
use serde::Serialize;
#[derive(BinRead, Serialize, Debug)]
#[binread]
#[derive(Serialize, Debug)]
pub struct Object {
#[br(temp)]
data_size: u32,
#[br(temp)]
link_header_size: u32,
#[br(temp)]
decompressed_size: u32,
#[br(temp)]
compressed_size: u32,
class_name: u32,
name: u32,
#[br(count = data_size)]
#[serde(skip_serializing)]
data: Vec<u8>,
}

View file

@ -1,11 +1,11 @@
use ascii::AsciiChar;
use ascii::AsciiString;
use ascii::FromAsciiError;
use binrw::io::Read;
use binrw::io::Seek;
use binrw::BinRead;
use binrw::BinResult;
use binrw::Endian;
use binrw::io::Seek;
use binrw::io::Read;
use binrw::BinRead;
use serde::Serialize;
use serde::Serializer;
use std::fmt;
@ -33,7 +33,11 @@ impl<const S: usize> BinRead for FixedStringNULL<S> {
}
// TODO: Don't unwrap
reader.seek(std::io::SeekFrom::Current(i64::try_from(S - values.len() - 1).unwrap())).unwrap();
reader
.seek(std::io::SeekFrom::Current(
i64::try_from(S - values.len() - 1).unwrap(),
))
.unwrap();
return Ok(Self(values));
}
@ -53,7 +57,6 @@ impl<const S: usize> From<FixedStringNULL<S>> for AsciiString {
}
impl<const S: usize> From<FixedStringNULL<S>> for String {
fn from(value: FixedStringNULL<S>) -> Self {
String::from(value.0)
}