1use bytes::Buf;
8use std::io::{Cursor, Read, Result as IoResult};
9
10#[derive(Debug)]
12pub struct ReadBuffer<const CHUNK_SIZE: usize> {
13 storage: Cursor<Vec<u8>>,
14 chunk: Box<[u8; CHUNK_SIZE]>,
15}
16
17impl<const CHUNK_SIZE: usize> ReadBuffer<CHUNK_SIZE> {
18 pub fn new() -> Self {
20 Self::with_capacity(CHUNK_SIZE)
21 }
22
23 pub fn with_capacity(capacity: usize) -> Self {
25 Self {
26 storage: Cursor::new(Vec::with_capacity(capacity)),
27 chunk: Box::new([0; CHUNK_SIZE]),
28 }
29 }
30
31 pub fn read_from<S: Read>(&mut self, source: &mut S) -> IoResult<usize> {
33 self.clean();
34
35 let read_size = source.read(&mut *self.chunk)?;
36 self.storage.get_mut().extend_from_slice(&self.chunk[..read_size]);
37
38 Ok(read_size)
39 }
40
41 fn clean(&mut self) {
43 let pos = self.storage.position() as usize;
44 self.storage.get_mut().drain(..pos);
45 self.storage.set_position(0);
46 }
47
48 pub fn into_vec(mut self) -> Vec<u8> {
50 self.clean();
51 self.storage.into_inner()
52 }
53
54 pub fn as_cursor(&self) -> &Cursor<Vec<u8>> {
56 &self.storage
57 }
58
59 pub fn as_cursor_mut(&mut self) -> &mut Cursor<Vec<u8>> {
61 &mut self.storage
62 }
63}
64
65impl<const CHUNK_SIZE: usize> Buf for ReadBuffer<CHUNK_SIZE> {
66 fn remaining(&self) -> usize {
67 self.storage.get_ref().len() - self.storage.position() as usize
68 }
69
70 fn chunk(&self) -> &[u8] {
71 let pos = self.storage.position() as usize;
72 &self.storage.get_ref()[pos..]
73 }
74
75 fn advance(&mut self, cnt: usize) {
76 let new_position =
77 (self.storage.position() + cnt as u64).min(self.storage.get_ref().len() as u64);
78 self.storage.set_position(new_position);
79 }
80}
81
82impl<const CHUNK_SIZE: usize> Default for ReadBuffer<CHUNK_SIZE> {
83 fn default() -> Self {
84 Self::new()
85 }
86}