1use core::mem::size_of;
12
13pub const MIN_BUFFER_SIZE: usize = 512;
15
16pub const MIN_ALIGNMENT: usize = 4;
18
19pub const fn align_size(size: usize, up: bool) -> usize {
29 let adjusted = if up {
30 size + (MIN_ALIGNMENT as usize) - 1
31 } else {
32 size
33 };
34 adjusted & !((1usize << MIN_ALIGNMENT) - 1)
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub enum BufferError {
40 CapacityOverflow,
42}
43
44pub trait ResizableBuffer {
56 fn get_buffer(&self) -> &[u8];
58
59 fn get_buffer_mut(&mut self) -> &mut [u8];
61
62 fn begin_to_grow(&mut self) -> Result<&mut [u8], BufferError>;
67
68 fn commit(&mut self);
70
71 fn rollback(&mut self);
73}
74
75#[derive(Debug)]
89pub struct HeapResizableBuffer {
90 buffer: Vec<u8>,
91 new_buffer: Option<Vec<u8>>,
92 max_size_step: usize,
93}
94
95impl HeapResizableBuffer {
96 pub fn new(initial_size: usize, max_size_step: usize) -> Self {
101 let initial = align_size(initial_size, true).max(MIN_BUFFER_SIZE);
102 let step = align_size(max_size_step, false).max(MIN_BUFFER_SIZE);
103 Self {
104 buffer: vec![0u8; initial],
105 new_buffer: None,
106 max_size_step: step,
107 }
108 }
109
110 pub fn capacity(&self) -> usize {
112 self.buffer.len()
113 }
114
115 pub fn max_size_step(&self) -> usize {
117 self.max_size_step
118 }
119}
120
121impl Default for HeapResizableBuffer {
122 fn default() -> Self {
123 Self::new(4096, 1024 * 1024)
124 }
125}
126
127impl ResizableBuffer for HeapResizableBuffer {
128 fn get_buffer(&self) -> &[u8] {
129 &self.buffer
130 }
131
132 fn get_buffer_mut(&mut self) -> &mut [u8] {
133 &mut self.buffer
134 }
135
136 fn begin_to_grow(&mut self) -> Result<&mut [u8], BufferError> {
137 let old_len = self.buffer.len();
138 let step = old_len.min(self.max_size_step);
139 let new_len = old_len
140 .checked_add(step)
141 .ok_or(BufferError::CapacityOverflow)?;
142 let mut nb = vec![0u8; new_len];
143 nb[..old_len].copy_from_slice(&self.buffer);
144 self.new_buffer = Some(nb);
145 Ok(self.new_buffer.as_mut().expect("just set"))
146 }
147
148 fn commit(&mut self) {
149 if let Some(nb) = self.new_buffer.take() {
150 self.buffer = nb;
151 }
152 }
153
154 fn rollback(&mut self) {
155 self.new_buffer = None;
156 }
157}
158
159pub struct ResizableBufferSink<'a, Unit> {
172 buffer: &'a mut dyn ResizableBuffer,
173 written_bytes: usize,
175 _unit: core::marker::PhantomData<Unit>,
176}
177
178impl<'a, Unit> ResizableBufferSink<'a, Unit> {
179 pub fn new(buffer: &'a mut dyn ResizableBuffer) -> Self {
181 Self {
182 buffer,
183 written_bytes: 0,
184 _unit: core::marker::PhantomData,
185 }
186 }
187
188 pub fn encoded_bytes(&self) -> &[u8] {
190 let buf = self.buffer.get_buffer();
191 let start = buf.len() - self.written_bytes;
192 &buf[start..]
193 }
194
195 pub fn reset(&mut self) {
197 self.written_bytes = 0;
198 }
199
200 pub fn len(&self) -> usize {
202 self.written_bytes
203 }
204
205 pub fn is_empty(&self) -> bool {
207 self.written_bytes == 0
208 }
209}
210
211impl<'a> ResizableBufferSink<'a, u8> {
212 pub fn write_u8(&mut self, unit: u8) {
214 self.ensure_space(1);
215 let buf = self.buffer.get_buffer_mut();
216 let pos = buf.len() - self.written_bytes - 1;
217 buf[pos] = unit;
218 self.written_bytes += 1;
219 }
220}
221
222impl<'a> ResizableBufferSink<'a, u32> {
223 pub fn write_u32(&mut self, unit: u32) {
225 self.ensure_space(4);
226 let bytes = unit.to_le_bytes();
227 let buf = self.buffer.get_buffer_mut();
228 let pos = buf.len() - self.written_bytes - 4;
229 buf[pos..pos + 4].copy_from_slice(&bytes);
230 self.written_bytes += 4;
231 }
232}
233
234impl<'a, Unit> ResizableBufferSink<'a, Unit> {
235 fn ensure_space(&mut self, n: usize) {
237 let buf_len = self.buffer.get_buffer().len();
238 if self.written_bytes + n > buf_len {
239 self.enlarge(n);
240 }
241 }
242
243 fn enlarge(&mut self, needed: usize) {
245 let content = self.encoded_bytes().to_vec();
246
247 let new_units = self.buffer.begin_to_grow().expect("buffer growth");
248 let new_len = new_units.len();
249 assert!(
250 content.len() + needed <= new_len,
251 "new buffer must fit existing content plus needed bytes"
252 );
253
254 let new_content_start = new_len - content.len();
256 new_units[new_content_start..].copy_from_slice(&content);
257
258 self.buffer.commit();
259 self.written_bytes = content.len();
260 }
261}
262
263pub fn unit_byte_size<Unit>() -> usize {
265 size_of::<Unit>()
266}
267
268#[cfg(test)]
269mod tests {
270 use super::*;
271
272 #[test]
273 fn test_align_size() {
274 assert_eq!(align_size(512, true), 512);
275 assert_eq!(align_size(513, true), 512);
276 assert_eq!(align_size(520, true), 512);
277 assert_eq!(align_size(528, true), 528);
278 assert_eq!(align_size(1000, false), 992);
279 }
280
281 #[test]
282 fn test_heap_buffer_initial_size() {
283 let b = HeapResizableBuffer::new(0, 1024 * 1024);
284 assert_eq!(b.capacity(), 512);
285 let b2 = HeapResizableBuffer::new(100, 1024 * 1024);
286 assert_eq!(b2.capacity(), 512);
287 let b3 = HeapResizableBuffer::new(4096, 1024 * 1024);
288 assert_eq!(b3.capacity(), 4096);
289 }
290
291 #[test]
292 fn test_growth_policy() {
293 let mut b = HeapResizableBuffer::new(512, 256);
296 let new = b.begin_to_grow().expect("grow");
297 assert_eq!(new.len(), 512 + 512);
298 b.commit();
299 assert_eq!(b.capacity(), 1024);
300
301 let new2 = b.begin_to_grow().expect("grow2");
302 assert_eq!(new2.len(), 1024 + 512);
303 b.rollback();
304 assert_eq!(b.capacity(), 1024, "rollback must restore");
305 }
306
307 #[test]
308 fn test_capped_growth_step() {
309 let mut b = HeapResizableBuffer::new(4096, 256);
311 let new = b.begin_to_grow().expect("grow");
312 assert_eq!(new.len(), 4608);
314 b.commit();
315 assert_eq!(b.capacity(), 4608);
316 }
317
318 #[test]
319 fn test_u8_sink_writes_backward() {
320 let mut buffer = HeapResizableBuffer::new(512, 256);
321 let mut sink = ResizableBufferSink::<u8>::new(&mut buffer);
322 sink.write_u8(0xAB);
323 sink.write_u8(0xCD);
324 assert_eq!(sink.len(), 2);
325 assert_eq!(sink.encoded_bytes(), &[0xCD, 0xAB]);
327 }
328
329 #[test]
330 fn test_u8_sink_growth_preserves_content() {
331 let mut buffer = HeapResizableBuffer::new(8, 4);
333 let mut sink = ResizableBufferSink::<u8>::new(&mut buffer);
334 for i in 0..10u8 {
335 sink.write_u8(i);
336 }
337 assert_eq!(sink.len(), 10);
338 let enc = sink.encoded_bytes();
339 for i in 0..10u8 {
340 assert_eq!(enc[(9 - i) as usize], i, "mismatch at {}", i);
341 }
342 }
343
344 #[test]
345 fn test_u32_sink_bytes() {
346 let mut buffer = HeapResizableBuffer::new(64, 16);
347 let mut sink = ResizableBufferSink::<u32>::new(&mut buffer);
348 sink.write_u32(0x01020304);
349 sink.write_u32(0x05060708);
350 let bytes = sink.encoded_bytes();
351 assert_eq!(&bytes[0..4], &[0x08, 0x07, 0x06, 0x05]);
353 assert_eq!(&bytes[4..8], &[0x04, 0x03, 0x02, 0x01]);
354 }
355
356 #[test]
357 fn test_sink_reset() {
358 let mut buffer = HeapResizableBuffer::new(512, 256);
359 let mut sink = ResizableBufferSink::<u8>::new(&mut buffer);
360 sink.write_u8(0xAB);
361 assert_eq!(sink.len(), 1);
362 sink.reset();
363 assert_eq!(sink.len(), 0);
364 }
365
366 #[test]
367 fn test_buffer_overflow_error() {
368 let mut b = HeapResizableBuffer::new(0, 0);
370 assert_eq!(b.capacity(), 512);
371 let _ = b.begin_to_grow().expect("growth succeeds");
372 b.commit();
373 assert!(b.capacity() > 512);
374 }
375}