chiark / gitweb /
rename [Frame]QueueBuf
[hippotat.git] / src / queue.rs
1 // Copyright 2021 Ian Jackson and contributors to Hippotat
2 // SPDX-License-Identifier: GPL-3.0-or-later
3 // There is NO WARRANTY.
4
5 use crate::prelude::*;
6
7 #[derive(Default,Clone)]
8 pub struct QueueBuf<E> {
9   content: usize,
10   eaten1: usize, // 0 <= eaten1 < queue.front()...len()
11   queue: VecDeque<E>,
12 }
13
14 #[derive(Default,Debug,Clone)]
15 pub struct FrameQueueBuf {
16   queue: QueueBuf<Cervine<'static, Box<[u8]>, [u8]>>,
17 }
18
19 impl<E> Debug for QueueBuf<E> where E: AsRef<[u8]> {
20   #[throws(fmt::Error)]
21   fn fmt(&self, f: &mut fmt::Formatter) {
22     write!(f, "Queue{{content={},eaten1={},queue=[",
23            self.content, self.eaten1)?;
24     for q in &self.queue { write!(f, "{},", q.as_ref().len())?; }
25     write!(f, "]}}")?;
26   }
27 }
28
29 impl<E> QueueBuf<E> where E: AsRef<[u8]> {
30   pub fn push<B: Into<E>>(&mut self, b: B) {
31     self.push_(b.into());
32   }
33   pub fn push_(&mut self, b: E) {
34     let l = b.as_ref().len();
35     self.queue.push_back(b);
36     self.content += l;
37   }
38   pub fn is_empty(&self) -> bool { self.content == 0 }
39 }
40
41 impl FrameQueueBuf {
42   pub fn push<B: Into<Box<[u8]>>>(&mut self, b: B) {
43     self.push_(b.into());
44   }
45   pub fn push_(&mut self, b: Box<[u8]>) {
46     self.queue.push_(Cervine::Owned(b));
47     self.queue.push_(Cervine::Borrowed(&SLIP_END_SLICE));
48   }
49   pub fn is_empty(&self) -> bool { self.queue.is_empty() }
50 }
51
52 impl<E> Extend<E> for FrameQueueBuf where E: Into<Box<[u8]>> {
53   fn extend<I>(&mut self, it: I)
54   where I: IntoIterator<Item=E>
55   {
56     for b in it { self.push(b) }
57   }
58 }
59
60 impl<E> hyper::body::Buf for QueueBuf<E> where E: AsRef<[u8]> {
61   fn remaining(&self) -> usize { self.content }
62   fn chunk(&self) -> &[u8] {
63     let front = if let Some(f) = self.queue.front() { f } else { return &[] };
64     &front.as_ref()[ self.eaten1.. ]
65   }
66   fn advance(&mut self, cnt: usize) {
67     self.content -= cnt;
68     self.eaten1 += cnt;
69     loop {
70       if self.eaten1 == 0 { break }
71       let front = self.queue.front().unwrap();
72       if self.eaten1 < front.as_ref().len() { break; }
73       self.eaten1 -= front.as_ref().len();
74       self.queue.pop_front().unwrap();
75     }
76   }
77 }
78
79 impl hyper::body::Buf for FrameQueueBuf {
80   fn remaining(&self) -> usize { self.queue.remaining() }
81   fn chunk(&self) -> &[u8] { self.queue.chunk() }
82   fn advance(&mut self, cnt: usize) { self.queue.advance(cnt) }
83 }