diff --git a/src/file.rs b/src/file.rs index d9ebb14..f3a2473 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,8 +1,9 @@ //file format "sniff" +use binrw::{binrw, BinReaderExt}; + pub enum Error{ - InvalidMagic, - InvalidVersion, + InvalidHeader(binrw::Error), UnexpectedEOF, } @@ -33,13 +34,19 @@ for block_id in 0..num_blocks{ //each block is compressed with zstd or gz or something */ +#[binrw] +#[brw(little)] #[derive(Clone,Copy)] pub(crate) enum FourCC{ + #[brw(magic=b"SNFM")] Map, + #[brw(magic=b"SNFB")] Bot, + #[brw(magic=b"SNFD")] Demo, } - +#[binrw] +#[brw(little)] struct Header{ /// Type of file fourcc:FourCC, @@ -49,25 +56,23 @@ struct Header{ priming:u64, /// uuid for this file resource:u128, + #[bw(try_calc(u64::try_from(block_location.len())))] + block_count:u64, + #[br(count=block_count)] + block_location:Vec, } -pub(crate) struct BlockLayout{ - count:u64, - location:Vec, -} pub(crate) struct File{ header:Header, - block_layout:BlockLayout, //reference to the data } impl File{ - pub(crate) fn new(input:R)->Result{ - Self{ - header:input.read_le()?, - block_layout:input.read_le()?, - } + pub(crate) fn new(mut input:R)->Result{ + Ok(Self{ + header:input.read_le().map_err(|e|Error::InvalidHeader(e))?, + }) } pub(crate) fn read_block(&mut self,block_id:u64)->Result,Error>{ Err(Error::UnexpectedEOF) diff --git a/src/lib.rs b/src/lib.rs index 2777453..6ea292d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -use std::io::Read; +use binrw::BinReaderExt; pub mod file; pub mod map; @@ -19,30 +19,30 @@ pub enum SNF{ Demo(demo::StreamableDemo), } -pub fn read_snf(input:R)->Result{ - let file=file::File::read(input).map_err(|e|Error::Header(e))?; +pub fn read_snf(input:R)->Result{ + let file=file::File::new(input).map_err(|e|Error::Header(e))?; Ok(match file.fourcc(){ 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::Demo=>SNF::Demo(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?), }) } -pub fn read_map(input:R)->Result{ - let file=file::File::read(input).map_err(|e|Error::Header(e))?; +pub fn read_map(input:R)->Result{ + let file=file::File::new(input).map_err(|e|Error::Header(e))?; match file.fourcc(){ file::FourCC::Map=>Ok(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?), _=>Err(Error::UnexpectedFourCC) } } -pub fn read_bot(input:R)->Result{ - let file=file::File::read(input).map_err(|e|Error::Header(e))?; +pub fn read_bot(input:R)->Result{ + let file=file::File::new(input).map_err(|e|Error::Header(e))?; match file.fourcc(){ file::FourCC::Bot=>Ok(bot::StreamableBot::new(file).map_err(|e|Error::Bot(e))?), _=>Err(Error::UnexpectedFourCC) } } -pub fn read_demo(input:R)->Result{ - let file=file::File::read(input).map_err(|e|Error::Header(e))?; +pub fn read_demo(input:R)->Result{ + let file=file::File::new(input).map_err(|e|Error::Header(e))?; match file.fourcc(){ file::FourCC::Demo=>Ok(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?), _=>Err(Error::UnexpectedFourCC)