Skip to main content

layer_crypto/
deque_buffer.rs

1//! A deque-like growable buffer that supports efficient prepend.
2
3use std::ops::{Index, IndexMut};
4use std::slice::SliceIndex;
5
6/// Growable byte buffer that supports efficient front-extension.
7#[derive(Clone, Debug)]
8pub struct DequeBuffer {
9    buf: Vec<u8>,
10    head: usize,
11    default_head: usize,
12}
13
14impl DequeBuffer {
15    /// Create with reserved space for `back` bytes in the back and `front` in the front.
16    pub fn with_capacity(back: usize, front: usize) -> Self {
17        let mut buf = Vec::with_capacity(front + back);
18        buf.resize(front, 0);
19        Self { buf, head: front, default_head: front }
20    }
21
22    /// Reset the buffer to empty (but keep allocation).
23    pub fn clear(&mut self) {
24        self.buf.truncate(self.default_head);
25        self.buf[..self.head].fill(0);
26        self.head = self.default_head;
27    }
28
29    /// Prepend `slice` to the front.
30    pub fn extend_front(&mut self, slice: &[u8]) {
31        if self.head >= slice.len() {
32            self.head -= slice.len();
33        } else {
34            let shift = slice.len() - self.head;
35            self.buf.extend(std::iter::repeat(0).take(shift));
36            self.buf.rotate_right(shift);
37            self.head = 0;
38        }
39        self.buf[self.head..self.head + slice.len()].copy_from_slice(slice);
40    }
41
42    /// Number of bytes in the buffer.
43    pub fn len(&self) -> usize { self.buf.len() - self.head }
44
45    /// True if empty.
46    pub fn is_empty(&self) -> bool { self.head == self.buf.len() }
47}
48
49impl AsRef<[u8]> for DequeBuffer {
50    fn as_ref(&self) -> &[u8] { &self.buf[self.head..] }
51}
52impl AsMut<[u8]> for DequeBuffer {
53    fn as_mut(&mut self) -> &mut [u8] { &mut self.buf[self.head..] }
54}
55impl<I: SliceIndex<[u8]>> Index<I> for DequeBuffer {
56    type Output = I::Output;
57    fn index(&self, i: I) -> &Self::Output { self.as_ref().index(i) }
58}
59impl<I: SliceIndex<[u8]>> IndexMut<I> for DequeBuffer {
60    fn index_mut(&mut self, i: I) -> &mut Self::Output { self.as_mut().index_mut(i) }
61}
62impl Extend<u8> for DequeBuffer {
63    fn extend<T: IntoIterator<Item = u8>>(&mut self, iter: T) { self.buf.extend(iter); }
64}
65impl<'a> Extend<&'a u8> for DequeBuffer {
66    fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, iter: T) { self.buf.extend(iter); }
67}