1use io_buffer::{safe_copy, Buffer};
2use std::fs::*;
3use std::io::{Result, Write};
4use std::path::Path;
5
6pub struct RingBuffer {
21 end: usize,
22 full: bool,
23 inner: Buffer,
24}
25
26impl RingBuffer {
27 pub fn new(buf_size: i32) -> Self {
29 assert!(buf_size > 0);
30 let inner = Buffer::alloc(buf_size).expect("alloc");
31 Self { end: 0, inner, full: false }
32 }
33
34 pub fn dump<P: AsRef<Path>>(&self, file_path: P) -> Result<()> {
36 let mut file =
37 OpenOptions::new().write(true).create(true).truncate(true).open(file_path.as_ref())?;
38 if self.full {
39 file.write_all(&self.inner[self.end..])?;
40 return file.write_all(&self.inner[0..self.end]);
41 } else {
42 return file.write_all(&self.inner[0..self.end]);
43 }
44 }
45
46 #[inline]
47 pub fn clear(&mut self) {
48 self.end = 0;
49 self.full = false;
50 }
51}
52
53impl std::io::Write for RingBuffer {
54 #[inline]
57 fn write(&mut self, buf: &[u8]) -> Result<usize> {
58 let bound = self.inner.capacity();
59 let l = buf.len();
60 if self.end + l >= bound {
61 self.full = true;
62 let l1 = safe_copy(&mut self.inner[self.end..], &buf);
63 self.end = 0;
64 return Ok(l1);
65 } else {
66 safe_copy(&mut self.inner[self.end..], buf);
67 self.end += l;
68 return Ok(l);
69 }
70 }
71
72 #[inline]
73 fn flush(&mut self) -> Result<()> {
74 Ok(())
75 }
76}