use crate::util::ConsumeBuf;
pub trait Buffers {
fn output(&mut self) -> &mut [u8];
fn input(&self) -> &[u8];
fn input_append_buf(&mut self) -> &mut [u8];
fn input_appended(&mut self, amount: usize);
fn input_consume(&mut self, amount: usize);
fn tmp_and_output(&mut self) -> (&mut [u8], &mut [u8]);
fn can_use_input(&self) -> bool;
}
#[derive(Debug)]
pub struct LazyBuffers {
input_size: usize,
output_size: usize,
input: ConsumeBuf,
output: Vec<u8>,
progress: bool,
}
impl LazyBuffers {
pub fn new(input_size: usize, output_size: usize) -> Self {
assert!(input_size > 0);
assert!(output_size > 0);
LazyBuffers {
input_size,
output_size,
input: ConsumeBuf::new(0),
output: vec![],
progress: false,
}
}
fn ensure_allocation(&mut self) {
if self.output.len() < self.output_size {
self.output.resize(self.output_size, 0);
}
if self.input.unconsumed().len() < self.input_size {
self.input.resize(self.input_size);
}
}
}
impl Buffers for LazyBuffers {
fn output(&mut self) -> &mut [u8] {
self.ensure_allocation();
&mut self.output
}
fn input(&self) -> &[u8] {
self.input.unconsumed()
}
fn input_append_buf(&mut self) -> &mut [u8] {
self.ensure_allocation();
self.input.free_mut()
}
fn tmp_and_output(&mut self) -> (&mut [u8], &mut [u8]) {
self.ensure_allocation();
const MIN_TMP_SIZE: usize = 10 * 1024;
let tmp_available = self.input.free_mut().len();
if tmp_available < MIN_TMP_SIZE {
let needed = MIN_TMP_SIZE - tmp_available;
self.input.resize(self.input.unconsumed().len() + needed);
}
(self.input.free_mut(), &mut self.output)
}
fn input_appended(&mut self, amount: usize) {
self.input.add_filled(amount);
}
fn input_consume(&mut self, amount: usize) {
self.progress = amount > 0;
self.input.consume(amount);
}
fn can_use_input(&self) -> bool {
!self.input.unconsumed().is_empty() && self.progress
}
}