implement some binrw stuff

This commit is contained in:
Quaternions 2024-01-18 16:59:00 -08:00
parent 040b607792
commit 14e7e4df29
2 changed files with 27 additions and 22 deletions

View File

@ -1,8 +1,9 @@
//file format "sniff" //file format "sniff"
use binrw::{binrw, BinReaderExt};
pub enum Error{ pub enum Error{
InvalidMagic, InvalidHeader(binrw::Error),
InvalidVersion,
UnexpectedEOF, UnexpectedEOF,
} }
@ -33,13 +34,19 @@ for block_id in 0..num_blocks{
//each block is compressed with zstd or gz or something //each block is compressed with zstd or gz or something
*/ */
#[binrw]
#[brw(little)]
#[derive(Clone,Copy)] #[derive(Clone,Copy)]
pub(crate) enum FourCC{ pub(crate) enum FourCC{
#[brw(magic=b"SNFM")]
Map, Map,
#[brw(magic=b"SNFB")]
Bot, Bot,
#[brw(magic=b"SNFD")]
Demo, Demo,
} }
#[binrw]
#[brw(little)]
struct Header{ struct Header{
/// Type of file /// Type of file
fourcc:FourCC, fourcc:FourCC,
@ -49,25 +56,23 @@ struct Header{
priming:u64, priming:u64,
/// uuid for this file /// uuid for this file
resource:u128, resource:u128,
#[bw(try_calc(u64::try_from(block_location.len())))]
block_count:u64,
#[br(count=block_count)]
block_location:Vec<u64>,
} }
pub(crate) struct BlockLayout{
count:u64,
location:Vec<u64>,
}
pub(crate) struct File{ pub(crate) struct File{
header:Header, header:Header,
block_layout:BlockLayout,
//reference to the data //reference to the data
} }
impl File{ impl File{
pub(crate) fn new<R:std::io::Read+std::io::Seek>(input:R)->Result<Self,Error>{ pub(crate) fn new<R:BinReaderExt>(mut input:R)->Result<Self,Error>{
Self{ Ok(Self{
header:input.read_le()?, header:input.read_le().map_err(|e|Error::InvalidHeader(e))?,
block_layout:input.read_le()?, })
}
} }
pub(crate) fn read_block(&mut self,block_id:u64)->Result<Vec<u8>,Error>{ pub(crate) fn read_block(&mut self,block_id:u64)->Result<Vec<u8>,Error>{
Err(Error::UnexpectedEOF) Err(Error::UnexpectedEOF)

View File

@ -1,4 +1,4 @@
use std::io::Read; use binrw::BinReaderExt;
pub mod file; pub mod file;
pub mod map; pub mod map;
@ -19,30 +19,30 @@ pub enum SNF{
Demo(demo::StreamableDemo), Demo(demo::StreamableDemo),
} }
pub fn read_snf<R:Read>(input:R)->Result<SNF,Error>{ pub fn read_snf<R:BinReaderExt>(input:R)->Result<SNF,Error>{
let file=file::File::read(input).map_err(|e|Error::Header(e))?; let file=file::File::new(input).map_err(|e|Error::Header(e))?;
Ok(match file.fourcc(){ Ok(match file.fourcc(){
file::FourCC::Map=>SNF::Map(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?), file::FourCC::Map=>SNF::Map(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?),
file::FourCC::Bot=>SNF::Bot(bot::StreamableBot::new(file).map_err(|e|Error::Bot(e))?), file::FourCC::Bot=>SNF::Bot(bot::StreamableBot::new(file).map_err(|e|Error::Bot(e))?),
file::FourCC::Demo=>SNF::Demo(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?), file::FourCC::Demo=>SNF::Demo(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?),
}) })
} }
pub fn read_map<R:Read>(input:R)->Result<map::StreamableMap,Error>{ pub fn read_map<R:BinReaderExt>(input:R)->Result<map::StreamableMap,Error>{
let file=file::File::read(input).map_err(|e|Error::Header(e))?; let file=file::File::new(input).map_err(|e|Error::Header(e))?;
match file.fourcc(){ match file.fourcc(){
file::FourCC::Map=>Ok(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?), file::FourCC::Map=>Ok(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?),
_=>Err(Error::UnexpectedFourCC) _=>Err(Error::UnexpectedFourCC)
} }
} }
pub fn read_bot<R:Read>(input:R)->Result<bot::StreamableBot,Error>{ pub fn read_bot<R:BinReaderExt>(input:R)->Result<bot::StreamableBot,Error>{
let file=file::File::read(input).map_err(|e|Error::Header(e))?; let file=file::File::new(input).map_err(|e|Error::Header(e))?;
match file.fourcc(){ match file.fourcc(){
file::FourCC::Bot=>Ok(bot::StreamableBot::new(file).map_err(|e|Error::Bot(e))?), file::FourCC::Bot=>Ok(bot::StreamableBot::new(file).map_err(|e|Error::Bot(e))?),
_=>Err(Error::UnexpectedFourCC) _=>Err(Error::UnexpectedFourCC)
} }
} }
pub fn read_demo<R:Read>(input:R)->Result<demo::StreamableDemo,Error>{ pub fn read_demo<R:BinReaderExt>(input:R)->Result<demo::StreamableDemo,Error>{
let file=file::File::read(input).map_err(|e|Error::Header(e))?; let file=file::File::new(input).map_err(|e|Error::Header(e))?;
match file.fourcc(){ match file.fourcc(){
file::FourCC::Demo=>Ok(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?), file::FourCC::Demo=>Ok(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?),
_=>Err(Error::UnexpectedFourCC) _=>Err(Error::UnexpectedFourCC)