use std;
use std::io::{Read, Error, ErrorKind};
pub trait Reader {
fn read_u8(&mut self) -> std::io::Result<Option<u8>>;
fn read_u16(&mut self) -> std::io::Result<Option<u16>>;
fn read_u32(&mut self) -> std::io::Result<Option<u32>>;
fn read_u64(&mut self) -> std::io::Result<Option<u64>>;
fn read_bytes(&mut self, buf: &mut [u8]) -> std::io::Result<usize>;
fn read_string(&mut self) -> std::io::Result<Option<String>>;
}
pub struct BasicReader<'a> {
read: &'a mut Read
}
impl<'a> BasicReader<'a> {
pub fn new(read: &'a mut Read) -> BasicReader {
BasicReader {
read: read
}
}
}
impl<'a> Reader for BasicReader<'a> {
fn read_u8(&mut self) -> std::io::Result<Option<u8>> {
let mut buf = [0];
match self.read.read(&mut buf[..]) {
Ok(1) => Ok(Some(buf[0])),
Ok(_) => Ok(None),
Err(err) => {
return Err(err)
}
}
}
fn read_u16(&mut self) -> std::io::Result<Option<u16>> {
let mut buf = [0; 2];
match self.read.read(&mut buf[..]) {
Ok(2) => {
let a = (buf[0] as u16) << 8;
let b = buf[1] as u16;
Ok(Some(a | b))
},
Ok(_) => Ok(None),
Err(err) => {
Err(err)
}
}
}
fn read_u32(&mut self) -> std::io::Result<Option<u32>> {
let mut buf = [0; 4];
match self.read.read(&mut buf[..]) {
Ok(4) => {
let a = (buf[0] as u32) << 24;
let b = (buf[1] as u32) << 16;
let c = (buf[2] as u32) << 8;
let d = buf[3] as u32;
Ok(Some(a | b | c | d))
},
Ok(_) => Ok(None),
Err(err) => {
Err(err)
}
}
}
fn read_u64(&mut self) -> std::io::Result<Option<u64>> {
let mut buf = [0; 8];
match self.read.read(&mut buf[..]) {
Ok(8) => {
let a = (buf[0] as u64) << 56;
let b = (buf[1] as u64) << 48;
let c = (buf[2] as u64) << 40;
let d = (buf[3] as u64) << 32;
let e = (buf[4] as u64) << 24;
let f = (buf[5] as u64) << 16;
let g = (buf[6] as u64) << 8;
let h = buf[7] as u64;
Ok(Some(a | b | c | d | e | f | g | h))
},
Ok(_) => Ok(None),
Err(err) => {
Err(err)
}
}
}
fn read_bytes(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.read.read(buf)
}
fn read_string(&mut self) -> std::io::Result<Option<String>> {
let len = match try!(self.read_u16()) {
Some(len) => len as usize,
None => {
return Ok(None)
}
};
let mut buf = vec![0 as u8; len];
let n = try!(self.read_bytes(&mut buf[..]));
if n != len {
return Ok(None)
}
let s = match String::from_utf8(buf) {
Ok(s) => s,
Err(err) => {
return Err(Error::new(ErrorKind::Other, format!("encoding error: {}", err)))
}
};
return Ok(Some(s))
}
}