use block::Block; use ops::{num_to_op, Operation}; use Result; pub trait BinReadable { fn get(&mut self) -> Result; fn cur(&self) -> usize; fn len(&self) -> usize; fn slice(&mut self, len: usize) -> &[u8]; fn is_empty(&self) -> bool; } pub trait BinRead { fn has_i8(&self) -> bool; fn has_i16(&self) -> bool; fn has_i32(&self) -> bool; fn read_u8(&mut self) -> Result; fn read_u16(&mut self) -> Result; fn read_u32(&mut self) -> Result; fn read_i8(&mut self) -> Result; fn read_i16(&mut self) -> Result; fn read_i32(&mut self) -> Result; fn read_block(&mut self) -> Result; fn read_op(&mut self) -> Result<&'static Operation>; } impl BinRead for T { fn has_i8(&self) -> bool { self.cur() < self.len() } fn has_i16(&self) -> bool { self.cur() + 1 < self.len() } fn has_i32(&self) -> bool { self.cur() + 3 < self.len() } fn read_u8(&mut self) -> Result { self.get() } fn read_u16(&mut self) -> Result { let a = u16::from(self.read_u8()?); let b = u16::from(self.read_u8()?); Ok(a << 8 | b) } fn read_u32(&mut self) -> Result { let a = u32::from(self.read_u16()?); let b = u32::from(self.read_u16()?); Ok(a << 16 | b) } fn read_i8(&mut self) -> Result { Ok(self.get()? as i8) } fn read_i16(&mut self) -> Result { let a = i16::from(self.read_u8()?); let b = i16::from(self.read_u8()?); Ok((a << 8 | b) as i16) } fn read_i32(&mut self) -> Result { let a = i32::from(self.read_u16()?); let b = i32::from(self.read_u16()?); Ok(a << 16 | b) } fn read_block(&mut self) -> Result { let origin = self.read_u32()?; let len = self.read_u32()? as usize; Ok(Block::new(origin, self.slice(len))) } fn read_op(&mut self) -> Result<&'static Operation> { Ok(num_to_op(self.read_u8()?)) } }