use crate::error::Error;
use alloc::vec::Vec;
pub(super) fn feed(
buf: &mut Vec<u8>,
pending: usize,
max: usize,
data: &[u8],
) -> Result<(), Error> {
debug_assert!(pending == 0, "feed called with pending mut_buf");
let new_size = buf
.len()
.checked_add(data.len())
.ok_or(Error::BufferOverflow {
size: usize::MAX,
limit: max,
})?;
if new_size > max {
return Err(Error::BufferOverflow {
size: new_size,
limit: max,
});
}
buf.extend_from_slice(data);
Ok(())
}
pub(super) fn feed_unchecked(buf: &mut Vec<u8>, pending: usize, data: &[u8]) {
debug_assert!(pending == 0, "feed_unchecked called with pending mut_buf");
buf.extend_from_slice(data);
}
pub(super) fn mut_buf<'a>(
buf: &'a mut Vec<u8>,
pending: &mut usize,
max: usize,
len: usize,
) -> Result<&'a mut [u8], Error> {
if *pending > 0 {
let new_len = buf.len() - *pending;
buf.truncate(new_len);
*pending = 0;
}
let new_size = buf.len().checked_add(len).ok_or(Error::BufferOverflow {
size: usize::MAX,
limit: max,
})?;
if new_size > max {
return Err(Error::BufferOverflow {
size: new_size,
limit: max,
});
}
let old = buf.len();
buf.resize(new_size, 0);
*pending = len;
Ok(&mut buf[old..])
}
pub(super) fn advance_buf(buf: &mut Vec<u8>, pending: &mut usize, len: usize) {
debug_assert!(len <= *pending, "advance_buf len exceeds pending");
let len = len.min(*pending);
let drop = *pending - len;
if drop > 0 {
let new_len = buf.len() - drop;
buf.truncate(new_len);
}
*pending = 0;
}
pub(super) fn available_buf(buf: &[u8], max: usize) -> usize {
max.saturating_sub(buf.len())
}
pub(super) fn remaining(buf: &[u8], pending: usize) -> &[u8] {
debug_assert!(pending == 0, "remaining called with pending mut_buf");
buf
}