use crate::error::Error;
use crate::number::{Signed, SignedVarInt, VarInt};
#[derive(Default)]
pub struct Cursor<'a> {
pub buf: &'a [u8],
pub next: usize,
}
impl<'a> Cursor<'a> {
pub fn new(buf: &'a [u8]) -> Cursor<'a> {
Cursor { buf, next: 0 }
}
pub fn has_content(&self) -> bool {
self.next != self.buf.len()
}
}
impl<'a, R> From<&'a R> for Cursor<'a>
where
R: AsRef<[u8]>,
{
fn from(buf: &'a R) -> Self {
Self::new(buf.as_ref())
}
}
impl<'a> Read for Cursor<'a> {
fn read_exact(&mut self, len: usize) -> Result<&[u8], Error> {
if self.next + len > self.buf.len() {
Err(Error::EndOfBuffer(len))
} else {
let slice = &self.buf[self.next..(self.next + len)];
self.next += len as usize;
Ok(slice)
}
}
fn read_u8(&mut self) -> Result<u8, Error> {
if let Some(&b) = self.buf.get(self.next) {
self.next += 1;
Ok(b)
} else {
Err(Error::EndOfBuffer(1))
}
}
}
pub trait Read: Sized {
fn read_exact(&mut self, len: usize) -> Result<&[u8], Error>;
fn read_u8(&mut self) -> Result<u8, Error> {
let buf = self.read_exact(1)?;
Ok(buf[0])
}
fn read_buf(&mut self) -> Result<&[u8], Error> {
let len: u32 = self.read_var()?;
self.read_exact(len as usize)
}
fn read_u16(&mut self) -> Result<u16, Error> {
let buf = self.read_exact(2)?;
Ok(buf[0] as u16 | ((buf[1] as u16) << 8))
}
fn read_u32(&mut self) -> Result<u32, Error> {
let buf = self.read_exact(4)?;
Ok(buf[0] as u32 | (buf[1] as u32) << 8 | (buf[2] as u32) << 16 | (buf[3] as u32) << 24)
}
fn read_u32_be(&mut self) -> Result<u32, Error> {
let buf = self.read_exact(4)?;
Ok((buf[0] as u32) << 24 | (buf[1] as u32) << 16 | (buf[2] as u32) << 8 | buf[3] as u32)
}
#[inline]
fn read_var<T: VarInt>(&mut self) -> Result<T, Error> {
T::read(self)
}
#[inline]
fn read_var_signed<T: SignedVarInt>(&mut self) -> Result<Signed<T>, Error> {
T::read_signed(self)
}
fn read_string(&mut self) -> Result<&str, Error> {
let buf = self.read_buf()?;
Ok(unsafe { std::str::from_utf8_unchecked(buf) })
}
fn read_f32(&mut self) -> Result<f32, Error> {
let mut buf = [0; 4];
let slice = self.read_exact(4)?;
buf.copy_from_slice(slice);
Ok(f32::from_be_bytes(buf))
}
fn read_f64(&mut self) -> Result<f64, Error> {
let mut buf = [0; 8];
let slice = self.read_exact(8)?;
buf.copy_from_slice(slice);
Ok(f64::from_be_bytes(buf))
}
fn read_i64(&mut self) -> Result<i64, Error> {
let mut buf = [0; 8];
let slice = self.read_exact(8)?;
buf.copy_from_slice(slice);
Ok(i64::from_be_bytes(buf))
}
fn read_u64(&mut self) -> Result<u64, Error> {
let mut buf = [0; 8];
let slice = self.read_exact(8)?;
buf.copy_from_slice(slice);
Ok(u64::from_be_bytes(buf))
}
}