use std::io::{Read, Seek, SeekFrom};
use super::traits::*;
pub trait SeqByteReader {
fn next<U: SizedNumber>(&mut self) -> Option<U>;
fn shift<U: SizedNumber>(&mut self) -> Option<U>;
fn next_slice(&mut self, amount: usize) -> Option<Vec<u8>>;
fn shift_slice(&mut self, amount: usize) -> Option<Vec<u8>>;
fn next_string(&mut self, amount: usize) -> Option<String> {
let slice = self.next_slice(amount)?;
Some(String::from_utf8_lossy(&slice).to_string())
}
fn shift_string(&mut self, amount: usize) -> Option<String> {
let slice = self.shift_slice(amount)?;
Some(String::from_utf8_lossy(&slice).to_string())
}
}
pub trait ESeqByteReader {
fn next_e<U: EndianNumber>(&mut self, bigendian: bool) -> Option<U>;
fn shift_e<U: EndianNumber>(&mut self, bigendian: bool) -> Option<U>;
}
impl<T: Seek + Read> SeqByteReader for T {
fn next<U: SizedNumber>(&mut self) -> Option<U> {
let size = U::size() as isize;
let mut a = vec![0u8; size as usize];
self.read_exact(&mut a).ok()?;
self.seek(SeekFrom::Current(-size as i64)).unwrap();
return U::from_bytes(&a[..]);
}
fn shift<U: SizedNumber>(&mut self) -> Option<U> {
let size = U::size() as isize;
let mut a = vec![0u8; size as usize];
self.read_exact(&mut a).ok()?;
return U::from_bytes(&a[..]);
}
fn next_slice(&mut self, amount: usize) -> Option<Vec<u8>> {
let mut a = vec![0u8; amount];
self.read_exact(&mut a).ok()?;
self.seek(SeekFrom::Current(-(amount as i64))).unwrap();
return Some(a);
}
fn shift_slice(&mut self, amount: usize) -> Option<Vec<u8>> {
let mut a = vec![0u8; amount];
self.read_exact(&mut a).ok()?;
return Some(a);
}
}
impl<T: Seek + Read> ESeqByteReader for T {
fn next_e<U: EndianNumber>(&mut self, bigendian: bool) -> Option<U> {
let size = U::size() as isize;
let mut a = vec![0u8; size as usize];
self.read_exact(&mut a).ok()?;
self.seek(SeekFrom::Current(-size as i64)).unwrap();
return U::from_bytes_e(&a[..], bigendian);
}
fn shift_e<U: EndianNumber>(&mut self, bigendian: bool) -> Option<U> {
let size = U::size() as isize;
let mut a = vec![0u8; size as usize];
self.read_exact(&mut a).ok()?;
return U::from_bytes_e(&a[..], bigendian);
}
}