117 lines
2.1 KiB
Rust
117 lines
2.1 KiB
Rust
use std::io::{Read, Result as IOResult};
|
|
|
|
pub struct NotEnoughSpace;
|
|
pub struct Buf<T, U> {
|
|
written_len: usize,
|
|
data: T,
|
|
_dt: core::marker::PhantomData<U>,
|
|
}
|
|
impl<T, U> Buf<T, U> {
|
|
pub fn new(data: T) -> Self {
|
|
Self {
|
|
data,
|
|
written_len: 0,
|
|
_dt: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T, U> Buf<T, U>
|
|
where
|
|
T: AsRef<[U]>,
|
|
{
|
|
pub fn remaining(&self) -> &[U] {
|
|
&self.data.as_ref()[self.written_len..]
|
|
}
|
|
|
|
pub fn filled(&self) -> &[U] {
|
|
&self.data.as_ref()[..self.written_len]
|
|
}
|
|
}
|
|
|
|
impl<T, U> Buf<T, U>
|
|
where
|
|
T: AsRef<[U]>,
|
|
T: AsMut<[U]>,
|
|
{
|
|
pub fn remaining_mut(&mut self) -> &mut [U] {
|
|
&mut self.data.as_mut()[self.written_len..]
|
|
}
|
|
|
|
pub fn extend_from_slice(&mut self, s: &[U]) -> Result<(), NotEnoughSpace>
|
|
where
|
|
U: Copy,
|
|
{
|
|
if self.remaining().len() < s.len() {
|
|
return Err(NotEnoughSpace);
|
|
}
|
|
|
|
self.remaining_mut()[..s.len()].copy_from_slice(s);
|
|
self.written_len += s.len();
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn clear(&mut self) {
|
|
self.written_len = 0;
|
|
}
|
|
|
|
pub fn pop_front_alloc(&mut self, amt: usize)
|
|
where
|
|
U: Copy + Default,
|
|
{
|
|
let to_copy = &self.filled()[amt..];
|
|
let buf_sz = to_copy.len();
|
|
let mut buf = vec![Default::default(); buf_sz].into_boxed_slice();
|
|
buf.copy_from_slice(to_copy);
|
|
self.clear();
|
|
let _ = self.extend_from_slice(&buf);
|
|
}
|
|
|
|
pub fn pop_front(&mut self, amt: usize)
|
|
where
|
|
U: Copy,
|
|
{
|
|
if amt > self.filled().len() {
|
|
panic!("Filled not big enough");
|
|
}
|
|
|
|
let data = self.data.as_mut();
|
|
|
|
let src = &data[amt..];
|
|
let count = data.len() - amt;
|
|
|
|
// SAFETY:
|
|
// - src comes from data
|
|
// - U is copy
|
|
// - count is within bounds of data
|
|
unsafe { core::ptr::copy(src.as_ptr(), data.as_mut_ptr(), count) }
|
|
|
|
self.written_len -= amt;
|
|
}
|
|
}
|
|
|
|
impl<T> Buf<T, u8>
|
|
where
|
|
T: AsRef<[u8]> + AsMut<[u8]>,
|
|
{
|
|
pub fn read_from(&mut self, mut r: impl Read) -> IOResult<usize> {
|
|
let remaining = self.remaining_mut();
|
|
let amt = r.read(remaining)?;
|
|
|
|
self.written_len += amt;
|
|
|
|
Ok(amt)
|
|
}
|
|
}
|
|
|
|
impl<T> httplz::Write for Buf<T, u8>
|
|
where
|
|
T: AsRef<[u8]> + AsMut<[u8]>,
|
|
{
|
|
fn write(&mut self, buf: &[u8]) -> httplz::Written {
|
|
self.extend_from_slice(buf)
|
|
.map_err(|_| httplz::ErrorKind::BufNotBigEnough.into())
|
|
}
|
|
}
|