use heapless::Deque;
use crate::{DecodeError, EncodeError};
pub trait EncodeBuffer {
fn push(&mut self, byte: u8) -> Result<(), EncodeError>;
fn push_slice(&mut self, slice: &[u8]) -> Result<(), EncodeError>;
fn get_encoded_len(&self) -> usize;
}
pub trait DecodeBuffer {
fn read(&mut self) -> Result<u8, DecodeError>;
fn read_slice(&mut self, buf: &mut [u8]) -> Result<(),DecodeError>;
fn get_read_len(&self) -> usize;
}
pub struct StaticBuffer<'a> {
ptr: usize,
buf: &'a mut [u8]
}
impl<'a> StaticBuffer<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
Self { ptr: 0, buf }
}
pub fn reset(&mut self) {
self.ptr = 0;
}
pub fn get_raw(&'a self) -> &'a [u8] {
&self.buf[0..self.ptr]
}
}
impl<'b> EncodeBuffer for StaticBuffer<'b> {
fn get_encoded_len(&self) -> usize {self.ptr}
fn push(&mut self, byte: u8) -> Result<(), EncodeError> {
if self.ptr >= self.buf.len() {return Err(EncodeError::Overrun);}
self.buf[self.ptr] = byte;
self.ptr+=1;
Ok(())
}
fn push_slice(&mut self, slice: &[u8]) -> Result<(), EncodeError> {
if self.ptr + slice.len() > self.buf.len() {return Err(EncodeError::Overrun)}
self.buf[self.ptr..self.ptr+slice.len()].copy_from_slice(slice);
self.ptr += slice.len();
Ok(())
}
}
impl<'b> DecodeBuffer for StaticBuffer<'b> {
fn get_read_len(&self) -> usize {self.ptr}
fn read(&mut self) -> Result<u8, DecodeError> {
if self.buf.len() <= self.ptr {return Err(DecodeError::Incomplete);}
self.ptr+=1;
Ok(self.buf[self.ptr-1])
}
fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), DecodeError> {
if slice.len() > (self.buf.len() - self.ptr) {return Err(DecodeError::Incomplete);}
self.ptr+=slice.len();
slice.copy_from_slice(&self.buf[self.ptr-slice.len()..self.ptr]);
Ok(())
}
}
pub struct RollingBuffer<'a, const SIZE: usize> {
buf: &'a mut Deque<u8, SIZE>
}
impl<'a, const SIZE: usize> RollingBuffer<'a, SIZE> {
pub fn new(buf: &'a mut Deque<u8, SIZE>) -> Self {
RollingBuffer { buf }
}
pub fn reset(&mut self) {
self.buf.clear();
}
pub fn get_raw(&'a self) -> &'a Deque<u8, SIZE> {
&self.buf
}
pub fn pop(&mut self) -> Option<u8> {
self.buf.pop_front()
}
}
impl<'a, const SIZE: usize> EncodeBuffer for RollingBuffer<'a, SIZE> {
fn get_encoded_len(&self) -> usize {self.buf.len()}
fn push(&mut self, byte: u8) -> Result<(), EncodeError> {
if self.buf.push_back(byte).is_err() {
Err(EncodeError::Overrun)
} else {
Ok(())
}
}
fn push_slice(&mut self, slice: &[u8]) -> Result<(), EncodeError> {
for item in slice {
if self.buf.push_back(*item).is_err() {
return Err(EncodeError::Overrun);
}
}
Ok(())
}
}
impl<'a, const SIZE: usize> DecodeBuffer for RollingBuffer<'a, SIZE> {
fn get_read_len(&self) -> usize {self.buf.capacity()-self.buf.len()}
fn read(&mut self) -> Result<u8, DecodeError> {
if let Some(item) = self.buf.pop_front() {
Ok(item)
} else {
Err(DecodeError::Incomplete)
}
}
fn read_slice(&mut self, buf: &mut [u8]) -> Result<(), DecodeError> {
if self.buf.len() < buf.len() {return Err(DecodeError::Incomplete);}
for i in 0..buf.len() {
buf[i] = self
.buf
.pop_front()
.expect("Since we already early returned for bad len, we should always have enough bytes to read");
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use heapless::Vec;
use super::*;
#[test]
fn static_buffer_read_singles() {
let mut slice: [u8;10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_read_len(), 0);
for i in 0..10 {
assert_eq!(buf.read().unwrap(), i);
}
buf.read().expect_err("Buf should be empty");
assert_eq!(buf.get_read_len(), 10);
}
#[test]
fn static_buffer_read_batches() {
let mut slice: [u8;10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_read_len(), 0);
for i in 0..5 {
let mut slice = [0;2];
buf.read_slice(&mut slice).unwrap();
assert_eq!(slice, [i*2, i*2 + 1]);
}
buf.read().expect_err("Buf should be empty");
assert_eq!(buf.get_read_len(), 10);
}
#[test]
fn static_buffer_read_larger_than_buffer() {
let mut slice: [u8;10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_read_len(), 0);
let mut too_large = [0;11];
buf
.read_slice(&mut too_large)
.expect_err("Should not be able to read more than the buffers size");
assert_eq!(buf.get_read_len(), 0);
}
#[test]
fn static_buffer_original_buffer_restored_on_failed_read() {
let mut slice: [u8;10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_read_len(), 0);
let mut first = [0;5];
buf
.read_slice(&mut first)
.expect("Should be able to read data within range");
assert_eq!(buf.get_read_len(), 5);
let mut second = [0;6];
buf
.read_slice(&mut second)
.expect_err("Should not be able to read more than the buffers size");
assert_eq!(buf.get_read_len(), 5);
}
#[test]
fn static_buffer_write_singles() {
let mut slice: [u8;10] = [0; 10];
{
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..10 {
buf.push(i).unwrap();
}
buf.push(69).expect_err("Buf should be full");
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(slice, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
}
#[test]
fn static_buffer_write_batches() {
let mut slice: [u8;10] = [0; 10];
{
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..5 {
buf.push_slice(&[i*2, i*2 + 1]).unwrap();
}
buf.push(69).expect_err("Buf should be full");
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(slice, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
}
#[test]
fn static_buffer_reset() {
let mut slice: [u8;10] = [0; 10];
{
let mut buf = StaticBuffer::new(&mut slice);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..10 {
buf.push(i).unwrap();
}
assert_eq!(buf.get_encoded_len(), 10);
buf.reset();
assert_eq!(buf.get_encoded_len(), 0);
for i in 10..20 {
buf.push(i).unwrap();
}
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(slice, [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
}
#[test]
fn rolling_buffer_read_singles() {
let mut inner = Deque::<u8, 10>::new();
for i in 0..10 {
inner.push_back(i as u8).expect("Pushing within size should succeed");
}
let mut buf = RollingBuffer::new(&mut inner);
assert_eq!(buf.get_read_len(), 0);
for i in 0..10 {
assert_eq!(buf.read().unwrap(), i);
}
buf.read().expect_err("Buf should be empty");
assert_eq!(buf.get_read_len(), 10);
}
#[test]
fn rolling_buffer_read_batches() {
let mut inner = Deque::<u8, 10>::new();
for i in 0..10 {
inner.push_back(i as u8).expect("Pushing within size should succeed");
}
let mut buf = RollingBuffer::new(&mut inner);
assert_eq!(buf.get_read_len(), 0);
for i in 0..5 {
let mut slice = [0;2];
buf.read_slice(&mut slice).unwrap();
assert_eq!(slice, [i*2, i*2 + 1]);
}
buf.read().expect_err("Buf should be empty");
assert_eq!(buf.get_read_len(), 10);
}
#[test]
fn rolling_buffer_read_larger_than_buffer() {
let mut inner = Deque::<u8, 10>::new();
for i in 0..10 {
inner.push_back(i as u8).expect("Pushing within size should succeed");
}
let mut buf = RollingBuffer::new(&mut inner);
assert_eq!(buf.get_read_len(), 0);
let mut too_large = [0;11];
buf
.read_slice(&mut too_large)
.expect_err("Should not be able to read more than the buffers size");
assert_eq!(buf.get_read_len(), 0);
}
#[test]
fn rolling_buffer_original_buffer_restored_on_failed_read() {
let mut inner = Deque::<u8, 10>::new();
for i in 0..10 {
inner.push_back(i as u8).expect("Pushing within size should succeed");
}
let mut buf = RollingBuffer::new(&mut inner);
assert_eq!(buf.get_read_len(), 0);
let mut first = [0;5];
buf
.read_slice(&mut first)
.expect("Should be able to read data within range");
assert_eq!(buf.get_read_len(), 5);
let mut second = [0;6];
buf
.read_slice(&mut second)
.expect_err("Should not be able to read more than the buffers size");
assert_eq!(buf.get_read_len(), 5);
}
#[test]
fn rolling_buffer_write_singles() {
let mut inner = Deque::<u8, 10>::new();
{
let mut buf = RollingBuffer::new(&mut inner);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..10 {
buf.push(i).unwrap();
}
buf.push(69).expect_err("Buf should be full");
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(inner.iter().map(|x| *x).collect::<Vec<u8, 10>>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
#[test]
fn rolling_buffer_write_batches() {
let mut inner = Deque::<u8, 10>::new();
{
let mut buf = RollingBuffer::new(&mut inner);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..5 {
buf.push_slice(&[i*2, i*2 + 1]).unwrap();
}
buf.push(69).expect_err("Buf should be full");
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(inner.iter().map(|x| *x).collect::<Vec<u8, 10>>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
#[test]
fn rolling_buffer_reset() {
let mut inner = Deque::<u8, 10>::new();
{
let mut buf = RollingBuffer::new(&mut inner);
assert_eq!(buf.get_encoded_len(), 0);
for i in 0..10 {
buf.push(i).unwrap();
}
assert_eq!(buf.get_encoded_len(), 10);
buf.reset();
assert_eq!(buf.get_encoded_len(), 0);
for i in 10..20 {
buf.push(i).unwrap();
}
assert_eq!(buf.get_encoded_len(), 10);
}
assert_eq!(inner.iter().map(|x| *x).collect::<Vec<u8, 10>>(), [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
}
}