Files
RustIJVM/src/block.rs

104 lines
2.2 KiB
Rust

use std::ops;
use Result;
use binread::BinReadable;
#[derive(Debug)]
pub struct Block {
origin: u32,
length: usize,
pointer: usize,
source: Vec<u8>
}
impl Block {
pub fn new(origin: u32, source: &[u8]) -> Block {
Block {
origin,
length: source.len(),
pointer: 0,
source: source.to_owned()
}
}
pub fn jump(&mut self, offset: i32) -> Result<()> {
if offset < 0 {
if (-offset as usize) > self.pointer {
return Err("Jump before block")
}
self.pointer -= -offset as usize;
} else {
if self.pointer + (offset as usize) >= self.length {
return Err("Jump outside of block")
}
self.pointer += offset as usize;
}
Ok(())
}
pub fn seek(&mut self, location: usize) -> Result<()> {
if location >= self.length {
println!("hoho {}", location);
return Err("Seek outside of block")
}
self.pointer = location;
Ok(())
}
pub fn read_string(&mut self) -> Result<String> {
let mut bytes = vec![];
loop {
let c = self.get()?;
if c == 0 {
return match String::from_utf8(bytes) {
Ok(string) => Ok(string),
_ => Err("Invalid string in block")
}
}
bytes.push(c);
}
}
}
impl ops::Index<usize> for Block {
type Output = u8;
fn index(&self, index: usize) -> &<Self as ops::Index<usize>>::Output {
&self.source[index]
}
}
impl BinReadable for Block {
fn get(&mut self) -> Result<u8> {
if self.pointer >= self.length {
return Err("EOF reached")
}
let byte = self.source[self.pointer];
self.pointer += 1;
Ok(byte)
}
fn len(&self) -> usize {
self.source.len()
}
fn cur(&self) -> usize {
self.pointer
}
fn slice(&mut self, len: usize) -> &[u8] {
let slice = &self.source[self.pointer..self.pointer+len];
self.pointer += len;
slice
}
fn is_empty(&self) -> bool {
self.source.is_empty()
}
}