use io_buffer::{safe_copy, Buffer};
use std::fs::*;
use std::io::{Result, Write};
use std::path::Path;
pub struct RingBuffer {
end: usize,
full: bool,
inner: Buffer,
}
impl RingBuffer {
pub fn new(buf_size: i32) -> Self {
assert!(buf_size > 0);
let inner = Buffer::alloc(buf_size).expect("alloc");
Self { end: 0, inner, full: false }
}
pub fn dump<P: AsRef<Path>>(&self, file_path: P) -> Result<()> {
let mut file =
OpenOptions::new().write(true).create(true).truncate(true).open(file_path.as_ref())?;
if self.full {
file.write_all(&self.inner[self.end..])?;
return file.write_all(&self.inner[0..self.end]);
} else {
return file.write_all(&self.inner[0..self.end]);
}
}
#[inline]
pub fn clear(&mut self) {
self.end = 0;
self.full = false;
}
}
impl std::io::Write for RingBuffer {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let bound = self.inner.capacity();
let l = buf.len();
if self.end + l >= bound {
self.full = true;
let l1 = safe_copy(&mut self.inner[self.end..], &buf);
self.end = 0;
return Ok(l1);
} else {
safe_copy(&mut self.inner[self.end..], buf);
self.end += l;
return Ok(l);
}
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}