1#![no_std]
2
3extern crate alloc;
4
5use alloc::boxed::Box;
6use alloc::collections::VecDeque;
7use alloc::vec::Vec;
8use core::cmp::min;
9use core::ops::{Index, IndexMut};
10
11pub const DEFAULT_CHUNK_SIZE: usize = 256;
13
14pub type ChunkedBuffer = GenericChunkedBuffer<DEFAULT_CHUNK_SIZE>;
17
18pub struct GenericChunkedBuffer<const CHUNK_SIZE: usize> {
43 write_pos: usize,
45 read_pos: usize,
47 chunks: VecDeque<Box<[u8; CHUNK_SIZE]>>,
48}
49
50impl<const CHUNK_SIZE: usize> GenericChunkedBuffer<CHUNK_SIZE> {
51 pub fn new() -> Self {
53 let mut s = GenericChunkedBuffer {
54 write_pos: 0,
55 read_pos: 0,
56 chunks: VecDeque::new(),
57 };
58 s.chunks.push_back(Box::new([0; CHUNK_SIZE]));
59 s
60 }
61
62 pub fn len(&self) -> usize {
64 (self.chunks.len() - 1) * CHUNK_SIZE + self.write_pos - self.read_pos
65 }
66
67 pub fn is_empty(&self) -> bool {
69 self.chunks.len() == 1 && self.write_pos == self.read_pos
70 }
71
72 pub fn read(&mut self, dest: &mut [u8]) -> usize {
75 let mut nread = 0;
76 while nread < dest.len() && !self.is_empty() {
77 let chunk = &*self.chunks[0];
78 let start = self.read_pos;
79 let mut end = min(CHUNK_SIZE, start + dest.len() - nread);
80 if self.chunks.len() == 1 {
81 end = end.min(self.write_pos);
82 }
83 let n = end - start;
84 dest[nread..nread + n].copy_from_slice(&chunk[start..end]);
85 if end == CHUNK_SIZE {
86 self.read_pos = 0;
87 self.chunks.pop_front();
88 } else {
91 self.read_pos = end;
92 }
93 nread += n;
94 }
95 nread
96 }
97
98 pub fn write(&mut self, src: &[u8]) {
100 let mut nwritten = 0;
101 while nwritten < src.len() {
102 let chunk = &mut **self.chunks.back_mut().unwrap();
103 let start = self.write_pos;
104 let end = min(CHUNK_SIZE, start + src.len() - nwritten);
105 let n = end - start;
106 chunk[start..end].copy_from_slice(&src[nwritten..nwritten + n]);
107 nwritten += n;
108 if end == CHUNK_SIZE {
109 self.write_pos = 0;
110 self.chunks.push_back(Box::new([0; CHUNK_SIZE]));
111 } else {
112 self.write_pos = end;
113 }
114 }
115 }
116
117 pub fn iter(&self) -> Iter<CHUNK_SIZE> {
119 Iter::new(self)
120 }
121
122 pub fn iter_chunks(&self) -> IterChunk<CHUNK_SIZE> {
124 IterChunk::new(self)
125 }
126
127 pub fn to_vec(&self) -> Vec<u8> {
129 let mut vec = Vec::with_capacity(self.len());
130 for chunk in self.iter_chunks() {
131 vec.extend_from_slice(chunk);
132 }
133 vec
134 }
135}
136
137impl<const CHUNK_SIZE: usize> Default for GenericChunkedBuffer<CHUNK_SIZE> {
138 fn default() -> Self {
139 Self::new()
140 }
141}
142
143impl<const CHUNK_SIZE: usize> Index<usize> for GenericChunkedBuffer<CHUNK_SIZE> {
144 type Output = u8;
145
146 fn index(&self, index: usize) -> &Self::Output {
147 if self.is_empty() {
148 panic!("indexed into an empty buffer");
149 }
150 if index >= self.len() {
151 panic!("out of bounds access");
152 }
153 let pos = index % CHUNK_SIZE;
154 let index = index / CHUNK_SIZE;
155 &self.chunks[index][pos]
156 }
157}
158
159impl<const CHUNK_SIZE: usize> IndexMut<usize> for GenericChunkedBuffer<CHUNK_SIZE> {
160 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
161 if self.is_empty() {
162 panic!("indexed into an empty buffer");
163 }
164 if index >= self.len() {
165 panic!("out of bounds access");
166 }
167 let pos = index % CHUNK_SIZE;
168 let index = index / CHUNK_SIZE;
169 &mut self.chunks[index][pos]
170 }
171}
172
173pub struct Iter<'a, const CHUNK_SIZE: usize> {
174 nread: usize,
175 index: usize,
176 read_pos: usize,
177 buf: &'a GenericChunkedBuffer<CHUNK_SIZE>,
178}
179
180impl<'a, const CHUNK_SIZE: usize> Iter<'a, CHUNK_SIZE> {
181 fn new(buf: &'a GenericChunkedBuffer<CHUNK_SIZE>) -> Self {
182 Iter {
183 nread: 0,
184 index: 0,
185 read_pos: buf.read_pos,
186 buf,
187 }
188 }
189}
190
191impl<const CHUNK_SIZE: usize> Iterator for Iter<'_, CHUNK_SIZE> {
192 type Item = u8;
193 fn next(&mut self) -> Option<Self::Item> {
194 if self.nread == self.buf.len() {
195 None
196 } else {
197 let byte = self.buf.chunks[self.index][self.read_pos];
198 self.nread += 1;
199 self.read_pos += 1;
200 if self.read_pos == CHUNK_SIZE {
201 self.read_pos = 0;
202 self.index += 1;
203 }
204 Some(byte)
205 }
206 }
207}
208
209pub struct IterChunk<'a, const CHUNK_SIZE: usize> {
210 index: usize,
211 buf: &'a GenericChunkedBuffer<CHUNK_SIZE>,
212}
213
214impl<'a, const CHUNK_SIZE: usize> IterChunk<'a, CHUNK_SIZE> {
215 fn new(buf: &'a GenericChunkedBuffer<CHUNK_SIZE>) -> Self {
216 IterChunk { index: 0, buf }
217 }
218}
219
220impl<'a, const CHUNK_SIZE: usize> Iterator for IterChunk<'a, CHUNK_SIZE> {
221 type Item = &'a [u8];
222 fn next(&mut self) -> Option<Self::Item> {
223 if self.index == self.buf.chunks.len() {
224 None
225 } else {
226 let begin = if self.index == 0 {
227 self.buf.read_pos
228 } else {
229 0
230 };
231 let end = if self.index + 1 == self.buf.chunks.len() {
232 self.buf.write_pos
233 } else {
234 CHUNK_SIZE
235 };
236 let slice = &self.buf.chunks[self.index][begin..end];
237 self.index += 1;
238 if slice.is_empty() {
239 None
240 } else {
241 Some(slice)
242 }
243 }
244 }
245}
246
247#[cfg(test)]
248mod tests {
249 use super::*;
250
251 type Buf = GenericChunkedBuffer<4>;
252
253 #[test]
254 fn test() {
255 let mut buf = Buf::new();
256 assert_eq!(buf.len(), 0);
257 assert!(buf.is_empty());
258
259 let mut dest = [0; 10];
260 assert_eq!(buf.read(&mut dest), 0);
261
262 buf.write(&[1, 2, 3]);
263 assert_eq!(buf.len(), 3);
264 assert!(!buf.is_empty());
265
266 let mut dest = [0; 10];
267 assert_eq!(buf.read(&mut dest), 3);
268 assert_eq!(dest, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]);
269 assert_eq!(buf.len(), 0);
270 assert!(buf.is_empty());
271
272 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
273 assert_eq!(buf.len(), 10);
274 assert!(!buf.is_empty());
275
276 let mut dest = [0; 9];
277 assert_eq!(buf.read(&mut dest), 9);
278 assert_eq!(dest, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
279 assert_eq!(buf.len(), 1);
280
281 let mut dest = [0; 9];
282 assert_eq!(buf.read(&mut dest), 1);
283 assert_eq!(dest, [10, 0, 0, 0, 0, 0, 0, 0, 0]);
284 assert_eq!(buf.len(), 0);
285 assert!(buf.is_empty());
286
287 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
288 assert_eq!(buf.len(), 10);
289 assert!(!buf.is_empty());
290
291 let mut dest = [0; 5];
292 assert_eq!(buf.read(&mut dest), 5);
293 assert_eq!(dest, [1, 2, 3, 4, 5]);
294 assert_eq!(buf.len(), 5);
295 assert!(!buf.is_empty());
296
297 let mut dest = [0; 5];
298 assert_eq!(buf.read(&mut dest), 5);
299 assert_eq!(dest, [6, 7, 8, 9, 10]);
300 assert_eq!(buf.len(), 0);
301 assert!(buf.is_empty());
302
303 let mut dest = [0; 5];
305 buf.write(&[99]);
306 assert_eq!(buf.len(), 1);
307 assert_eq!(buf.read(&mut dest), 1);
308 assert_eq!(dest, [99, 0, 0, 0, 0]);
309 }
310 #[test]
311 fn test_iterator() {
312 let mut buf = Buf::new();
314 let mut i = buf.iter();
315 assert_eq!(i.next(), None);
316 assert_eq!(i.next(), None);
317 assert_eq!(i.next(), None);
318
319 buf = Buf::new();
321 buf.write(&[]);
322 i = buf.iter();
323 assert_eq!(i.next(), None);
324 assert_eq!(i.next(), None);
325 assert_eq!(i.next(), None);
326
327 buf = Buf::new();
329 buf.write(&[1, 2, 3]);
330 i = buf.iter();
331 for count in 1..4 {
332 assert_eq!(i.next(), Some(count));
333 }
334 assert_eq!(i.next(), None);
335 assert_eq!(i.next(), None);
336 assert_eq!(i.next(), None);
337
338 buf = Buf::new();
340 buf.write(&[1, 2, 3, 4]);
341 i = buf.iter();
342 for count in 1..5 {
343 assert_eq!(i.next(), Some(count));
344 }
345 assert_eq!(i.next(), None);
346 assert_eq!(i.next(), None);
347 assert_eq!(i.next(), None);
348
349 buf = Buf::new();
351 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
352 i = buf.iter();
353 for count in 1..11 {
354 assert_eq!(i.next(), Some(count));
355 }
356 assert_eq!(i.next(), None);
357 assert_eq!(i.next(), None);
358 assert_eq!(i.next(), None);
359
360 buf = Buf::new();
362 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
363 i = buf.iter();
364 for count in 1..13 {
365 assert_eq!(i.next(), Some(count));
366 }
367 assert_eq!(i.next(), None);
368 assert_eq!(i.next(), None);
369 assert_eq!(i.next(), None);
370
371 buf = Buf::new();
373 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
374 i = buf.iter();
375 for count in 1..14 {
376 assert_eq!(i.next(), Some(count));
377 }
378 assert_eq!(i.next(), None);
379 assert_eq!(i.next(), None);
380 assert_eq!(i.next(), None);
381 }
382 #[test]
383 fn test_iter_chunks() {
384 let mut buf = Buf::new();
386 let mut i = buf.iter_chunks();
387 assert_eq!(i.next(), None);
388 assert_eq!(i.next(), None);
389 assert_eq!(i.next(), None);
390
391 buf = Buf::new();
393 buf.write(&[]);
394 i = buf.iter_chunks();
395 assert_eq!(i.next(), None);
396 assert_eq!(i.next(), None);
397 assert_eq!(i.next(), None);
398
399 buf = Buf::new();
401 buf.write(&[1, 2, 3]);
402 i = buf.iter_chunks();
403 assert_eq!(i.next(), Some(&[1, 2, 3][..]));
404 assert_eq!(i.next(), None);
405 assert_eq!(i.next(), None);
406 assert_eq!(i.next(), None);
407
408 buf = Buf::new();
410 buf.write(&[1, 2, 3, 4]);
411 i = buf.iter_chunks();
412 assert_eq!(i.next(), Some(&[1, 2, 3, 4][..]));
413 assert_eq!(i.next(), None);
414 assert_eq!(i.next(), None);
415 assert_eq!(i.next(), None);
416
417 buf = Buf::new();
419 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
420 i = buf.iter_chunks();
421 assert_eq!(i.next(), Some(&[1, 2, 3, 4][..]));
422 assert_eq!(i.next(), Some(&[5, 6, 7, 8][..]));
423 assert_eq!(i.next(), Some(&[9, 10][..]));
424 assert_eq!(i.next(), None);
425 assert_eq!(i.next(), None);
426 assert_eq!(i.next(), None);
427
428 buf = Buf::new();
430 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
431 i = buf.iter_chunks();
432 assert_eq!(i.next(), Some(&[1, 2, 3, 4][..]));
433 assert_eq!(i.next(), Some(&[5, 6, 7, 8][..]));
434 assert_eq!(i.next(), Some(&[9, 10, 11, 12][..]));
435 assert_eq!(i.next(), None);
436 assert_eq!(i.next(), None);
437 assert_eq!(i.next(), None);
438
439 buf = Buf::new();
441 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
442 i = buf.iter_chunks();
443 assert_eq!(i.next(), Some(&[1, 2, 3, 4][..]));
444 assert_eq!(i.next(), Some(&[5, 6, 7, 8][..]));
445 assert_eq!(i.next(), Some(&[9, 10, 11, 12][..]));
446 assert_eq!(i.next(), Some(&[13][..]));
447 assert_eq!(i.next(), None);
448 assert_eq!(i.next(), None);
449 assert_eq!(i.next(), None);
450 }
451 #[test]
452 fn test_index() {
453 let mut buf = Buf::new();
454 buf.write(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
455 for i in 0..14 {
456 assert_eq!(buf[i], i as u8);
457 }
458 }
459 #[test]
460 #[should_panic]
461 fn test_index_panic_on_empty() {
462 let buf = Buf::new();
463 buf[0];
464 }
465 #[test]
466 #[should_panic]
467 fn test_index_out_of_bounds() {
468 let mut buf = Buf::new();
469 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
470 buf[13];
471 }
472 #[test]
473 fn test_index_mut() {
474 let mut buf = Buf::new();
475 buf.write(&[0u8; 14]);
476 for i in 0..14 {
477 buf[i] = i as u8;
478 }
479 let mut want = Buf::new();
480 want.write(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
481 assert_eq!(buf.to_vec(), want.to_vec());
482 }
483 #[test]
484 #[should_panic]
485 fn test_index_mut_panic_on_empty() {
486 let mut buf = Buf::new();
487 buf[0] = 3;
488 }
489 #[test]
490 #[should_panic]
491 fn test_index_mut_out_of_bounds() {
492 let mut buf = Buf::new();
493 buf.write(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
494 buf[13] = 3;
495 }
496}