use crate::{Result, Error};
pub trait ReadBytes {
fn peek<F, R>(&mut self, n: usize, f: F) -> Result<R> where F: FnOnce(&[u8]) -> Result<R>;
fn advance(&mut self, n: usize);
fn read<F, R>(&mut self, n: usize, f: F) -> Result<R> where F: FnOnce(&[u8]) -> Result<R> {
let r = self.peek(n, f)?;
self.advance(n);
Ok(r)
}
fn remaining_buffer(&mut self) -> &'_[u8];
fn is_complete(&mut self) -> Result {
if self.remaining_buffer().is_empty() {
Ok(())
} else {
Err(Error::BufferUnderflow)
}
}
}
pub trait TailReadBytes: ReadBytes {
fn peek_tail<F, R>(&mut self, n: usize, f: F) -> Result<R> where F: FnOnce(&[u8]) -> Result<R>;
fn advance_tail(&mut self, n: usize);
fn read_tail<F, R>(&mut self, n: usize, f: F) -> Result<R> where F: FnOnce(&[u8]) -> Result<R> {
let r = self.peek_tail(n, f)?;
self.advance_tail(n);
Ok(r)
}
}
impl<'a, T> ReadBytes for &'a mut T where T: ReadBytes {
fn peek<F, R>(&mut self, n: usize, f: F) -> Result<R> where F: FnOnce(&[u8]) -> Result<R> {
(*self).peek(n, f)
}
fn advance(&mut self, n: usize) {
(*self).advance(n)
}
fn remaining_buffer(&mut self) -> &'_[u8] { (*self).remaining_buffer() }
}
impl<'a, T> TailReadBytes for &'a mut T where T: TailReadBytes {
fn peek_tail<F, R>(&mut self, n: usize, f: F) -> Result<R> where F: FnOnce(&[u8]) -> Result<R> {
(*self).peek_tail(n, f)
}
fn advance_tail(&mut self, n: usize) {
(*self).advance_tail(n)
}
}
pub struct DeBytesReader<'a> {
buf: &'a [u8],
}
impl<'a> DeBytesReader<'a> {
#[must_use] pub fn new(buf: &'a [u8]) -> Self { Self { buf } }
}
impl <'a> ReadBytes for DeBytesReader<'a> {
fn peek<F, R>(&mut self, n: usize, f: F) -> Result<R>
where F: FnOnce(&[u8]) -> Result<R>,
{
if n <= self.buf.len() {
f(&self.buf[..n])
} else {
Err(Error::PrematureEndOfInput)
}
}
fn advance(&mut self, n: usize) {
self.buf = &self.buf[n..];
}
fn remaining_buffer(&mut self) -> &'_[u8] { self.buf }
}
impl<'a> TailReadBytes for DeBytesReader<'a> {
fn peek_tail<F, R>(&mut self, n: usize, f: F) -> Result<R>
where F: FnOnce(&[u8]) -> Result<R>,
{
if n <= self.buf.len() {
f(&self.buf[(self.buf.len() - n)..])
} else {
Err(Error::PrematureEndOfInput)
}
}
fn advance_tail(&mut self, n: usize) {
self.buf = &self.buf[..self.buf.len() - n];
}
}
pub struct ReadFromTail<'a, R>(pub &'a mut R) where R: TailReadBytes;
impl <'a, R> ReadBytes for ReadFromTail<'a, R>
where R: TailReadBytes,
{
fn peek<F, RV>(&mut self, n: usize, f: F) -> Result<RV>
where F: FnOnce(&[u8]) -> Result<RV>,
{
self.0.peek_tail(n, f)
}
fn advance(&mut self, n: usize) {
self.0.advance_tail(n)
}
fn remaining_buffer(&mut self) -> &'_[u8] { self.0.remaining_buffer() }
}
#[cfg(feature="std")]
impl std::io::Read for DeBytesReader<'_> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.buf.read(buf)
}
}
pub trait WriteBytes {
fn write(&mut self, value: &[u8]) -> Result;
}
pub trait TailWriteBytes: WriteBytes {
fn write_tail(&mut self, value: &[u8]) -> Result;
}
pub struct DeBytesWriter<'a> {
buf: &'a mut [u8],
head: usize,
tail: usize,
}
impl<'a> DeBytesWriter<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
let tail = buf.len();
Self { buf, head: 0, tail }
}
pub fn finalize(&mut self) -> Result<usize> {
if self.head == self.tail {
Ok(self.buf.len())
} else {
self.buf.copy_within(self.tail.., self.head);
let len = self.buf.len() - (self.tail - self.head);
self.head = self.tail;
Ok(len)
}
}
pub fn is_complete(&self) -> Result {
if self.head == self.tail {
Ok(())
} else {
Err(Error::BufferUnderflow)
}
}
}
impl<'a> WriteBytes for DeBytesWriter<'a> {
fn write(&mut self, value: &[u8]) -> Result {
if (self.head + value.len()) > self.tail {
Err(Error::BufferOverflow)
} else {
self.buf[self.head..(self.head + value.len())].copy_from_slice(value);
self.head += value.len();
Ok(())
}
}
}
impl<'a> TailWriteBytes for DeBytesWriter<'a> {
fn write_tail(&mut self, value: &[u8]) -> Result {
if (self.head + value.len()) > self.tail {
Err(Error::BufferOverflow)
} else {
let end_offs = self.tail - value.len();
self.buf[end_offs..self.tail].copy_from_slice(value);
self.tail = end_offs;
Ok(())
}
}
}
pub struct WriteToTail<'a, W>(pub &'a mut W) where W: TailWriteBytes;
impl<'a, W> WriteBytes for WriteToTail<'a, W>
where W: TailWriteBytes
{
fn write(&mut self, value: &[u8]) -> Result {
self.0.write_tail(value)
}
}
impl<T> WriteBytes for &mut T where T: WriteBytes {
fn write(&mut self, buf: &[u8]) -> Result { (*self).write(buf) }
}
impl<T> TailWriteBytes for &mut T where T: TailWriteBytes {
fn write_tail(&mut self, buf: &[u8]) -> Result { (*self).write_tail(buf) }
}
#[cfg(feature="std")]
impl WriteBytes for Vec<u8> {
fn write(&mut self, buf: &[u8]) -> Result {
self.extend_from_slice(buf);
Ok(())
}
}
#[cfg(feature="std")]
impl TailWriteBytes for Vec<u8> {
fn write_tail(&mut self, buf: &[u8]) -> Result {
self.extend_from_slice(buf);
Ok(())
}
}
pub struct WriteToHead<'a, W>(pub &'a mut W) where W: WriteBytes;
impl<'a, W> WriteBytes for WriteToHead<'a, W>
where W: TailWriteBytes
{
fn write(&mut self, value: &[u8]) -> Result {
self.0.write(value)
}
}
impl<'a, W> TailWriteBytes for WriteToHead<'a, W>
where W: TailWriteBytes
{
fn write_tail(&mut self, value: &[u8]) -> Result {
self.0.write(value)
}
}
#[test]
fn test_debuffer() {
let mut byte_buf = [0_u8; 7];
let mut bib = DeBytesWriter::new(byte_buf.as_mut());
bib.write(b"aa").unwrap();
bib.write_tail(b"1").unwrap();
bib.write(b"bb").unwrap();
bib.write_tail(b"2").unwrap();
bib.write(b"d").unwrap();
bib.is_complete().unwrap();
assert_eq!(byte_buf.as_ref(), b"aabbd21");
let mut rb = DeBytesReader::new(byte_buf.as_mut());
assert_eq!(rb.read(3, |b| Ok(b == b"aab")).unwrap(), true);
assert_eq!(rb.read_tail(1, |b| Ok(b == b"1")).unwrap(), true);
assert_eq!(rb.read_tail(1, |b| Ok(b == b"2")).unwrap(), true);
assert_eq!(rb.read(2, |b| Ok(b == b"bd")).unwrap(), true);
rb.is_complete().unwrap();
}