use core::{
marker::PhantomData,
mem,
num::NonZeroUsize,
option,
slice::{self},
};
use crate::{
buffer::{Buffer, SplitBuffer},
reader::{BacktrackableReader, DidntRead, DidntSiphon, HasReader, Reader, SiphonableReader},
writer::{BacktrackableWriter, DidntWrite, HasWriter, Writer},
ZBuf, ZSlice,
};
impl Buffer for &[u8] {
#[inline(always)]
fn len(&self) -> usize {
<[u8]>::len(self)
}
}
impl Buffer for &mut [u8] {
#[inline(always)]
fn len(&self) -> usize {
<[u8]>::len(self)
}
}
impl<'b> SplitBuffer for &'b [u8] {
type Slices<'a>
= option::IntoIter<&'a [u8]>
where
'b: 'a;
fn slices(&self) -> Self::Slices<'_> {
Some(*self).into_iter()
}
}
impl HasWriter for &mut [u8] {
type Writer = Self;
fn writer(self) -> Self::Writer {
self
}
}
impl Writer for &mut [u8] {
#[inline(always)]
fn write(&mut self, bytes: &[u8]) -> Result<NonZeroUsize, DidntWrite> {
let Some(len) = NonZeroUsize::new(bytes.len().min(self.len())) else {
return Err(DidntWrite);
};
let (to_write, remain) = mem::take(self).split_at_mut(len.get());
to_write.copy_from_slice(&bytes[..len.get()]);
*self = remain;
Ok(len)
}
#[inline(always)]
fn write_exact(&mut self, bytes: &[u8]) -> Result<(), DidntWrite> {
let len = bytes.len();
if self.len() < len {
return Err(DidntWrite);
}
let _ = self.write(bytes);
Ok(())
}
fn remaining(&self) -> usize {
self.len()
}
unsafe fn with_slot<F>(&mut self, len: usize, write: F) -> Result<NonZeroUsize, DidntWrite>
where
F: FnOnce(&mut [u8]) -> usize,
{
if len > self.len() {
return Err(DidntWrite);
}
let written = write(&mut self[..len]);
*self = unsafe { mem::take(self).get_unchecked_mut(written..) };
NonZeroUsize::new(written).ok_or(DidntWrite)
}
}
pub struct SliceMark<'s> {
ptr: *const u8,
len: usize,
_phantom: PhantomData<&'s u8>,
}
impl<'s> BacktrackableWriter for &'s mut [u8] {
type Mark = SliceMark<'s>;
fn mark(&mut self) -> Self::Mark {
SliceMark {
ptr: self.as_ptr(),
len: self.len(),
_phantom: PhantomData,
}
}
fn rewind(&mut self, mark: Self::Mark) -> bool {
*self = unsafe { slice::from_raw_parts_mut(mark.ptr as *mut u8, mark.len) };
true
}
}
impl HasReader for &[u8] {
type Reader = Self;
fn reader(self) -> Self::Reader {
self
}
}
impl Reader for &[u8] {
#[inline(always)]
fn read(&mut self, into: &mut [u8]) -> Result<NonZeroUsize, DidntRead> {
let Some(len) = NonZeroUsize::new(self.len().min(into.len())) else {
return Err(DidntRead);
};
let (to_write, remain) = self.split_at(len.get());
into[..len.get()].copy_from_slice(to_write);
*self = remain;
Ok(len)
}
#[inline(always)]
fn read_exact(&mut self, into: &mut [u8]) -> Result<(), DidntRead> {
let len = into.len();
if self.len() < len {
return Err(DidntRead);
}
let (to_write, remain) = self.split_at(len);
into[..len].copy_from_slice(to_write);
*self = remain;
Ok(())
}
fn remaining(&self) -> usize {
self.len()
}
fn read_zbuf(&mut self, len: usize) -> Result<ZBuf, DidntRead> {
Ok(self.read_zslice(len)?.into())
}
fn read_zslices<F: FnMut(ZSlice)>(&mut self, len: usize, mut f: F) -> Result<(), DidntRead> {
let zslice = self.read_zslice(len)?;
f(zslice);
Ok(())
}
fn read_zslice(&mut self, len: usize) -> Result<ZSlice, DidntRead> {
let mut buffer = crate::vec::uninit(len);
self.read_exact(&mut buffer)?;
Ok(buffer.into())
}
#[inline(always)]
fn read_u8(&mut self) -> Result<u8, DidntRead> {
let mut buf = [0; 1];
self.read(&mut buf)?;
Ok(buf[0])
}
fn can_read(&self) -> bool {
!self.is_empty()
}
}
impl<'a> BacktrackableReader for &'a [u8] {
type Mark = &'a [u8];
fn mark(&mut self) -> Self::Mark {
self
}
fn rewind(&mut self, mark: Self::Mark) -> bool {
*self = mark;
true
}
}
impl SiphonableReader for &[u8] {
fn siphon<W>(&mut self, writer: &mut W) -> Result<NonZeroUsize, DidntSiphon>
where
W: Writer,
{
let res = writer.write(self).map_err(|_| DidntSiphon);
if let Ok(len) = res {
*self = crate::unsafe_slice!(self, len.get()..);
}
res
}
}