1use 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 #[inline]
16 pub fn as_mut_ptr(&mut self) -> *mut u8 {
17 self.buf.as_mut_ptr()
18 }
19
20 #[inline]
22 pub fn capacity(&self) -> usize {
23 self.buf.len()
24 }
25
26 #[inline]
28 pub fn len(&self) -> usize {
29 self.filled
30 }
31
32 #[inline]
34 pub fn is_empty(&self) -> bool {
35 self.filled == 0
36 }
37
38 #[inline]
40 pub fn filled(&self) -> &[u8] {
41 &self.buf.as_slice()[..self.filled]
42 }
43
44 #[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 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 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}