chiark / gitweb /
provide queue
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 3 Aug 2021 18:31:45 +0000 (19:31 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 3 Aug 2021 18:31:45 +0000 (19:31 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/lib.rs
src/queue.rs [new file with mode: 0644]
src/rope.rs [new file with mode: 0644]

index 7a3c2ca262a99b6471396471a33d584f9afc883a..1dcc96818812b900fffc7d87e0715c340b8d4628 100644 (file)
@@ -16,5 +16,6 @@ pub mod prelude;
 pub mod config;
 pub mod slip;
 pub mod reporter;
+pub mod queue;
 pub mod types;
 pub mod utils;
diff --git a/src/queue.rs b/src/queue.rs
new file mode 100644 (file)
index 0000000..41691af
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2021 Ian Jackson and contributors to Hippotat
+// SPDX-License-Identifier: GPL-3.0-or-later
+// There is NO WARRANTY.
+
+use crate::prelude::*;
+
+#[derive(Default,Clone)]
+pub struct Queue {
+  content: usize,
+  eaten1: usize, // 0 <= eaten1 < queue.front()...len()
+  queue: VecDeque<Box<[u8]>>,
+}
+
+impl Queue {
+  pub fn push<B: Into<Box<[u8]>>>(&mut self, b: B) {
+    self.push_(b.into());
+  }
+  pub fn push_(&mut self, b: Box<[u8]>) {
+    let l = b.len();
+    self.push(b);
+    self.content += l;
+  }
+  pub fn is_empty(&self) -> bool { self.content == 0 }
+}
+
+impl hyper::body::Buf for Queue {
+  fn remaining(&self) -> usize { self.content }
+  fn chunk(&self) -> &[u8] {
+    let front = if let Some(f) = self.queue.front() { f } else { return &[] };
+    &front[ self.eaten1.. ]
+  }
+  fn advance(&mut self, cnt: usize) {
+    self.content -= cnt;
+    self.eaten1 += cnt;
+    loop {
+      if self.eaten1 == 0 { break }
+      let front = self.queue.front().unwrap();
+      if self.eaten1 < front.len() { break; }
+      self.eaten1 -= front.len();
+      self.queue.pop_front().unwrap();
+    }
+  }
+}
diff --git a/src/rope.rs b/src/rope.rs
new file mode 100644 (file)
index 0000000..fd400fe
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2021 Ian Jackson and contributors to Hippotat
+// SPDX-License-Identifier: GPL-3.0-or-later
+// There is NO WARRANTY.
+
+use crate::prelude::*;
+
+#[derive(Default,Clone)]
+pub struct Queue {
+  content: usize,
+  eaten1: usize, // 0 <= eaten1 < queue.front()...len()
+  queue: VecDeque<Box<[u8]>>,
+}
+
+pub impl Queue {
+  pub fn push<B: Into<Box<[u8]>>>(&mut self, b: B) {
+    self.push_(b.into());
+  }
+  pub fn push_(&mut self, b: Box<[u8]>) {
+    let l = b.len();
+    self.push(b);
+    b.content += b;
+  }
+  pub fn is_empty(&self) { self.content == 0 }
+}
+
+impl bytes::Buf for Queue {
+  fn remaining(&self) -> usize { self.content }
+  fn chunk(&self) -> usize {
+    let front = if let(f) = self.queue.front() { f } else { return &[] };
+    front[ self.eaten1.. ]
+  }
+  fn advance(&self, cnt: usize) {
+    eaten1 += cnt;
+    loop {
+      if eaten1 == 0 { break }
+      let front = self.queue.front().unwrap();
+      if eaten1 < front.len() { break; }
+      eaten1 -= front.len();
+      self.queue.pop_front().unwrap();
+    }
+  }
+}