use bitvec::vec::BitVec;
use crate::protocol::{
errors::{ Error, ErrorKind },
managers::event::EventEncoder,
versions::Version,
};
use super::prelude::BitReversible;
#[derive(Debug)]
pub struct FrameEncoder<R: BitReversible> {
encoder: BitEncoder<R>,
version: Version,
}
impl<R: BitReversible> FrameEncoder<R> {
pub fn new(version: u8) -> Result<Self, Error> {
Ok(Self {
encoder: BitEncoder::new(),
version: Version::from_u8(version)?,
})
}
pub fn encode(
&mut self,
mut frame: Box<dyn EventEncoder<R>>
) -> Result<Vec<u8>, Error> {
self.encoder.add_data(self.version.to_u8() as u32, 8)?;
frame.encode()?;
let data_size = frame.get_encoder().frame.len();
if data_size > 1 << 32 {
return Err(Error {
code: 0b1000,
message: "Maximum of 2^32 bits allowed".to_string(),
kind: ErrorKind::SizeConstraintViolation,
});
}
if data_size < 8 {
return Err(Error {
code: 0b1001,
message: "Minimum of 8 bits allowed".to_string(),
kind: ErrorKind::SizeConstraintViolation,
});
}
self.encoder.add_data(frame.get_event() as u32, 16)?;
self.encoder.add_data(data_size as u32, 32)?;
self.encoder.append_data_from(frame.get_encoder());
while self.encoder.frame.len() % 8 != 0 {
self.encoder.add_data(0, 1)?;
}
if cfg!(feature = "debug") {
println!(
"[\x1b[38;5;227mSHDP\x1b[0m] Sent: In-size {}b / {}B, out-size {}b / {}B",
data_size,
(data_size + 8 - (data_size % 8)) / 8,
self.encoder.frame.len(),
self.encoder.frame.len() / 8
);
}
Ok(self.encoder.encode())
}
}
#[derive(Clone, Debug)]
pub struct BitEncoder<R: BitReversible> {
pub frame: BitVec<u8, R>,
}
impl<R: BitReversible> BitEncoder<R> {
pub fn new() -> Self {
Self {
frame: BitVec::<u8, R>::new(),
}
}
#[cfg(feature = "debug")]
#[allow(dead_code)]
pub fn print_frame(&self) {
println!("Frame size: {}", self.frame.len());
for bit in &self.frame {
print!("{}", if *bit { 1 } else { 0 });
}
println!();
}
pub fn add_data(&mut self, data: u32, n: u8) -> Result<&mut Self, Error> {
if self.frame.len() + (n as usize) > 1 << 32 {
return Err(Error {
code: 0b1000,
message: "Maximum of 2^32 bits allowed".to_string(),
kind: ErrorKind::SizeConstraintViolation,
});
}
if n > 32 {
return Err(Error {
code: 0b1000,
message: "Data of more than 32 bits long are not allowed".to_string(),
kind: ErrorKind::SizeConstraintViolation,
});
}
for i in (0..n).rev() {
let bit = ((data >> i) & 1) == 1;
self.frame.push(bit);
}
Ok(self)
}
pub fn add_bytes(&mut self, bytes: &[u8]) -> Result<&mut Self, Error> {
for &byte in bytes {
self.add_data(byte as u32, 8)?;
}
Ok(self)
}
pub fn add_bitvec(
&mut self,
bitvec: &BitVec<u8, R>
) -> Result<&mut Self, Error> {
for bit in bitvec {
self.frame.push(*bit);
}
Ok(self)
}
pub fn append_data_from(&mut self, encoder: &BitEncoder<R>) {
self.frame.append(&mut encoder.frame.clone());
}
fn reverse_bits_in_bytes(&self, input: &[u8]) -> Vec<u8> {
input
.iter()
.map(|&byte| byte.reverse_bits())
.collect()
}
pub fn encode(&self) -> Vec<u8> {
let vec = self.frame.clone().into_vec();
self.reverse_bits_in_bytes(&vec)
}
}