use cl_generic_vec::{raw::Storage, ArrayVec, HeapVec, SimpleVec, SliceVec};
use std::{cmp, fmt, io, mem::MaybeUninit, ops::Deref};
pub trait Bytes: Storage<Item = u8> {}
impl<S: Storage<Item = u8>> Bytes for S {}
pub trait Read: io::Read {
fn read_buf(&mut self, buf: ReadBufRef<'_, impl Bytes>) -> io::Result<()> {
default_read_buf(|b| self.read(b), buf)
}
fn read_buf_exact(&mut self, mut buf: ReadBufRef<'_, impl Bytes>) -> io::Result<()> {
while buf.remaining() > 0 {
let prev_filled = buf.filled().len();
match Read::read_buf(self, buf.reborrow()) {
Ok(()) => {}
Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
}
if buf.filled().len() == prev_filled {
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"failed to fill buffer",
));
}
}
Ok(())
}
}
impl<R: io::Read> Read for R {}
pub(crate) fn default_read_buf<F>(read: F, mut buf: ReadBufRef<'_, impl Bytes>) -> io::Result<()>
where
F: FnOnce(&mut [u8]) -> io::Result<usize>,
{
let n = read(buf.initialize_unfilled())?;
buf.add_filled(n);
Ok(())
}
pub struct ReadBuf<S: Bytes> {
filled: usize,
buf: SimpleVec<S>,
}
impl<S: Bytes> fmt::Debug for ReadBuf<S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ReadBuf")
.field("init", &self.buf.len())
.field("filled", &self.filled)
.field("capacity", &self.buf.capacity())
.finish()
}
}
pub type ReadSlice<'a> = ReadBuf<&'a mut [MaybeUninit<u8>]>;
pub type ReadVec = ReadBuf<Box<[MaybeUninit<u8>]>>;
pub type ReadArray<const N: usize> = ReadBuf<[MaybeUninit<u8>; N]>;
impl<const N: usize> ReadArray<N> {
pub fn new_uninit_array() -> Self {
Self {
filled: 0,
buf: ArrayVec::new(),
}
}
}
impl<const N: usize> From<[u8; N]> for ReadArray<N> {
fn from(buf: [u8; N]) -> Self {
ReadBuf {
filled: 0,
buf: ArrayVec::from_array(buf),
}
}
}
impl From<Vec<u8>> for ReadVec {
fn from(buf: Vec<u8>) -> Self {
ReadBuf {
filled: 0,
buf: buf.into(),
}
}
}
impl From<Box<[MaybeUninit<u8>]>> for ReadVec {
fn from(buf: Box<[MaybeUninit<u8>]>) -> Self {
ReadBuf {
filled: 0,
buf: HeapVec::with_storage(buf),
}
}
}
impl<'a> From<&'a mut [u8]> for ReadSlice<'a> {
fn from(buf: &'a mut [u8]) -> Self {
ReadBuf {
filled: 0,
buf: SliceVec::full(buf),
}
}
}
impl<'a> From<&'a mut [MaybeUninit<u8>]> for ReadSlice<'a> {
fn from(buf: &'a mut [MaybeUninit<u8>]) -> Self {
ReadBuf {
filled: 0,
buf: unsafe { SliceVec::new(buf) },
}
}
}
impl<S: Bytes> ReadBuf<S> {
pub fn into_inner(self) -> SimpleVec<S> {
assert_eq!(self.filled, self.buf.len());
self.buf
}
#[inline]
pub fn borrow(&mut self) -> ReadBufRef<'_, S> {
ReadBufRef { read_buf: self }
}
#[inline]
pub fn capacity(&self) -> usize {
self.buf.capacity()
}
#[inline]
pub fn filled(&self) -> &[u8] {
&self.buf[..self.filled]
}
#[inline]
pub fn filled_mut(&mut self) -> &mut [u8] {
&mut self.buf[..self.filled]
}
#[inline]
pub fn initialized(&self) -> &[u8] {
self.buf.as_slice()
}
#[inline]
pub fn initialized_mut(&mut self) -> &mut [u8] {
self.buf.as_mut_slice()
}
#[inline]
pub unsafe fn unfilled_mut(&mut self) -> &mut [MaybeUninit<u8>] {
&mut self.buf.storage_mut().as_mut()[self.filled..]
}
#[inline]
pub fn uninitialized_mut(&mut self) -> &mut [MaybeUninit<u8>] {
self.buf.spare_capacity_mut()
}
#[inline]
pub fn initialize_unfilled(&mut self) -> &mut [u8] {
self.initialize_unfilled_to(self.remaining())
}
#[inline]
pub fn initialize_unfilled_to(&mut self, n: usize) -> &mut [u8] {
assert!(self.remaining() >= n);
let extra_init = self.buf.len() - self.filled;
if n > extra_init {
let uninit = n - extra_init;
let unfilled = &mut self.uninitialized_mut()[0..uninit];
for byte in unfilled.iter_mut() {
byte.write(0);
}
unsafe {
self.assume_init(n);
}
}
let filled = self.filled;
&mut self.initialized_mut()[filled..filled + n]
}
#[inline]
pub fn remaining(&self) -> usize {
self.capacity() - self.filled
}
#[inline]
pub fn clear(&mut self) {
self.set_filled(0); }
#[inline]
pub fn add_filled(&mut self, n: usize) {
self.set_filled(self.filled + n);
}
#[inline]
pub fn set_filled(&mut self, n: usize) {
assert!(n <= self.buf.len());
self.filled = n;
}
#[inline]
pub unsafe fn assume_init(&mut self, n: usize) {
self.buf
.set_len_unchecked(cmp::max(self.buf.len(), self.filled + n));
}
#[inline]
pub fn append(&mut self, buf: &[u8]) {
assert!(self.remaining() >= buf.len());
unsafe {
write_slice(&mut self.unfilled_mut()[..buf.len()], buf);
}
unsafe { self.assume_init(buf.len()) }
self.add_filled(buf.len());
}
#[inline]
pub fn filled_len(&self) -> usize {
self.filled
}
#[inline]
pub fn initialized_len(&self) -> usize {
self.buf.len()
}
}
unsafe fn write_slice<T>(this: &mut [MaybeUninit<T>], src: &[T])
where
T: Copy,
{
let uninit_src: &[MaybeUninit<T>] = core::mem::transmute(src);
this.copy_from_slice(uninit_src);
}
#[derive(Debug)]
pub struct ReadBufRef<'a, S: Bytes> {
read_buf: &'a mut ReadBuf<S>,
}
impl<'a, S: Bytes> ReadBufRef<'a, S> {
pub fn reborrow(&mut self) -> ReadBufRef<'_, S> {
ReadBufRef {
read_buf: self.read_buf,
}
}
#[inline]
pub fn filled_mut(&mut self) -> &mut [u8] {
self.read_buf.filled_mut()
}
#[inline]
pub fn initialized_mut(&mut self) -> &mut [u8] {
self.read_buf.initialized_mut()
}
#[inline]
pub unsafe fn unfilled_mut(&mut self) -> &mut [MaybeUninit<u8>] {
self.read_buf.unfilled_mut()
}
#[inline]
pub fn uninitialized_mut(&mut self) -> &mut [MaybeUninit<u8>] {
self.read_buf.uninitialized_mut()
}
#[inline]
pub fn initialize_unfilled(&mut self) -> &mut [u8] {
self.read_buf.initialize_unfilled()
}
#[inline]
pub fn initialize_unfilled_to(&mut self, n: usize) -> &mut [u8] {
self.read_buf.initialize_unfilled_to(n)
}
#[inline]
pub fn clear(&mut self) {
self.read_buf.clear()
}
#[inline]
pub fn add_filled(&mut self, n: usize) {
self.read_buf.add_filled(n)
}
#[inline]
pub fn set_filled(&mut self, n: usize) {
self.read_buf.set_filled(n)
}
#[inline]
pub unsafe fn assume_init(&mut self, n: usize) {
self.read_buf.assume_init(n)
}
#[inline]
pub fn append(&mut self, buf: &[u8]) {
self.read_buf.append(buf)
}
}
impl<'a, S: Bytes> Deref for ReadBufRef<'a, S> {
type Target = ReadBuf<S>;
fn deref(&self) -> &ReadBuf<S> {
&*self.read_buf
}
}