use crate::net::constants::STANDARD_HEADER_SIZE;
use crate::packet::header::{
AckedPacketHeader, ArrangingHeader, FragmentHeader, HeaderReader, StandardHeader,
};
use crate::{ErrorKind, Result};
use std::io::Cursor;
pub struct PacketReader<'s> {
buffer: &'s [u8],
cursor: Cursor<&'s [u8]>,
}
impl<'s> PacketReader<'s> {
pub fn new(buffer: &'s [u8]) -> PacketReader<'s> {
PacketReader {
buffer,
cursor: Cursor::new(buffer),
}
}
pub fn read_standard_header(&mut self) -> Result<StandardHeader> {
self.cursor.set_position(0);
if self.can_read(StandardHeader::size()) {
StandardHeader::read(&mut self.cursor)
} else {
Err(ErrorKind::CouldNotReadHeader(String::from("standard")))
}
}
pub fn read_arranging_header(&mut self, start_offset: u16) -> Result<ArrangingHeader> {
self.cursor.set_position(u64::from(start_offset));
if self.can_read(ArrangingHeader::size()) {
ArrangingHeader::read(&mut self.cursor)
} else {
Err(ErrorKind::CouldNotReadHeader(String::from("arranging")))
}
}
pub fn read_acknowledge_header(&mut self) -> Result<AckedPacketHeader> {
self.cursor.set_position(u64::from(STANDARD_HEADER_SIZE));
if self.can_read(AckedPacketHeader::size()) {
AckedPacketHeader::read(&mut self.cursor)
} else {
Err(ErrorKind::CouldNotReadHeader(String::from(
"acknowledgment",
)))
}
}
pub fn read_fragment(&mut self) -> Result<(FragmentHeader, Option<AckedPacketHeader>)> {
if self.can_read(FragmentHeader::size()) {
let fragment_header = FragmentHeader::read(&mut self.cursor)?;
let acked_header = if fragment_header.id() == 0 {
Some(AckedPacketHeader::read(&mut self.cursor)?)
} else {
None
};
Ok((fragment_header, acked_header))
} else {
Err(ErrorKind::CouldNotReadHeader(String::from("fragment")))
}
}
pub fn read_payload(&self) -> Box<[u8]> {
self.buffer[self.cursor.position() as usize..self.buffer.len()]
.to_vec()
.into_boxed_slice()
}
fn can_read(&self, length: u8) -> bool {
(self.buffer.len() - self.cursor.position() as usize) >= length as usize
}
}
#[cfg(test)]
mod tests {
use crate::packet::header::{AckedPacketHeader, HeaderReader, StandardHeader};
use crate::packet::{DeliveryGuarantee, OrderingGuarantee, PacketReader, PacketType};
#[test]
fn can_read_bytes() {
let buffer = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let reader = PacketReader::new(buffer.as_slice());
assert_eq!(reader.can_read(buffer.len() as u8), true);
assert_eq!(reader.can_read((buffer.len() + 1) as u8), false);
}
#[test]
fn assure_read_standard_header() {
let reliable_ordered_payload: Vec<u8> = vec![vec![0, 1, 0, 1, 2]].concat();
let mut reader = PacketReader::new(reliable_ordered_payload.as_slice());
let standard_header = reader.read_standard_header().unwrap();
assert_eq!(standard_header.protocol_version(), 1);
assert_eq!(standard_header.packet_type(), PacketType::Packet);
assert_eq!(
standard_header.delivery_guarantee(),
DeliveryGuarantee::Reliable
);
assert_eq!(
standard_header.ordering_guarantee(),
OrderingGuarantee::Ordered(None)
);
}
#[test]
fn assure_read_acknowledgment_header() {
let reliable_ordered_payload: Vec<u8> =
vec![vec![0, 1, 0, 1, 2], vec![0, 1, 0, 2, 0, 0, 0, 3]].concat();
let mut reader = PacketReader::new(reliable_ordered_payload.as_slice());
let acked_header = reader.read_acknowledge_header().unwrap();
assert_eq!(acked_header.sequence(), 1);
assert_eq!(acked_header.ack_seq(), 2);
assert_eq!(acked_header.ack_field(), 3);
}
#[test]
fn assure_read_fragment_header() {
let reliable_ordered_payload: Vec<u8> = vec![
vec![0, 1, 0, 1, 2],
vec![0, 1, 0, 3],
vec![0, 1, 0, 2, 0, 0, 0, 3],
]
.concat();
let mut reader = PacketReader::new(reliable_ordered_payload.as_slice());
let standard_header = reader.read_standard_header().unwrap();
let (fragment_header, acked_header) = reader.read_fragment().unwrap();
assert_eq!(standard_header.protocol_version(), 1);
assert_eq!(standard_header.packet_type(), PacketType::Packet);
assert_eq!(
standard_header.delivery_guarantee(),
DeliveryGuarantee::Reliable
);
assert_eq!(
standard_header.ordering_guarantee(),
OrderingGuarantee::Ordered(None)
);
assert_eq!(acked_header.unwrap().sequence(), 1);
assert_eq!(acked_header.unwrap().ack_seq(), 2);
assert_eq!(acked_header.unwrap().ack_field(), 3);
assert_eq!(fragment_header.sequence(), 1);
assert_eq!(fragment_header.id(), 0);
assert_eq!(fragment_header.fragment_count(), 3);
}
#[test]
fn assure_read_unreliable_sequenced_header() {
let reliable_ordered_payload: Vec<u8> = vec![vec![0, 1, 0, 1, 2], vec![0, 1, 2]].concat();
let mut reader = PacketReader::new(reliable_ordered_payload.as_slice());
let arranging_header = reader
.read_arranging_header(StandardHeader::size() as u16)
.unwrap();
assert_eq!(arranging_header.arranging_id(), 1);
assert_eq!(arranging_header.stream_id(), 2);
}
#[test]
fn assure_read_reliable_ordered_header() {
let reliable_ordered_payload: Vec<u8> = vec![
vec![0, 1, 0, 1, 2],
vec![0, 1, 0, 2, 0, 0, 0, 3],
vec![0, 1, 2],
]
.concat();
let mut reader = PacketReader::new(reliable_ordered_payload.as_slice());
let standard_header = reader.read_standard_header().unwrap();
let acked_header = reader.read_acknowledge_header().unwrap();
let arranging_header = reader
.read_arranging_header((StandardHeader::size() + AckedPacketHeader::size()) as u16)
.unwrap();
assert_eq!(standard_header.protocol_version(), 1);
assert_eq!(standard_header.packet_type(), PacketType::Packet);
assert_eq!(
standard_header.delivery_guarantee(),
DeliveryGuarantee::Reliable
);
assert_eq!(
standard_header.ordering_guarantee(),
OrderingGuarantee::Ordered(None)
);
assert_eq!(acked_header.sequence(), 1);
assert_eq!(acked_header.ack_seq(), 2);
assert_eq!(acked_header.ack_field(), 3);
assert_eq!(arranging_header.arranging_id(), 1);
assert_eq!(arranging_header.stream_id(), 2);
}
#[test]
fn assure_read_reliable_unordered_header() {
let reliable_ordered_payload: Vec<u8> =
vec![vec![0, 1, 0, 1, 2], vec![0, 1, 0, 2, 0, 0, 0, 3]].concat();
let mut reader = PacketReader::new(reliable_ordered_payload.as_slice());
let standard_header = reader.read_standard_header().unwrap();
let acked_header = reader.read_acknowledge_header().unwrap();
assert_eq!(standard_header.protocol_version(), 1);
assert_eq!(standard_header.packet_type(), PacketType::Packet);
assert_eq!(
standard_header.delivery_guarantee(),
DeliveryGuarantee::Reliable
);
assert_eq!(
standard_header.ordering_guarantee(),
OrderingGuarantee::Ordered(None)
);
assert_eq!(acked_header.sequence(), 1);
assert_eq!(acked_header.ack_seq(), 2);
assert_eq!(acked_header.ack_field(), 3);
}
#[test]
fn expect_read_error() {
let reliable_ordered_payload: Vec<u8> = vec![vec![0, 1, 0, 1]].concat();
let mut reader = PacketReader::new(reliable_ordered_payload.as_slice());
assert!(reader.read_standard_header().is_err());
}
}