1use std::{
2 cmp,
3 io::{self, Read, Write},
4 ptr,
5};
6
7use poule::Reset;
8
9#[derive(Debug, PartialEq, Eq, Clone, Default)]
10pub struct BufferMetadata {
11 position: usize,
12 end: usize,
13}
14
15#[derive(Debug, PartialEq, Clone)]
16pub struct Buffer {
17 inner: trailer::Trailer<BufferMetadata>,
18}
19
20impl Buffer {
21 pub fn with_capacity(capacity: usize) -> Buffer {
22 let mut inner: trailer::Trailer<BufferMetadata> = trailer::Trailer::new(capacity);
23 inner.position = 0;
24 inner.end = 0;
25
26 Buffer { inner }
27 }
28
29 pub fn grow(&mut self, new_size: usize) -> bool {
41 if self.inner.capacity() >= new_size {
42 return false;
43 }
44
45 unimplemented!()
51 }
52
53 pub fn available_data(&self) -> usize {
54 self.inner.end - self.inner.position
55 }
56
57 pub fn available_space(&self) -> usize {
58 self.inner.capacity() - self.inner.end
59 }
60
61 pub fn capacity(&self) -> usize {
62 self.inner.capacity()
63 }
64
65 pub fn empty(&self) -> bool {
66 self.inner.position == self.inner.end
67 }
68
69 pub fn consume(&mut self, count: usize) -> usize {
70 let cnt = cmp::min(count, self.available_data());
71 self.inner.position += cnt;
72 if self.inner.position > self.inner.capacity() / 2 {
73 self.shift();
75 }
76 cnt
77 }
78
79 pub fn fill(&mut self, count: usize) -> usize {
80 let cnt = cmp::min(count, self.available_space());
81 self.inner.end += cnt;
82 if self.available_space() < self.available_data() + cnt {
83 self.shift();
85 }
86
87 cnt
88 }
89
90 pub fn reset(&mut self) {
91 self.inner.position = 0;
92 self.inner.end = 0;
93 }
94
95 pub fn data(&self) -> &[u8] {
96 &self.inner.bytes()[self.inner.position..self.inner.end]
97 }
98
99 pub fn space(&mut self) -> &mut [u8] {
100 let range = self.inner.end..self.inner.capacity();
101 &mut self.inner.bytes_mut()[range]
102 }
103
104 pub fn shift(&mut self) {
105 if self.inner.position > 0 {
106 unsafe {
107 let length = self.inner.end - self.inner.position;
108 ptr::copy(
109 self.inner.bytes()[self.inner.position..self.inner.end].as_ptr(),
110 self.inner.bytes_mut()[..length].as_mut_ptr(),
111 length,
112 );
113 self.inner.position = 0;
114 self.inner.end = length;
115 }
116 }
117 }
118
119 pub fn delete_slice(&mut self, start: usize, length: usize) -> Option<usize> {
120 if start + length >= self.available_data() {
121 return None;
122 }
123
124 unsafe {
125 let begin = self.inner.position + start;
126 let next_end = self.inner.end - length;
127 ptr::copy(
128 self.inner.bytes()[begin + length..self.inner.end].as_ptr(),
129 self.inner.bytes_mut()[begin..next_end].as_mut_ptr(),
130 self.inner.end - (begin + length),
131 );
132 self.inner.end = next_end;
133 }
134 Some(self.available_data())
135 }
136
137 pub fn replace_slice(&mut self, data: &[u8], start: usize, length: usize) -> Option<usize> {
138 let data_len = data.len();
139 if start + length > self.available_data()
140 || self.inner.position + start + data_len > self.capacity()
141 {
142 return None;
143 }
144
145 unsafe {
146 let begin = self.inner.position + start;
147 let slice_end = begin + data_len;
148 if data_len < length {
150 ptr::copy(
151 data.as_ptr(),
152 self.inner.bytes_mut()[begin..slice_end].as_mut_ptr(),
153 data_len,
154 );
155
156 ptr::copy(
157 self.inner.bytes()[start + length..self.inner.end].as_ptr(),
158 self.inner.bytes_mut()[slice_end..].as_mut_ptr(),
159 self.inner.end - (start + length),
160 );
161 self.inner.end -= length - data_len;
162
163 } else {
165 ptr::copy(
166 self.inner.bytes()[start + length..self.inner.end].as_ptr(),
167 self.inner.bytes_mut()[start + data_len..].as_mut_ptr(),
168 self.inner.end - (start + length),
169 );
170 ptr::copy(
171 data.as_ptr(),
172 self.inner.bytes_mut()[begin..slice_end].as_mut_ptr(),
173 data_len,
174 );
175 self.inner.end += data_len - length;
176 }
177 }
178 Some(self.available_data())
179 }
180
181 pub fn insert_slice(&mut self, data: &[u8], start: usize) -> Option<usize> {
182 let data_len = data.len();
183 if start > self.available_data()
184 || self.inner.position + self.inner.end + data_len > self.capacity()
185 {
186 return None;
187 }
188
189 unsafe {
190 let begin = self.inner.position + start;
191 let slice_end = begin + data_len;
192 ptr::copy(
193 self.inner.bytes()[start..self.inner.end].as_ptr(),
194 self.inner.bytes_mut()[start + data_len..].as_mut_ptr(),
195 self.inner.end - start,
196 );
197 ptr::copy(
198 data.as_ptr(),
199 self.inner.bytes_mut()[begin..slice_end].as_mut_ptr(),
200 data_len,
201 );
202 self.inner.end += data_len;
203 }
204 Some(self.available_data())
205 }
206}
207
208impl Write for Buffer {
209 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
210 match self.space().write(buf) {
211 Ok(size) => {
212 self.fill(size);
213 Ok(size)
214 }
215 err => err,
216 }
217 }
218
219 fn flush(&mut self) -> io::Result<()> {
220 Ok(())
221 }
222}
223
224impl Read for Buffer {
225 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
226 let len = cmp::min(self.available_data(), buf.len());
227 unsafe {
228 ptr::copy(
229 self.inner.bytes()[self.inner.position..self.inner.position + len].as_ptr(),
230 buf.as_mut_ptr(),
231 len,
232 );
233 self.inner.position += len;
234 }
235 Ok(len)
236 }
237}
238
239impl Reset for Buffer {
240 fn reset(&mut self) {
241 self.reset();
242 }
243}
244
245#[cfg(test)]
246mod tests {
247 use super::*;
248 use std::io::Write;
249
250 #[test]
251 fn fill_and_consume() {
252 let mut b = Buffer::with_capacity(10);
253 assert_eq!(b.available_data(), 0);
254 assert_eq!(b.available_space(), 10);
255 let res = b.write(&b"abcd"[..]);
256 assert_eq!(res.ok(), Some(4));
257 assert_eq!(b.available_data(), 4);
258 assert_eq!(b.available_space(), 6);
259
260 assert_eq!(b.data(), &b"abcd"[..]);
261
262 b.consume(2);
263 assert_eq!(b.available_data(), 2);
264 assert_eq!(b.available_space(), 6);
265 assert_eq!(b.data(), &b"cd"[..]);
266
267 b.shift();
268 assert_eq!(b.available_data(), 2);
269 assert_eq!(b.available_space(), 8);
270 assert_eq!(b.data(), &b"cd"[..]);
271
272 assert_eq!(b.write(&b"efghijklmnop"[..]).ok(), Some(8));
273 assert_eq!(b.available_data(), 10);
274 assert_eq!(b.available_space(), 0);
275 assert_eq!(b.data(), &b"cdefghijkl"[..]);
276 b.shift();
277 assert_eq!(b.available_data(), 10);
278 assert_eq!(b.available_space(), 0);
279 assert_eq!(b.data(), &b"cdefghijkl"[..]);
280 }
281
282 #[test]
283 fn delete() {
284 let mut b = Buffer::with_capacity(10);
285 let _ = b.write(&b"abcdefgh"[..]).expect("should write");
286 assert_eq!(b.available_data(), 8);
287 assert_eq!(b.available_space(), 2);
288
289 assert_eq!(b.delete_slice(2, 3), Some(5));
290 assert_eq!(b.available_data(), 5);
291 assert_eq!(b.available_space(), 5);
292 assert_eq!(b.data(), &b"abfgh"[..]);
293
294 assert_eq!(b.delete_slice(5, 2), None);
295 assert_eq!(b.delete_slice(4, 2), None);
296 }
297
298 #[test]
299 fn replace() {
300 let mut b = Buffer::with_capacity(10);
301 let _ = b.write(&b"abcdefgh"[..]).expect("should write");
302 assert_eq!(b.available_data(), 8);
303 assert_eq!(b.available_space(), 2);
304
305 assert_eq!(b.replace_slice(&b"ABC"[..], 2, 3), Some(8));
306 assert_eq!(b.available_data(), 8);
307 assert_eq!(b.available_space(), 2);
308 assert_eq!(b.data(), &b"abABCfgh"[..]);
309
310 assert_eq!(b.replace_slice(&b"XYZ"[..], 8, 3), None);
311 assert_eq!(b.replace_slice(&b"XYZ"[..], 6, 3), None);
312
313 assert_eq!(b.replace_slice(&b"XYZ"[..], 2, 4), Some(7));
314 assert_eq!(b.available_data(), 7);
315 assert_eq!(b.available_space(), 3);
316 assert_eq!(b.data(), &b"abXYZgh"[..]);
317
318 assert_eq!(b.replace_slice(&b"123"[..], 2, 2), Some(8));
319 assert_eq!(b.available_data(), 8);
320 assert_eq!(b.available_space(), 2);
321 assert_eq!(b.data(), &b"ab123Zgh"[..]);
322 }
323}