buffer_redux/buffer/
slice_deque_buf.rs

1//! Move-free buffer and reader utilizing the [`slice-ring-buffer`] crate.
2//!
3//! These types are only available on target platforms with virtual memory support,
4//! namely Windows, OS X and Linux.
5//!
6//! [`slice-ring-buffer`]: https://crates.io/crates/slice-ring-buffer
7use slice_ring_buffer::SliceRingBuffer as SliceDeque;
8
9use std::{cmp, mem::MaybeUninit};
10
11pub struct SliceDequeBuf {
12    deque: SliceDeque<u8>,
13}
14
15/// Move-free buffer utilizing the [`slice-deque`] crate.
16///
17/// Its usable space will always be equal to its free space.
18///
19/// This is only available on target platforms with virtual memory support,
20/// namely Windows, OS X and Linux.
21impl SliceDequeBuf {
22    pub fn with_capacity(cap: usize) -> Self {
23        SliceDequeBuf {
24            deque: SliceDeque::with_capacity(cap),
25        }
26    }
27
28    pub fn capacity(&self) -> usize {
29        self.deque.capacity()
30    }
31
32    pub fn len(&self) -> usize {
33        self.deque.len()
34    }
35
36    pub fn usable_space(&self) -> usize {
37        self.capacity() - self.len()
38    }
39
40    pub fn reserve(&mut self, additional: usize) -> bool {
41        self.deque.reserve(additional);
42        true
43    }
44
45    /// This method is a no-op.
46    pub fn make_room(&mut self) {}
47
48    #[inline]
49    pub fn buf(&self) -> &[u8] {
50        &self.deque
51    }
52
53    pub fn buf_mut(&mut self) -> &mut [u8] {
54        &mut self.deque
55    }
56
57    pub unsafe fn write_buf(&mut self) -> &mut [MaybeUninit<u8>] {
58        self.deque.tail_head_slice()
59    }
60
61    pub unsafe fn bytes_written(&mut self, add: usize) {
62        let offset = cmp::min(add, self.usable_space()) as isize;
63
64        if offset < 0 {
65            panic!("BufImpl.bytes_written() arg overflowed isize: {add:x}");
66        }
67
68        self.deque.move_tail(offset);
69    }
70
71    pub fn consume(&mut self, amt: usize) {
72        unsafe {
73            let offset = cmp::min(amt, self.len()) as isize;
74
75            if offset < 0 {
76                panic!("BufImpl.consume() arg overflowed isize: {amt:x}")
77            }
78
79            self.deque.move_head(offset);
80        }
81    }
82}