84 lines
2.0 KiB
Rust
84 lines
2.0 KiB
Rust
use block::Block;
|
|
use ops::{num_to_op, Operation};
|
|
use Result;
|
|
|
|
pub trait BinReadable {
|
|
fn get(&mut self) -> Result<u8>;
|
|
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<u8>;
|
|
fn read_u16(&mut self) -> Result<u16>;
|
|
fn read_u32(&mut self) -> Result<u32>;
|
|
|
|
fn read_i8(&mut self) -> Result<i8>;
|
|
fn read_i16(&mut self) -> Result<i16>;
|
|
fn read_i32(&mut self) -> Result<i32>;
|
|
|
|
fn read_block(&mut self) -> Result<Block>;
|
|
fn read_op(&mut self) -> Result<&'static Operation>;
|
|
}
|
|
|
|
impl<T: BinReadable> 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<u8> {
|
|
self.get()
|
|
}
|
|
|
|
fn read_u16(&mut self) -> Result<u16> {
|
|
let a = u16::from(self.read_u8()?);
|
|
let b = u16::from(self.read_u8()?);
|
|
Ok(a << 8 | b)
|
|
}
|
|
|
|
fn read_u32(&mut self) -> Result<u32> {
|
|
let a = u32::from(self.read_u16()?);
|
|
let b = u32::from(self.read_u16()?);
|
|
Ok(a << 16 | b)
|
|
}
|
|
fn read_i8(&mut self) -> Result<i8> {
|
|
Ok(self.get()? as i8)
|
|
}
|
|
|
|
fn read_i16(&mut self) -> Result<i16> {
|
|
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<i32> {
|
|
let a = i32::from(self.read_u16()?);
|
|
let b = i32::from(self.read_u16()?);
|
|
Ok(a << 16 | b)
|
|
}
|
|
|
|
fn read_block(&mut self) -> Result<Block> {
|
|
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()?))
|
|
}
|
|
}
|