use crate::Buf;
use crate::BufError;
use crate::BufMut;
use crate::BufResult;
#[derive(Debug, Clone, Copy)]
pub struct Cursor<B: Buf> {
buffer: B,
position: usize,
}
impl<B: Buf> Cursor<B> {
#[inline(always)]
pub fn new(buffer: B) -> Self {
Self {
buffer,
position: 0,
}
}
#[inline(always)]
pub fn into_inner(self) -> B {
self.buffer
}
#[inline(always)]
pub fn position(&self) -> usize {
self.position
}
}
impl<B: Buf> Cursor<B> {
pub fn remaining(&self) -> usize {
self.buffer.length().saturating_sub(self.position)
}
pub fn is_eof(&self) -> bool {
self.position >= self.buffer.length()
}
pub fn advance(&mut self, amount: usize) -> BufResult<()> {
if self.remaining() < amount {
return Err(BufError::UnexpectedEof);
}
self.position += amount;
Ok(())
}
pub fn rewind(&mut self, amount: usize) -> BufResult<()> {
if self.position < amount {
return Err(BufError::OutOfBounds);
}
self.position -= amount;
Ok(())
}
pub fn seek_to(&mut self, position: usize) -> BufResult<()> {
if position > self.buffer.length() {
return Err(BufError::OutOfBounds);
}
self.position = position;
Ok(())
}
pub fn seek_from_end(&mut self, offset_from_end: usize) -> BufResult<()> {
if offset_from_end > self.buffer.length() {
return Err(BufError::OutOfBounds);
}
self.position = self.buffer.length() - offset_from_end;
Ok(())
}
pub fn peek_u8(&self) -> BufResult<u8> {
self.buffer.get_u8(self.position)
}
pub fn peek_u16_be(&self) -> BufResult<u16> {
self.buffer.get_u16_be(self.position)
}
pub fn peek_u32_be(&self) -> BufResult<u32> {
self.buffer.get_u32_be(self.position)
}
pub fn peek_array<const N: usize>(&self) -> BufResult<[u8; N]> {
self.buffer.get_array::<N>(self.position)
}
pub fn read_u8(&mut self) -> BufResult<u8> {
let val = self.peek_u8()?;
self.advance(1)?;
Ok(val)
}
pub fn read_u16_be(&mut self) -> BufResult<u16> {
let val = self.peek_u16_be()?;
self.advance(2)?;
Ok(val)
}
pub fn read_u32_be(&mut self) -> BufResult<u32> {
let val = self.peek_u32_be()?;
self.advance(4)?;
Ok(val)
}
pub fn read_array<const N: usize>(&mut self) -> BufResult<[u8; N]> {
let val = self.peek_array::<N>()?;
self.advance(N)?;
Ok(val)
}
pub fn read_into(&mut self, destination: &mut [u8]) -> BufResult<()> {
self.buffer.read_into(self.position, destination)?;
self.advance(destination.len())?;
Ok(())
}
}
impl<B: BufMut> Cursor<B> {
pub fn poke_u8(&mut self, val: u8) -> BufResult<()> {
self.buffer.set_u8(self.position, val)
}
pub fn poke_u16_be(&mut self, val: u16) -> BufResult<()> {
self.buffer.set_u16_be(self.position, val)
}
pub fn poke_u32_be(&mut self, val: u32) -> BufResult<()> {
self.buffer.set_u32_be(self.position, val)
}
pub fn poke_array<const N: usize>(&mut self, val: &[u8; N]) -> BufResult<()> {
self.buffer.set_array(self.position, val)
}
pub fn poke_slice(&mut self, src: &[u8]) -> BufResult<()> {
self.buffer.set_slice(self.position, src)
}
pub fn write_u8(&mut self, val: u8) -> BufResult<()> {
self.poke_u8(val)?;
self.advance(1)?;
Ok(())
}
pub fn write_u16_be(&mut self, val: u16) -> BufResult<()> {
self.poke_u16_be(val)?;
self.advance(2)?;
Ok(())
}
pub fn write_u32_be(&mut self, val: u32) -> BufResult<()> {
self.poke_u32_be(val)?;
self.advance(4)?;
Ok(())
}
pub fn write_array<const N: usize>(&mut self, val: &[u8; N]) -> BufResult<()> {
self.poke_array(val)?;
self.advance(N)?;
Ok(())
}
pub fn write_slice(&mut self, src: &[u8]) -> BufResult<()> {
self.poke_slice(src)?;
self.advance(src.len())?;
Ok(())
}
}