use bitflags::bitflags;
use bytes::{Buf, BufMut, Bytes};
use std::cmp::min;
use std::fmt;
use super::PacketParseError;
use crate::protocol::TimeStamp;
use crate::{MsgNumber, SeqNumber, SocketID};
#[derive(Clone, PartialEq, Eq)]
pub struct DataPacket {
pub seq_number: SeqNumber,
pub message_loc: PacketLocation,
pub in_order_delivery: bool,
pub message_number: MsgNumber,
pub timestamp: TimeStamp,
pub dest_sockid: SocketID,
pub payload: Bytes,
}
bitflags! {
pub struct PacketLocation: u8 {
const MIDDLE = 0b0000_0000;
const FIRST = 0b1000_0000;
const LAST = 0b0100_0000;
const ONLY = Self::FIRST.bits | Self::LAST.bits;
}
}
impl DataPacket {
pub fn parse(buf: &mut impl Buf) -> Result<DataPacket, PacketParseError> {
let seq_number = SeqNumber::new_truncate(buf.get_u32());
let message_loc = PacketLocation::from_bits_truncate(buf.bytes()[0]);
let in_order_delivery = (buf.bytes()[0] & 0b0010_0000) != 0;
let message_number = MsgNumber::new_truncate(buf.get_u32());
let timestamp = TimeStamp::from_micros(buf.get_u32());
let dest_sockid = SocketID(buf.get_u32());
Ok(DataPacket {
seq_number,
message_loc,
in_order_delivery,
message_number,
timestamp,
dest_sockid,
payload: buf.to_bytes(),
})
}
pub fn serialize(&self, into: &mut impl BufMut) {
assert!(self.seq_number.as_raw() & (1 << 31) == 0);
into.put_u32(self.seq_number.as_raw());
into.put_u32(
self.message_number.as_raw()
| ((u32::from(self.message_loc.bits() | (self.in_order_delivery as u8) << 5))
<< 24),
);
into.put_u32(self.timestamp.as_micros());
into.put_u32(self.dest_sockid.0);
into.put(&self.payload[..]);
}
}
impl fmt::Debug for DataPacket {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(
f,
"{{DATA sn={} loc={:?} msgno={} ts={:.4} dst={:?} payload=[len={}, start={:?}]}}",
self.seq_number.0,
self.message_loc,
self.message_number.0,
self.timestamp.as_secs_f64(),
self.dest_sockid,
self.payload.len(),
self.payload.slice(..min(8, self.payload.len())),
)
}
}