use bytes::{BufMut, BytesMut};
use super::Error;
pub struct ChannelData<'a> {
bytes: &'a [u8],
number: u16,
}
impl<'a> ChannelData<'a> {
pub fn new(number: u16, bytes: &'a [u8]) -> Self {
Self { number, bytes }
}
pub fn number(&self) -> u16 {
self.number
}
pub fn bytes(&self) -> &'a [u8] {
self.bytes
}
pub fn message_size(bytes: &[u8], is_tcp: bool) -> Result<usize, Error> {
if bytes.len() < 4 {
return Err(Error::InvalidInput);
}
if !(1..3).contains(&(bytes[0] >> 6)) {
return Err(Error::InvalidInput);
}
let mut size = (u16::from_be_bytes(bytes[2..4].try_into()?) + 4) as usize;
if is_tcp && !size.is_multiple_of(4) {
size += 4 - (size % 4);
}
Ok(size)
}
pub fn encode(self, bytes: &mut BytesMut) {
bytes.clear();
bytes.put_u16(self.number);
bytes.put_u16(self.bytes.len() as u16);
bytes.extend_from_slice(self.bytes);
}
pub fn decode(bytes: &'a [u8]) -> Result<Self, Error> {
if bytes.len() < 4 {
return Err(Error::InvalidInput);
}
let number = u16::from_be_bytes(bytes[..2].try_into()?);
if !(0x4000..0xFFFF).contains(&number) {
return Err(Error::InvalidInput);
}
let size = u16::from_be_bytes(bytes[2..4].try_into()?) as usize;
if size > bytes.len() - 4 {
return Err(Error::InvalidInput);
}
Ok(Self {
bytes: &bytes[4..],
number,
})
}
}