use super::header::Header;
use super::packet_types::PacketType;
use crate::errors::ParseError;
use byteorder::ReadBytesExt;
use std::any::Any;
use std::io::Cursor;
#[derive(Debug, Clone)]
pub struct Packet {
pub header: Header,
pub body: PacketType,
}
pub trait PacketData: std::fmt::Debug + Send + Sync + 'static + Any {
fn from_bytes(bytes: &[u8]) -> Result<Self, ParseError>
where
Self: Sized;
fn to_bytes(&self) -> Vec<u8>;
}
impl Packet {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ParseError> {
let header = Header::try_from_bytes(bytes)?;
let body = if header.size.unwrap_or(0) < bytes.len() {
&bytes[header.size.unwrap_or(0)..]
} else {
&[]
};
let body_bytes = if header.zerocoded {
zero_decode(body)
} else {
body.to_vec() };
let body = PacketType::from_id(header.id, header.frequency, body_bytes.as_slice())?;
Ok(Self { header, body })
}
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend(self.header.to_bytes());
bytes.extend(self.body.to_bytes());
if self.header.zerocoded {
let mut zeroed = zero_encode(&bytes[6..]);
let mut final_bytes = Vec::with_capacity(6 + zeroed.len());
final_bytes.extend_from_slice(&bytes[0..6]);
final_bytes.append(&mut zeroed);
return final_bytes;
}
bytes
}
}
fn zero_decode(bytes: &[u8]) -> Vec<u8> {
let mut cursor = Cursor::new(bytes);
let mut dest = Vec::new();
while let Ok(byte) = cursor.read_u8() {
if byte == 0x00 {
if let Ok(count) = cursor.read_u8() {
dest.extend(std::iter::repeat_n(0x00, count as usize));
} else {
dest.push(0x00);
}
} else {
dest.push(byte);
}
}
dest
}
fn zero_encode(src: &[u8]) -> Vec<u8> {
let mut dest = Vec::with_capacity(src.len());
let mut zerocount: u8 = 0;
let mut i = 0;
while i < src.len() {
if src[i] == 0x00 {
zerocount = zerocount.wrapping_add(1);
if zerocount == 0 {
dest.push(0x00);
dest.push(0xff);
zerocount = 1; }
} else {
if zerocount != 0 {
dest.push(0x00);
dest.push(zerocount);
zerocount = 0;
}
dest.push(src[i]);
}
i += 1;
}
if zerocount != 0 {
dest.push(0x00);
dest.push(zerocount);
}
dest
}