zlib_rs/
read_buf.rs

1// taken from https://docs.rs/tokio/latest/src/tokio/io/read_buf.rs.html#23-27
2// based on https://rust-lang.github.io/rfcs/2930-read-buf.html
3use core::fmt;
4
5use crate::allocate::Allocator;
6use crate::weak_slice::WeakSliceMut;
7
8pub struct ReadBuf<'a> {
9    buf: WeakSliceMut<'a, u8>,
10    filled: usize,
11}
12
13impl<'a> ReadBuf<'a> {
14    /// Pointer to the start of the `ReadBuf`
15    #[inline]
16    pub fn as_mut_ptr(&mut self) -> *mut u8 {
17        self.buf.as_mut_ptr()
18    }
19
20    /// Returns the total capacity of the buffer.
21    #[inline]
22    pub fn capacity(&self) -> usize {
23        self.buf.len()
24    }
25
26    /// Returns the length of the filled part of the buffer
27    #[inline]
28    pub fn len(&self) -> usize {
29        self.filled
30    }
31
32    /// Returns true if there are no bytes in this ReadBuf
33    #[inline]
34    pub fn is_empty(&self) -> bool {
35        self.filled == 0
36    }
37
38    /// Returns a shared reference to the filled portion of the buffer.
39    #[inline]
40    pub fn filled(&self) -> &[u8] {
41        &self.buf.as_slice()[..self.filled]
42    }
43
44    /// Clears the buffer, resetting the filled region to empty.
45    ///
46    /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
47    #[inline]
48    pub fn clear(&mut self) {
49        self.buf.as_mut_slice().fill(0);
50        self.filled = 0;
51    }
52
53    #[inline(always)]
54    pub fn push_lit(&mut self, byte: u8) {
55        // NOTE: we rely on the buffer being zeroed here!
56        self.buf.as_mut_slice()[self.filled + 2] = byte;
57
58        self.filled += 3;
59    }
60
61    #[inline(always)]
62    pub fn push_dist(&mut self, dist: u16, len: u8) {
63        let buf = &mut self.buf.as_mut_slice()[self.filled..][..3];
64        let [dist1, dist2] = dist.to_le_bytes();
65
66        buf[0] = dist1;
67        buf[1] = dist2;
68        buf[2] = len;
69
70        self.filled += 3;
71    }
72
73    pub(crate) fn new_in(alloc: &Allocator<'a>, len: usize) -> Option<Self> {
74        let ptr = alloc.allocate_zeroed(len)?;
75
76        // safety: all elements are now initialized
77        let buf = unsafe { WeakSliceMut::from_raw_parts_mut(ptr.as_ptr(), len) };
78
79        Some(Self { buf, filled: 0 })
80    }
81
82    pub(crate) fn clone_in(&self, alloc: &Allocator<'a>) -> Option<Self> {
83        let mut clone = Self::new_in(alloc, self.buf.len())?;
84
85        clone
86            .buf
87            .as_mut_slice()
88            .copy_from_slice(self.buf.as_slice());
89        clone.filled = self.filled;
90
91        Some(clone)
92    }
93
94    pub(crate) unsafe fn drop_in(&mut self, alloc: &Allocator<'a>) {
95        if !self.buf.is_empty() {
96            let mut buf = core::mem::replace(&mut self.buf, WeakSliceMut::empty());
97            alloc.deallocate(buf.as_mut_ptr(), buf.len());
98        }
99    }
100}
101
102impl fmt::Debug for ReadBuf<'_> {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        f.debug_struct("ReadBuf")
105            .field("filled", &self.filled)
106            .field("capacity", &self.capacity())
107            .finish()
108    }
109}