#[derive(Default)]
pub struct VecBuf {
buf: Vec<u8>,
wrote: usize,
read: usize,
min_write: usize,
}
impl VecBuf {
#[inline]
pub fn len(&self) -> usize {
self.wrote - self.read
}
#[inline]
pub fn is_empty(&self) -> bool {
self.read >= self.wrote
}
pub fn capacity(&self) -> usize {
self.buf.len() - self.len()
}
#[inline]
pub fn data(&self) -> &[u8] {
&self.buf[self.read..self.wrote]
}
pub fn prepare(&mut self, amt: usize) -> &mut [u8] {
self.reserve(amt);
&mut self.buf[self.wrote..self.wrote + amt]
}
pub fn prepare_at_least(&mut self, amt: usize) -> &mut [u8] {
self.reserve(amt);
&mut self.buf[self.wrote..]
}
#[inline]
pub fn commit(&mut self, amt: usize) {
debug_assert!(self.wrote + amt <= self.buf.len());
self.wrote += amt
}
#[inline]
pub fn consume(&mut self, amt: usize) {
debug_assert!(amt <= self.len());
if amt >= self.len() {
self.wrote = 0;
self.read = 0;
} else {
self.read += amt;
}
}
}
impl VecBuf {
pub fn new(min_write: usize) -> Self {
Self {
min_write,
..Default::default()
}
}
pub fn reserve(&mut self, amt: usize) {
let amt = amt.max(if self.buf.is_empty() {
self.min_write * 2
} else {
self.min_write
});
if self.buf.len() < self.wrote + amt {
if self.buf.len() >= self.len() + amt {
self.move_data_to_front();
return;
}
self.grow(amt);
}
}
fn move_data_to_front(&mut self) {
self.buf.copy_within(self.read..self.wrote, 0);
self.wrote -= self.read;
self.read = 0;
}
pub fn grow(&mut self, amt: usize) {
self.buf.reserve(amt.max(self.buf.len()));
self.buf.resize(self.buf.capacity(), 0);
}
pub fn write_all(&mut self, buf: &[u8]) {
self.prepare(buf.len()).copy_from_slice(buf);
self.commit(buf.len());
}
pub fn into_vec(mut self) -> Vec<u8> {
if self.read > 0 {
self.move_data_to_front();
}
self.buf.truncate(self.wrote);
self.buf
}
}