use core::borrow::{Borrow, BorrowMut};
use core::convert::TryFrom;
use crate::alloc::vec::Vec;
use crate::wire::tcp::SeqNumber;
use crate::storage::assembler::{Assembler, Contig};
use super::{AvailableBytes, ReceivedSegment, RecvBuf, SendBuf};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Empty {
_private: (),
}
#[derive(Default)]
pub struct Sink {
highest: Option<SeqNumber>,
}
pub struct SendFrom<B> {
data: B,
consumed: usize,
sent: usize,
fin: bool,
at: Option<SeqNumber>,
}
pub struct RecvInto<B> {
buffer: B,
complete: Option<SeqNumber>,
mark: usize,
asm: Assembler<[Contig; 4]>,
}
impl<Buffer: Borrow<[u8]>> SendFrom<Buffer> {
pub fn new(data: Buffer) -> Self {
SendFrom {
data,
consumed: 0,
sent: 0,
fin: false,
at: None,
}
}
pub fn once(data: Buffer) -> Self {
SendFrom {
data,
consumed: 0,
sent: 0,
fin: true,
at: None,
}
}
pub fn get_ref(&self) -> &Buffer {
&self.data
}
pub fn get_mut(&mut self) -> &mut Buffer {
&mut self.data
}
pub fn fin(&mut self) {
self.fin = true;
}
pub fn sent_bytes(&self) -> usize {
self.consumed
}
pub fn completed_bytes(&self) -> usize {
self.consumed
}
pub fn retransmit_bytes(&self) -> usize {
self.sent - self.consumed
}
pub fn sending(&self) -> &[u8] {
&self.data.borrow()[self.consumed..self.sent]
}
pub fn unsent(&self) -> &[u8] {
&self.data.borrow()[self.sent..]
}
pub fn unsent_mut(&mut self) -> &mut [u8]
where Buffer: BorrowMut<[u8]>
{
&mut self.data.borrow_mut()[self.sent..]
}
pub fn bump_external(&mut self, amount: usize) {
self.consumed = self.consumed.checked_sub(amount)
.expect("Tried bumping send buffer into sent region");
self.sent -= amount;
}
pub fn bump_with_write(&mut self, data: &[u8]) -> usize
where Buffer: BorrowMut<[u8]>
{
let front_space = self.completed_bytes();
let amount = front_space.min(data.len());
let buffer = self.get_mut().borrow_mut();
buffer.copy_within(front_space.., front_space - amount);
let new_space = buffer.len() - amount;
buffer[new_space..].copy_from_slice(&data[..amount]);
self.bump_external(amount);
amount
}
}
impl SendFrom<Vec<u8>> {
pub fn bump_to(&mut self, at: usize) {
assert!(at <= self.consumed, "Tried removing unsent data.");
self.bump_external(at);
self.data.drain(..at).for_each(drop);
}
pub fn bump(&mut self) {
self.bump_to(self.consumed)
}
}
impl<Buffer: BorrowMut<[u8]>> RecvInto<Buffer> {
pub fn new(buffer: Buffer) -> Self {
RecvInto {
buffer,
complete: None,
mark: 0,
asm: Assembler::new([Contig::default(); 4]),
}
}
pub fn get_ref(&self) -> &Buffer {
&self.buffer
}
pub fn get_mut(&mut self) -> &mut Buffer {
&mut self.buffer
}
pub fn received(&self) -> &[u8] {
&self.buffer.borrow()[..self.mark]
}
pub fn bump_external(&mut self, amount: usize) {
self.mark = self.mark.checked_sub(amount)
.expect("Tried bumping receive buffer into unreceived region");
}
pub fn bump_with_read(&mut self, buffer: &mut [u8])
-> usize
{
let to_write = self.mark.min(buffer.len());
let data = &self.buffer.borrow()[..to_write];
buffer[..to_write].copy_from_slice(data);
self.bump_external(to_write);
to_write
}
}
impl RecvInto<Vec<u8>> {
pub fn bump_to(&mut self, at: usize) {
self.bump_external(at);
self.buffer.drain(..at).for_each(drop);
}
pub fn bump(&mut self) {
self.bump_to(self.mark)
}
}
impl SendBuf for Empty {
fn available(&self) -> AvailableBytes {
AvailableBytes {
total: 0,
fin: true,
}
}
fn fill(&mut self, buf: &mut [u8], _: SeqNumber) {
assert_eq!(buf.len(), 0, "Called empty send buffer to fill data");
}
fn ack(&mut self, _: SeqNumber) {
}
}
impl RecvBuf for Sink {
fn receive(&mut self, _: &[u8], segment: ReceivedSegment) {
let highest = *self.highest.get_or_insert(segment.begin);
if segment.contains_in_window(highest) {
self.highest = Some(segment.sequence_end());
}
}
fn ack(&mut self) -> SeqNumber {
self.highest.expect("Must not be called before any isn indication")
}
fn window(&self) -> usize {
usize::max_value()
}
}
impl<B: Borrow<[u8]>> SendBuf for SendFrom<B> {
fn available(&self) -> AvailableBytes {
AvailableBytes {
total: self.data.borrow().len() - self.consumed,
fin: self.fin,
}
}
fn fill(&mut self, buf: &mut [u8], begin: SeqNumber) {
let consumed_at = self.at.expect("Fill must not be called before isn indication");
let data = &self.data.borrow()[self.consumed..];
let start = begin - consumed_at;
let end = start + buf.len();
self.sent = self.sent.max(self.consumed + end);
buf.copy_from_slice(&data[start..end])
}
fn ack(&mut self, ack: SeqNumber) {
let previous = *self.at.get_or_insert(ack);
self.consumed += ack - previous;
self.at = Some(ack);
}
}
impl<B: BorrowMut<[u8]>> RecvBuf for RecvInto<B> {
fn receive(&mut self, mut data: &[u8], segment: ReceivedSegment) {
let begin = self.complete.get_or_insert(segment.begin);
let buffer = &mut self.buffer.borrow_mut()[self.mark..];
let relative = if &segment.begin > begin {
(segment.begin - *begin) as u32
} else {
let pre = *begin - segment.begin;
data = &data[pre..];
0u32
};
let available = u32::try_from(buffer.len())
.ok().unwrap_or_else(u32::max_value);
let in_length = u32::try_from(data.len()).unwrap();
let length = available.min(in_length);
let new_data = match self.asm.bounded_add(relative, length, available) {
Err(_) => return,
Ok(new) => new as usize,
};
buffer[relative as usize..(relative+length) as usize]
.copy_from_slice(&data[..length as usize]);
self.mark += new_data;
*begin += usize::from(segment.syn);
*begin += new_data;
*begin += usize::from(new_data == segment.data_len && segment.fin);
}
fn ack(&mut self) -> SeqNumber {
self.complete.expect("Must not be called before any isn indication")
}
fn window(&self) -> usize {
self.buffer.borrow()[self.mark..].len()
}
}