1use core::mem::MaybeUninit;
2
3pub const fn _assert_send<T: Send>() {}
4pub const fn _assert_sync<T: Sync>() {}
5
6#[derive(Debug, Default)]
7pub struct PartialBuffer<B> {
8 buffer: B,
9 index: usize,
10}
11
12impl<B: AsRef<[u8]>> PartialBuffer<B> {
13 pub fn new(buffer: B) -> Self {
14 Self { buffer, index: 0 }
15 }
16
17 pub fn written(&self) -> &[u8] {
18 &self.buffer.as_ref()[..self.index]
19 }
20
21 pub fn written_len(&self) -> usize {
23 self.index
24 }
25
26 pub fn unwritten(&self) -> &[u8] {
27 &self.buffer.as_ref()[self.index..]
28 }
29
30 pub fn advance(&mut self, amount: usize) {
31 self.index += amount;
32 debug_assert!(self.index <= self.buffer.as_ref().len());
33 }
34
35 pub fn get_mut(&mut self) -> &mut B {
36 &mut self.buffer
37 }
38
39 pub fn into_inner(self) -> B {
40 self.buffer
41 }
42
43 pub fn reset(&mut self) {
44 self.index = 0;
45 }
46}
47
48impl<B: AsRef<[u8]> + AsMut<[u8]>> PartialBuffer<B> {
49 pub fn unwritten_mut(&mut self) -> &mut [u8] {
50 &mut self.buffer.as_mut()[self.index..]
51 }
52
53 pub fn copy_unwritten_from<C: AsRef<[u8]>>(&mut self, other: &mut PartialBuffer<C>) -> usize {
54 let len = self.unwritten().len().min(other.unwritten().len());
55
56 self.unwritten_mut()[..len].copy_from_slice(&other.unwritten()[..len]);
57
58 self.advance(len);
59 other.advance(len);
60 len
61 }
62}
63
64impl<B: AsRef<[u8]> + Default> PartialBuffer<B> {
65 pub fn take(&mut self) -> Self {
66 std::mem::take(self)
67 }
68}
69
70impl<B: AsRef<[u8]> + AsMut<[u8]>> From<B> for PartialBuffer<B> {
71 fn from(buffer: B) -> Self {
72 Self::new(buffer)
73 }
74}
75
76#[derive(Debug)]
88pub struct WriteBuffer<'a> {
89 buffer: &'a mut [MaybeUninit<u8>],
90 index: usize,
91 initialized: usize,
92}
93
94impl<'a> WriteBuffer<'a> {
95 pub fn new_initialized(buffer: &'a mut [u8]) -> Self {
96 Self {
97 initialized: buffer.len(),
98 buffer: unsafe { &mut *(buffer as *mut [u8] as *mut _) },
101 index: 0,
102 }
103 }
104
105 pub fn new_uninitialized(buffer: &'a mut [MaybeUninit<u8>]) -> Self {
106 Self {
107 buffer,
108 index: 0,
109 initialized: 0,
110 }
111 }
112
113 pub fn capacity(&self) -> usize {
114 self.buffer.len()
115 }
116
117 pub fn as_mut_ptr(&mut self) -> *mut u8 {
118 self.buffer.as_mut_ptr() as *mut _
119 }
120
121 pub fn initialized_len(&self) -> usize {
122 self.initialized
123 }
124
125 pub fn written(&self) -> &[u8] {
126 debug_assert!(self.index <= self.initialized);
127
128 unsafe { &*(&self.buffer[..self.index] as *const _ as *const [u8]) }
129 }
130
131 pub fn written_len(&self) -> usize {
133 self.index
134 }
135
136 pub fn has_no_spare_space(&self) -> bool {
138 self.index == self.buffer.len()
139 }
140
141 pub fn initialize_unwritten(&mut self) -> &mut [u8] {
144 self.buffer[self.initialized..]
145 .iter_mut()
146 .for_each(|maybe_uninit| {
147 maybe_uninit.write(0);
148 });
149 self.initialized = self.buffer.len();
150
151 unsafe { &mut *(&mut self.buffer[self.index..] as *mut _ as *mut [u8]) }
152 }
153
154 pub fn advance(&mut self, amount: usize) {
158 debug_assert!(self.index + amount <= self.buffer.len());
159 debug_assert!(self.index + amount <= self.initialized);
160
161 self.index += amount;
162 }
163
164 pub fn reset(&mut self) {
165 self.index = 0;
166 }
167
168 pub unsafe fn unwritten_mut(&mut self) -> &mut [MaybeUninit<u8>] {
178 &mut self.buffer[self.index..]
179 }
180
181 pub unsafe fn assume_init(&mut self, n: usize) {
190 debug_assert!(self.index <= (self.initialized + n));
191 debug_assert!((self.initialized + n) <= self.buffer.len());
192
193 self.initialized += n;
194 }
195
196 pub unsafe fn assume_init_and_advance(&mut self, n: usize) {
202 debug_assert!(self.index + n <= self.buffer.len());
203
204 self.index += n;
205 self.initialized = self.initialized.max(self.index);
206 }
207
208 pub unsafe fn set_written_and_initialized_len(&mut self, n: usize) {
215 debug_assert!(n <= self.buffer.len());
216
217 self.index = n;
218 self.initialized = self.initialized.max(n);
219 }
220
221 pub fn copy_unwritten_from<C: AsRef<[u8]>>(&mut self, other: &mut PartialBuffer<C>) -> usize {
222 fn inner(this: &mut WriteBuffer<'_>, input: &[u8]) -> usize {
223 let out = unsafe { this.unwritten_mut() };
225
226 let len = out.len().min(input.len());
227
228 out[..len]
229 .iter_mut()
230 .zip(&input[..len])
231 .for_each(|(maybe_uninit, byte)| {
232 maybe_uninit.write(*byte);
233 });
234
235 unsafe { this.assume_init_and_advance(len) };
237 len
238 }
239
240 let len = inner(self, other.unwritten());
241 other.advance(len);
242
243 len
244 }
245}