mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/data/mod.rs')
| -rw-r--r-- | src/data/mod.rs | 87 |
1 files changed, 62 insertions, 25 deletions
diff --git a/src/data/mod.rs b/src/data/mod.rs index 589a33c..c658210 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,7 +1,7 @@ //! all the IO use flate2::{ - Compress, CompressError, Compression, Decompress, DecompressError, FlushCompress, - FlushDecompress, Status, + Compress, CompressError as CError, Compression, Decompress, DecompressError as DError, + FlushCompress, FlushDecompress, Status, }; use std::collections::HashMap; use std::error::Error; @@ -124,16 +124,28 @@ impl<'d> DataRead<'d> { Ok(len) } - pub fn read_chunk<E>(&mut self, f: impl FnOnce(&mut DataRead) -> Result<(), E>) -> Result<(), E> + pub fn read_chunk<E>( + &mut self, + big: bool, + f: impl FnOnce(&mut DataRead) -> Result<(), E>, + ) -> Result<(), E> where E: Error + From<ReadError>, { - let len = self.read_u32()? as usize; + let len = if big { + self.read_u32()? as usize + } else { + self.read_u16()? as usize + }; self.read = 0; let r = f(self); match r { Err(e) => { // skip this chunk + if len < self.read { + eprintln!("overread ({e:?})"); + return Err(e); + } let n = len - self.read; if n != 0 { self.skip(n)?; @@ -167,7 +179,7 @@ impl<'d> DataRead<'d> { Ok(()) } - pub fn deflate(&mut self) -> Result<Vec<u8>, ReadError> { + pub fn deflate(&mut self) -> Result<Vec<u8>, DecompressError> { let mut dec = Decompress::new(true); let mut raw = Vec::<u8>::new(); raw.reserve(1024); @@ -187,7 +199,7 @@ impl<'d> DataRead<'d> { } if dec.total_in() == t_in && dec.total_out() == t_out { // protect against looping forever - return Err(ReadError::DecompressStall); + return Err(DecompressError::DecompressStall); } raw.reserve(1024); } @@ -198,11 +210,15 @@ impl<'d> DataRead<'d> { } #[derive(Debug, Error)] -pub enum ReadError { +pub enum DecompressError { + #[error("zlib decompression failed")] + Decompress(#[from] DError), #[error("decompressor stalled before completion")] DecompressStall, - #[error("zlib decompession failed")] - Decompress(#[from] DecompressError), +} + +#[derive(Debug, Error)] +pub enum ReadError { #[error("buffer underflow (expected {need} but got {have})")] Underflow { need: usize, have: usize }, #[error("expected {0}")] @@ -309,7 +325,17 @@ impl<'d> DataWrite<'d> { } } - pub fn inflate(self, to: &mut DataWrite) -> Result<(), WriteError> { + /// eat this datawrite + /// + /// panics if ref write buffer + pub fn consume(self) -> Vec<u8> { + match self.data { + WriteBuff::Vec(v) => v, + WriteBuff::Ref { .. } => unreachable!(), + } + } + + pub fn inflate(self, to: &mut DataWrite) -> Result<(), CompressError> { // compress into the provided buffer let WriteBuff::Vec(raw) = self.data else { unreachable!("write buffer not owned") @@ -324,7 +350,7 @@ impl<'d> DataWrite<'d> { match comp.compress(&raw, &mut dst[*pos..], FlushCompress::Finish)? { // there's no more input (and the flush mode says so), but we can't resize the output Status::Ok | Status::BufError => { - return Err(WriteError::CompressEof( + return Err(CompressError::CompressEof( raw.len() - comp.total_in() as usize, )) } @@ -350,7 +376,7 @@ impl<'d> DataWrite<'d> { } if comp.total_in() == t_in && comp.total_out() == t_out { // protect against looping forever - return Err(WriteError::CompressStall); + return Err(CompressError::CompressStall); } dst.reserve(1024); } @@ -370,20 +396,21 @@ impl Default for DataWrite<'static> { } #[derive(Debug, Error)] +pub enum CompressError { + #[error(transparent)] + Compress(#[from] CError), + #[error("compression overflow with {0} bytes of input remaining")] + CompressEof(usize), + #[error("compressor stalled before completion")] + CompressStall, +} + +#[derive(Debug, Error)] pub enum WriteError { #[error("buffer overflow (expected {need} but got {have})")] Overflow { need: usize, have: usize }, #[error("string too long ({len} bytes of {})", u16::MAX)] TooLong { len: usize }, - #[error("zlib compression failed")] - Compress { - #[from] - source: CompressError, - }, - #[error("compression overflow with {0} bytes of input remaining")] - CompressEof(usize), - #[error("compressor stalled before completion")] - CompressStall, } impl PartialEq for WriteError { @@ -428,18 +455,28 @@ pub trait Serializer<D> { fn serialize(&mut self, buff: &mut DataWrite<'_>, data: &D) -> Result<(), Self::WriteError>; } -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct GridPos(pub u16, pub u16); +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct GridPos(pub usize, pub usize); impl From<u32> for GridPos { fn from(value: u32) -> Self { - GridPos((value >> 16) as u16, value as u16) + GridPos((value >> 16) as u16 as usize, value as u16 as usize) } } impl From<GridPos> for u32 { + /// ``` + /// # use mindus::data::GridPos; + /// assert_eq!(GridPos::from(u32::from(GridPos(1000, 5))), GridPos(1000, 5)); + /// ``` fn from(value: GridPos) -> Self { - (u32::from(value.0) << 16) | u32::from(value.1) + ((value.0 << 16) | value.1) as u32 + } +} + +impl fmt::Debug for GridPos { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "({0}, {1})", self.0, self.1) } } |