quiche/dgram.rs
1// Copyright (C) 2020, Cloudflare, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10//
11// * Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27use crate::BufFactory;
28use crate::Error;
29use crate::Result;
30
31use std::collections::VecDeque;
32
33/// Keeps track of DATAGRAM frames.
34#[derive(Default)]
35pub struct DatagramQueue<F: BufFactory> {
36 queue: VecDeque<F::DgramBuf>,
37 queue_max_len: usize,
38 queue_bytes_size: usize,
39}
40
41impl<F: BufFactory> DatagramQueue<F> {
42 pub fn new(queue_max_len: usize) -> Self {
43 DatagramQueue {
44 queue: VecDeque::new(),
45 queue_bytes_size: 0,
46 queue_max_len,
47 }
48 }
49
50 pub fn push(&mut self, data: F::DgramBuf) -> Result<()> {
51 if self.is_full() {
52 return Err(Error::Done);
53 }
54
55 self.queue_bytes_size += data.as_ref().len();
56 self.queue.push_back(data);
57
58 Ok(())
59 }
60
61 pub fn peek_front_len(&self) -> Option<usize> {
62 self.queue.front().map(|d| d.as_ref().len())
63 }
64
65 pub fn peek_front_bytes(&self, buf: &mut [u8], len: usize) -> Result<usize> {
66 match self.queue.front() {
67 Some(d) => {
68 let len = std::cmp::min(len, d.as_ref().len());
69 if buf.len() < len {
70 return Err(Error::BufferTooShort);
71 }
72
73 buf[..len].copy_from_slice(&d.as_ref()[..len]);
74 Ok(len)
75 },
76
77 None => Err(Error::Done),
78 }
79 }
80
81 pub fn pop(&mut self) -> Option<F::DgramBuf> {
82 if let Some(d) = self.queue.pop_front() {
83 self.queue_bytes_size =
84 self.queue_bytes_size.saturating_sub(d.as_ref().len());
85 return Some(d);
86 }
87
88 None
89 }
90
91 pub fn has_pending(&self) -> bool {
92 !self.queue.is_empty()
93 }
94
95 pub fn purge<FN: Fn(&[u8]) -> bool>(&mut self, f: FN) {
96 self.queue.retain(|d| !f(d.as_ref()));
97 self.queue_bytes_size = self
98 .queue
99 .iter()
100 .fold(0, |total, d| total + d.as_ref().len());
101 }
102
103 pub fn is_full(&self) -> bool {
104 self.len() == self.queue_max_len
105 }
106
107 pub fn is_empty(&self) -> bool {
108 self.len() == 0
109 }
110
111 pub fn len(&self) -> usize {
112 self.queue.len()
113 }
114
115 pub fn byte_size(&self) -> usize {
116 self.queue_bytes_size
117 }
118}