Skip to main content

ferogram_crypto/
deque_buffer.rs

1// Copyright (c) Ankit Chaubey <ankitchaubey.dev@gmail.com>
2//
3// ferogram: async Telegram MTProto client in Rust
4// https://github.com/ankit-chaubey/ferogram
5//
6// Licensed under either the MIT License or the Apache License 2.0.
7// See the LICENSE-MIT or LICENSE-APACHE file in this repository:
8// https://github.com/ankit-chaubey/ferogram
9//
10// Feel free to use, modify, and share this code.
11// Please keep this notice when redistributing.
12
13use std::ops::{Index, IndexMut};
14use std::slice::SliceIndex;
15
16/// Growable byte buffer that supports efficient front-extension.
17#[derive(Clone, Debug)]
18pub struct DequeBuffer {
19    buf: Vec<u8>,
20    head: usize,
21    default_head: usize,
22}
23
24impl DequeBuffer {
25    /// Create with reserved space for `back` bytes in the back and `front` in the front.
26    pub fn with_capacity(back: usize, front: usize) -> Self {
27        let mut buf = Vec::with_capacity(front + back);
28        buf.resize(front, 0);
29        Self {
30            buf,
31            head: front,
32            default_head: front,
33        }
34    }
35
36    /// Reset the buffer to empty (but keep allocation).
37    pub fn clear(&mut self) {
38        self.buf.truncate(self.default_head);
39        self.buf[..self.head].fill(0);
40        self.head = self.default_head;
41    }
42
43    /// Prepend `slice` to the front.
44    pub fn extend_front(&mut self, slice: &[u8]) {
45        if self.head >= slice.len() {
46            self.head -= slice.len();
47        } else {
48            let shift = slice.len() - self.head;
49            self.buf.extend(std::iter::repeat_n(0, shift));
50            self.buf.rotate_right(shift);
51            self.head = 0;
52        }
53        self.buf[self.head..self.head + slice.len()].copy_from_slice(slice);
54    }
55
56    /// Number of bytes in the buffer.
57    pub fn len(&self) -> usize {
58        self.buf.len() - self.head
59    }
60
61    /// True if empty.
62    pub fn is_empty(&self) -> bool {
63        self.head == self.buf.len()
64    }
65}
66
67impl AsRef<[u8]> for DequeBuffer {
68    fn as_ref(&self) -> &[u8] {
69        &self.buf[self.head..]
70    }
71}
72impl AsMut<[u8]> for DequeBuffer {
73    fn as_mut(&mut self) -> &mut [u8] {
74        &mut self.buf[self.head..]
75    }
76}
77impl<I: SliceIndex<[u8]>> Index<I> for DequeBuffer {
78    type Output = I::Output;
79    fn index(&self, i: I) -> &Self::Output {
80        self.as_ref().index(i)
81    }
82}
83impl<I: SliceIndex<[u8]>> IndexMut<I> for DequeBuffer {
84    fn index_mut(&mut self, i: I) -> &mut Self::Output {
85        self.as_mut().index_mut(i)
86    }
87}
88impl Extend<u8> for DequeBuffer {
89    fn extend<T: IntoIterator<Item = u8>>(&mut self, iter: T) {
90        self.buf.extend(iter);
91    }
92}
93impl<'a> Extend<&'a u8> for DequeBuffer {
94    fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, iter: T) {
95        self.buf.extend(iter);
96    }
97}