use binary_util::{
interfaces::{Reader, Writer},
BinaryIo,
};
#[derive(Debug, Clone, BinaryIo)]
pub struct FragmentMeta {
pub(crate) size: u32,
pub(crate) id: u16,
pub(crate) index: u32,
}
impl FragmentMeta {
pub fn new(size: u32, id: u16, index: u32) -> Self {
Self { size, id, index }
}
}
use crate::rakrs_debug;
use super::reliability::Reliability;
#[derive(Debug, Clone)]
pub struct FramePacket {
pub sequence: u32,
pub frames: Vec<Frame>,
pub reliability: Reliability,
}
impl FramePacket {
pub fn new() -> Self {
Self {
sequence: 0,
frames: Vec::new(),
reliability: Reliability::ReliableOrd,
}
}
}
impl Reader<FramePacket> for FramePacket {
fn read(buf: &mut binary_util::ByteReader) -> Result<FramePacket, std::io::Error> {
let id = buf.read_u8()?;
match id {
0x80..=0x8d => {}
_ => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid Frame Packet ID",
))
}
}
let mut frames: Vec<Frame> = Vec::new();
let sequence = buf.read_u24_le()?;
loop {
let frame_pos = buf.read_type::<Frame>();
if let Ok(frame) = frame_pos {
frames.push(frame);
} else {
break;
}
}
Ok(FramePacket {
sequence,
frames,
reliability: Reliability::ReliableOrd,
})
}
}
impl Writer for FramePacket {
fn write(&self, buf: &mut binary_util::ByteWriter) -> Result<(), std::io::Error> {
buf.write_u8(0x84)?;
buf.write_u24_le(self.sequence)?;
for frame in &self.frames {
buf.write(frame.write_to_bytes()?.as_slice())?;
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct Frame {
pub flags: u8,
pub size: u16,
pub reliable_index: Option<u32>,
pub sequence_index: Option<u32>,
pub order_index: Option<u32>,
pub order_channel: Option<u8>,
pub fragment_meta: Option<FragmentMeta>,
pub reliability: Reliability,
pub body: Vec<u8>,
}
impl Frame {
pub fn init() -> Self {
Self {
flags: 0,
size: 0,
reliable_index: None,
sequence_index: None,
order_index: None,
order_channel: None,
fragment_meta: None,
reliability: Reliability::Unreliable,
body: Vec::new(),
}
}
pub fn new(reliability: Reliability, body: Option<&[u8]>) -> Self {
Self {
flags: 0,
size: if let Some(b) = body {
b.len() as u16
} else {
0
},
reliable_index: None,
sequence_index: None,
order_index: None,
order_channel: None,
fragment_meta: None,
reliability,
body: body.unwrap_or(&[]).to_vec(),
}
}
pub fn is_fragmented(&self) -> bool {
self.fragment_meta.is_some()
}
pub fn is_sequenced(&self) -> bool {
self.reliability.is_sequenced()
}
pub fn with_meta(mut self, meta: FragmentMeta) -> Self {
self.fragment_meta = Some(meta);
self
}
}
impl Reader<Frame> for Frame {
fn read(buf: &mut binary_util::ByteReader) -> Result<Frame, std::io::Error> {
let mut frame = Frame::init();
frame.flags = buf.read_u8()?;
frame.reliability = Reliability::from_flags(frame.flags);
let size = buf.read_u16();
if let Ok(size) = size {
frame.size = size / 8;
}
if frame.reliability.is_reliable() {
frame.reliable_index = Some(buf.read_u24_le()?);
}
if frame.reliability.is_sequenced() {
frame.sequence_index = Some(buf.read_u24_le()?);
}
if frame.reliability.is_ordered() {
frame.order_index = Some(buf.read_u24_le()?);
frame.order_channel = Some(buf.read_u8()?);
}
if (frame.flags & 0x10) > 0 {
frame.fragment_meta = Some(FragmentMeta::read(buf)?);
}
let mut body = vec![0; frame.size as usize];
match buf.read(&mut body) {
Ok(_) => {
frame.body = body.to_vec();
}
Err(e) => {
rakrs_debug!(true, "[DECODE_ERR] Error reading frame body: {:?}", e);
}
}
Ok(frame)
}
}
impl Writer for Frame {
fn write(&self, buf: &mut binary_util::ByteWriter) -> Result<(), std::io::Error> {
let mut flags = self.reliability.to_flags();
if self.fragment_meta.is_some() {
flags |= 0x10;
}
buf.write_u8(flags)?;
buf.write_u16(self.size * 8)?;
if self.reliability.is_reliable() {
buf.write_u24_le(self.reliable_index.unwrap_or(0))?;
}
if self.reliability.is_sequenced() {
buf.write_u24_le(self.sequence_index.unwrap_or(0))?;
}
if self.reliability.is_ordered() {
buf.write_u24_le(self.order_index.unwrap_or(0))?;
buf.write_u8(self.order_channel.unwrap_or(0))?;
}
if self.fragment_meta.is_some() {
buf.write(
self.fragment_meta
.as_ref()
.unwrap()
.write_to_bytes()?
.as_slice(),
)?;
}
buf.write(&self.body)?;
Ok(())
}
}