haagenti_stream/
buffer.rs1use crate::DEFAULT_BUFFER_SIZE;
4
5#[derive(Debug)]
9pub struct StreamBuffer {
10 data: Vec<u8>,
12 read_pos: usize,
14 write_pos: usize,
16}
17
18impl StreamBuffer {
19 pub fn new() -> Self {
21 Self::with_capacity(DEFAULT_BUFFER_SIZE)
22 }
23
24 pub fn with_capacity(capacity: usize) -> Self {
26 Self {
27 data: vec![0u8; capacity],
28 read_pos: 0,
29 write_pos: 0,
30 }
31 }
32
33 #[inline]
35 pub fn capacity(&self) -> usize {
36 self.data.len()
37 }
38
39 #[inline]
41 pub fn available(&self) -> usize {
42 self.write_pos - self.read_pos
43 }
44
45 #[inline]
47 pub fn remaining(&self) -> usize {
48 self.data.len() - self.write_pos
49 }
50
51 #[inline]
53 pub fn is_empty(&self) -> bool {
54 self.read_pos >= self.write_pos
55 }
56
57 #[inline]
59 pub fn is_full(&self) -> bool {
60 self.write_pos >= self.data.len()
61 }
62
63 #[inline]
65 pub fn readable(&self) -> &[u8] {
66 &self.data[self.read_pos..self.write_pos]
67 }
68
69 #[inline]
71 pub fn writable(&mut self) -> &mut [u8] {
72 &mut self.data[self.write_pos..]
73 }
74
75 #[inline]
77 pub fn consume(&mut self, n: usize) {
78 self.read_pos = (self.read_pos + n).min(self.write_pos);
79 }
80
81 #[inline]
83 pub fn advance(&mut self, n: usize) {
84 self.write_pos = (self.write_pos + n).min(self.data.len());
85 }
86
87 #[inline]
89 pub fn clear(&mut self) {
90 self.read_pos = 0;
91 self.write_pos = 0;
92 }
93
94 pub fn compact(&mut self) {
96 if self.read_pos > 0 {
97 let available = self.available();
98 if available > 0 {
99 self.data.copy_within(self.read_pos..self.write_pos, 0);
100 }
101 self.read_pos = 0;
102 self.write_pos = available;
103 }
104 }
105
106 pub fn write(&mut self, data: &[u8]) -> usize {
110 let space = self.remaining();
111 let to_write = data.len().min(space);
112
113 if to_write > 0 {
114 self.data[self.write_pos..self.write_pos + to_write].copy_from_slice(&data[..to_write]);
115 self.write_pos += to_write;
116 }
117
118 to_write
119 }
120
121 pub fn read(&mut self, buf: &mut [u8]) -> usize {
125 let available = self.available();
126 let to_read = buf.len().min(available);
127
128 if to_read > 0 {
129 buf[..to_read].copy_from_slice(&self.data[self.read_pos..self.read_pos + to_read]);
130 self.read_pos += to_read;
131 }
132
133 to_read
134 }
135
136 #[inline]
138 pub fn as_slice(&self) -> &[u8] {
139 &self.data[..self.write_pos]
140 }
141
142 #[inline]
144 pub fn as_mut_slice(&mut self) -> &mut [u8] {
145 &mut self.data
146 }
147}
148
149impl Default for StreamBuffer {
150 fn default() -> Self {
151 Self::new()
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158
159 #[test]
160 fn test_new_buffer() {
161 let buf = StreamBuffer::new();
162 assert_eq!(buf.capacity(), DEFAULT_BUFFER_SIZE);
163 assert!(buf.is_empty());
164 assert!(!buf.is_full());
165 }
166
167 #[test]
168 fn test_write_and_read() {
169 let mut buf = StreamBuffer::with_capacity(64);
170
171 let written = buf.write(b"Hello, World!");
172 assert_eq!(written, 13);
173 assert_eq!(buf.available(), 13);
174
175 let mut out = [0u8; 64];
176 let read = buf.read(&mut out);
177 assert_eq!(read, 13);
178 assert_eq!(&out[..13], b"Hello, World!");
179 assert!(buf.is_empty());
180 }
181
182 #[test]
183 fn test_compact() {
184 let mut buf = StreamBuffer::with_capacity(32);
185
186 buf.write(b"Hello, World!");
187 buf.consume(7); assert_eq!(buf.readable(), b"World!");
190 assert_eq!(buf.read_pos, 7);
191
192 buf.compact();
193 assert_eq!(buf.read_pos, 0);
194 assert_eq!(buf.write_pos, 6);
195 assert_eq!(buf.readable(), b"World!");
196 }
197
198 #[test]
199 fn test_full_buffer() {
200 let mut buf = StreamBuffer::with_capacity(8);
201
202 let written = buf.write(b"12345678");
203 assert_eq!(written, 8);
204 assert!(buf.is_full());
205
206 let written = buf.write(b"more");
208 assert_eq!(written, 0);
209 }
210
211 #[test]
212 fn test_clear() {
213 let mut buf = StreamBuffer::with_capacity(32);
214 buf.write(b"Hello");
215 buf.clear();
216
217 assert!(buf.is_empty());
218 assert_eq!(buf.available(), 0);
219 }
220}