use std::collections::VecDeque;
use std::io::{ErrorKind, Read, Write};
pub type PacketData = Vec<u8>;
pub trait Packet {
type PacketType;
fn get_bytes(&self) -> Result<Vec<u8>, std::io::Error>;
fn write_to<T: Write>(&self, out: &mut T) -> Result<(), std::io::Error> {
out.write_all(self.get_bytes()?.as_slice())
}
fn get_type(&self) -> Self::PacketType;
}
pub trait PacketBuilder<P> {
type Error;
fn build_from<T: Read>(&self, input: &mut T) -> Result<P, Self::Error>;
}
pub trait Packetization<T: Read> {
fn read_next_packet(&mut self, source: &mut T) -> Result<PacketData, std::io::Error>;
}
pub trait PacketTransport {
type Error;
fn poll_next_packet(&mut self) -> Result<PacketData, Self::Error>;
fn start(&mut self) -> Result<(), Self::Error>;
fn stop(&mut self) -> Result<(), Self::Error>;
}
pub struct Packetizer<'a, R: Read, P: Packetization<R>> {
reader: &'a mut R,
chunker: &'a mut P,
}
impl<'a, R, P> PacketTransport for Packetizer<'a, R, P>
where
R: Read,
P: Packetization<R>,
{
type Error = std::io::Error;
fn poll_next_packet(&mut self) -> Result<PacketData, Self::Error> {
self.chunker.read_next_packet(self.reader)
}
fn start(&mut self) -> Result<(), Self::Error> {
Ok(())
}
fn stop(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
#[derive(Default)]
pub struct DelimitedPacketizer {
pub delimiter: Vec<u8>,
pub include_delimiter: bool,
pub max_buffer_size: usize,
buffer: Vec<u8>,
}
impl<T: Read> Packetization<T> for DelimitedPacketizer {
fn read_next_packet(&mut self, source: &mut T) -> Result<PacketData, std::io::Error> {
if self.delimiter.is_empty() {
return Err(std::io::Error::new(
ErrorKind::InvalidData,
"Delimiter is empty",
));
}
self.buffer.clear();
let del_len = self.delimiter.len();
let mut ringbuf: VecDeque<u8> = VecDeque::with_capacity(del_len);
source.read_exact(ringbuf.as_mut_slices().0)?;
let mut onebuf: [u8; 1] = [0; 1];
loop {
if ringbuf.eq(&self.delimiter) {
let mut outbuf = self.buffer.clone();
if self.include_delimiter {
outbuf.extend(&self.delimiter);
}
return Ok(outbuf);
}
if self.buffer.len() == self.max_buffer_size {
return Err(std::io::Error::new(
ErrorKind::OutOfMemory,
"Packet exceeded max buffer size",
));
}
if source.read(&mut onebuf)? == 0 {
return Ok(self.buffer.clone());
}
ringbuf.pop_front();
ringbuf.push_back(onebuf[0]);
}
}
}