use crate::{EncodingError, EncodingResult, SeekError};
#[allow(unused)]
fn usize_to_u64(val: usize) -> u64 {
val as _
}
#[allow(unused)]
fn isize_to_i64(val: isize) -> i64 {
val as _
}
#[allow(unused)]
fn u64_to_usize(val: u64) -> usize {
assert!(val <= isize::MAX as _);
val as _
}
#[allow(unused)]
fn i64_to_isize(val: i64) -> isize {
assert!(val <= isize::MAX as _);
val as _
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
fn io_err(err: EncodingError) -> std::io::Error {
match err {
EncodingError::IOError(error) => {
std::io::Error::from(<std::io::ErrorKind as From<_>>::from(error))
}
EncodingError::UnexpectedEnd => std::io::Error::from(std::io::ErrorKind::UnexpectedEof),
error => std::io::Error::new(std::io::ErrorKind::Other, error),
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
#[repr(transparent)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Std<T>(T);
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
impl<T> Std<T> {
#[inline]
pub fn new(stream: T) -> Self {
Self(stream)
}
#[inline]
pub fn inner(&self) -> &T {
&self.0
}
#[inline]
pub fn inner_mut(&mut self) -> &mut T {
&mut self.0
}
#[inline]
pub fn into_inner(self) -> T {
self.0
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
impl<T: Write> std::io::Write for Std<T> {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
<T as Write>::write(&mut self.0, buf).map_err(io_err)?;
Ok(buf.len())
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
impl<T: Read> std::io::Read for Std<T> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
<T as Read>::read(&mut self.0, buf).map_err(io_err)?;
Ok(buf.len())
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
impl<T: Seek> std::io::Seek for Std<T> {
#[inline]
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
let pos = match pos {
std::io::SeekFrom::Start(off) => SeekFrom::Start(u64_to_usize(off)),
std::io::SeekFrom::End(off) => SeekFrom::End(i64_to_isize(off)),
std::io::SeekFrom::Current(off) => SeekFrom::Current(i64_to_isize(off)),
};
match <T as Seek>::seek(&mut self.0, pos) {
Ok(off) => Ok(usize_to_u64(off)),
Err(err) => Err(io_err(err)),
}
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
impl<T: std::io::Write> Write for Std<T> {
#[inline]
fn write(&mut self, buf: &[u8]) -> EncodingResult<()> {
<T as std::io::Write>::write_all(&mut self.0, buf).map_err(Into::into)
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
impl<T: std::io::Read> Read for Std<T> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()> {
<T as std::io::Read>::read_exact(&mut self.0, buf).map_err(Into::into)
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "std")))]
impl<T: std::io::Seek> Seek for Std<T> {
#[inline]
fn seek(&mut self, seek: SeekFrom) -> EncodingResult<usize> {
let seek = match seek {
SeekFrom::Start(off) => std::io::SeekFrom::Start(usize_to_u64(off)),
SeekFrom::End(off) => std::io::SeekFrom::End(isize_to_i64(off)),
SeekFrom::Current(off) => std::io::SeekFrom::Current(isize_to_i64(off)),
};
match <T as std::io::Seek>::seek(&mut self.0, seek) {
Ok(off) => Ok(u64_to_usize(off)),
Err(x) => Err(x.into()),
}
}
}
#[derive(Eq, PartialEq, Debug)]
pub struct SliceMut<'data> {
slice: &'data mut [u8],
pos: usize,
}
impl<'data> SliceMut<'data> {
#[inline]
pub fn new(slice: &'data mut [u8]) -> Self {
Self { slice, pos: 0 }
}
#[inline]
pub fn inner(&self) -> &[u8] {
&self.slice
}
#[inline]
pub fn inner_mut(&mut self) -> &mut [u8] {
&mut self.slice
}
#[inline]
pub fn into_inner(self) -> &'data mut [u8] {
self.slice
}
}
impl Write for SliceMut<'_> {
#[inline]
fn write(&mut self, buf: &[u8]) -> EncodingResult<()> {
let rem = self.slice.len() - self.pos;
if buf.len() > rem {
return Err(EncodingError::UnexpectedEnd);
}
let sub = &mut self.slice[self.pos..(self.pos + buf.len())];
sub.copy_from_slice(buf);
self.pos += buf.len();
Ok(())
}
}
impl Read for SliceMut<'_> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()> {
let rem = self.slice.len() - self.pos;
if buf.len() > rem {
return Err(EncodingError::UnexpectedEnd);
}
let sub = &self.slice[self.pos..(self.pos + buf.len())];
buf.copy_from_slice(sub);
self.pos += buf.len();
Ok(())
}
}
impl Seek for SliceMut<'_> {
#[inline]
fn seek(&mut self, seek: SeekFrom) -> EncodingResult<usize> {
let offset = seek.as_buf_offset(self.pos, self.slice.len())?;
self.pos = offset;
Ok(offset)
}
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Slice<'data> {
slice: &'data [u8],
pos: usize,
}
impl<'data> Slice<'data> {
#[inline]
pub fn new(slice: &'data [u8]) -> Self {
Self { slice, pos: 0 }
}
#[inline]
pub fn inner(&self) -> &[u8] {
&self.slice
}
#[inline]
pub fn into_inner(self) -> &'data [u8] {
self.slice
}
}
impl Read for Slice<'_> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()> {
let rem = self.slice.len() - self.pos;
if buf.len() > rem {
return Err(EncodingError::UnexpectedEnd);
}
let sub = &self.slice[self.pos..(self.pos + buf.len())];
buf.copy_from_slice(sub);
self.pos += buf.len();
Ok(())
}
}
impl<'data> BorrowRead<'data> for Slice<'data> {
#[inline]
fn peek(&self, len: usize) -> EncodingResult<&'data [u8]> {
let rem = self.slice.len() - self.pos;
if len > rem {
return Err(EncodingError::UnexpectedEnd);
}
let sub = &self.slice[self.pos..(self.pos + len)];
Ok(sub)
}
#[inline]
fn borrow_read(&mut self, len: usize) -> EncodingResult<&'data [u8]> {
let rem = self.slice.len() - self.pos;
if len > rem {
return Err(EncodingError::UnexpectedEnd);
}
let sub = &self.slice[self.pos..(self.pos + len)];
self.pos += len;
Ok(sub)
}
}
impl Seek for Slice<'_> {
#[inline]
fn seek(&mut self, seek: SeekFrom) -> EncodingResult<usize> {
let offset = seek.as_buf_offset(self.pos, self.slice.len())?;
self.pos = offset;
Ok(offset)
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "alloc")))]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct VecStream {
vec: alloc::vec::Vec<u8>,
pos: usize,
limit: usize
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "alloc")))]
impl VecStream {
#[inline]
pub fn new(vec: alloc::vec::Vec<u8>, start: usize) -> Self {
let vec_len = vec.len();
let mut this = Self { vec, pos: start, limit: vec_len.max(start) };
this.ensure_capacity(this.pos);
this
}
#[inline]
pub fn inner(&self) -> &[u8] {
&self.vec[..self.limit]
}
#[inline]
pub fn into_inner(mut self) -> alloc::vec::Vec<u8> {
self.vec.truncate(self.limit);
self.vec
}
fn ensure_capacity(&mut self, at_least: usize) {
if at_least > self.vec.capacity() {
self.vec.reserve(at_least - self.vec.len());
for _ in self.vec.len()..self.vec.capacity() {
self.vec.push(0);
}
}
self.limit = self.limit.max(at_least);
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "alloc")))]
impl Write for VecStream {
#[inline]
fn write(&mut self, buf: &[u8]) -> EncodingResult<()> {
self.ensure_capacity(self.pos + buf.len());
let sub = &mut self.vec[self.pos..(self.pos + buf.len())];
sub.copy_from_slice(buf);
self.pos += buf.len();
Ok(())
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "alloc")))]
impl Read for VecStream {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()> {
self.ensure_capacity(self.pos + buf.len());
let sub = &self.vec[self.pos..(self.pos + buf.len())];
buf.copy_from_slice(sub);
self.pos += buf.len();
Ok(())
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "unstable", doc(cfg(feature = "alloc")))]
impl Seek for VecStream {
#[inline]
fn seek(&mut self, seek: SeekFrom) -> EncodingResult<usize> {
if let SeekFrom::End(_) = seek {
return Err(SeekError::UnknownRange.into());
}
let offset = seek.as_buf_offset(self.pos, 0)?;
self.ensure_capacity(offset);
self.pos = offset;
Ok(offset)
}
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct SizeTrack<T> {
stream: T,
wsize: usize,
rsize: usize,
}
impl<T> SizeTrack<T> {
#[inline]
pub fn new(stream: T) -> Self {
Self {
stream,
wsize: 0,
rsize: 0,
}
}
#[inline]
pub fn size_written(&self) -> usize {
self.wsize
}
#[inline]
pub fn size_read(&self) -> usize {
self.rsize
}
pub fn clear(&mut self) {
self.wsize = 0;
self.rsize = 0;
}
#[inline]
pub fn inner(&self) -> &T {
&self.stream
}
#[inline]
pub fn inner_mut(&mut self) -> &mut T {
&mut self.stream
}
#[inline]
pub fn into_inner(self) -> T {
self.stream
}
}
impl<T: Write> Write for SizeTrack<T> {
#[inline]
fn write(&mut self, buf: &[u8]) -> EncodingResult<()> {
let ok = self.stream.write(buf)?;
self.wsize += buf.len();
Ok(ok)
}
}
impl<T: Read> Read for SizeTrack<T> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()> {
let ok = self.stream.read(buf)?;
self.rsize += buf.len();
Ok(ok)
}
}
impl<'data, T: BorrowRead<'data>> BorrowRead<'data> for SizeTrack<T> {
#[inline]
fn peek(&self, len: usize) -> EncodingResult<&'data [u8]> {
self.stream.peek(len)
}
#[inline]
fn borrow_read(&mut self, len: usize) -> EncodingResult<&'data [u8]> {
let ok = self.stream.borrow_read(len)?;
self.rsize += len;
Ok(ok)
}
}
#[derive(Clone, Debug)]
pub struct SizeLimit<T> {
stream: T,
wsize: usize,
rsize: usize,
}
impl<T> SizeLimit<T> {
#[inline]
pub fn new(stream: T, write_limit: usize, read_limit: usize) -> Self {
Self {
stream,
wsize: write_limit,
rsize: read_limit,
}
}
#[inline]
pub fn remaining_writable(&self) -> usize {
self.wsize
}
#[inline]
pub fn remaining_readable(&self) -> usize {
self.rsize
}
#[inline]
pub fn inner(&self) -> &T {
&self.stream
}
#[inline]
pub fn inner_mut(&mut self) -> &mut T {
&mut self.stream
}
#[inline]
pub fn into_inner(self) -> T {
self.stream
}
}
impl<T: Write> Write for SizeLimit<T> {
#[inline]
fn write(&mut self, buf: &[u8]) -> EncodingResult<()> {
if buf.len() > self.wsize {
return Err(EncodingError::UnexpectedEnd);
}
let ok = self.stream.write(buf)?;
self.wsize -= buf.len();
Ok(ok)
}
}
impl<T: Read> Read for SizeLimit<T> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()> {
if buf.len() > self.rsize {
return Err(EncodingError::UnexpectedEnd);
}
let ok = self.stream.read(buf)?;
self.rsize -= buf.len();
Ok(ok)
}
}
impl<'data, T: BorrowRead<'data>> BorrowRead<'data> for SizeLimit<T> {
#[inline]
fn peek(&self, len: usize) -> EncodingResult<&'data [u8]> {
if len > self.rsize {
return Err(EncodingError::UnexpectedEnd);
}
self.stream.peek(len)
}
#[inline]
fn borrow_read(&mut self, len: usize) -> EncodingResult<&'data [u8]> {
if len > self.rsize {
return Err(EncodingError::UnexpectedEnd);
}
let ok = self.stream.borrow_read(len)?;
self.rsize -= len;
Ok(ok)
}
}
#[derive(Clone)]
pub struct Zero;
impl Write for Zero {
#[inline]
fn write(&mut self, _buf: &[u8]) -> EncodingResult<()> {
Ok(())
}
}
impl Read for Zero {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()> {
for x in buf {
*x = 0;
}
Ok(())
}
}
impl Seek for Zero {
#[inline]
fn seek(&mut self, _seek: SeekFrom) -> EncodingResult<usize> {
Ok(0)
}
}
pub trait Write {
fn write(&mut self, buf: &[u8]) -> EncodingResult<()>;
}
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()>;
}
pub trait BorrowRead<'data>: Read {
fn peek(&self, len: usize) -> EncodingResult<&'data [u8]>;
fn borrow_read(&mut self, len: usize) -> EncodingResult<&'data [u8]>;
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum SeekFrom {
Start(usize),
End(isize),
Current(isize),
}
impl SeekFrom {
pub const POSITION: Self = Self::Current(0);
#[inline]
pub const fn as_buf_offset(&self, pos: usize, len: usize) -> Result<usize, SeekError> {
assert!(pos <= isize::MAX as _);
assert!(len <= isize::MAX as _);
let offset = match *self {
SeekFrom::Start(off) => off as isize,
SeekFrom::End(off) => len as isize + off,
SeekFrom::Current(off) => pos as isize + off,
};
if offset > len as isize {
Err(SeekError::AfterEnd(offset as usize))
} else if offset < 0 {
Err(SeekError::BeforeBeginning(offset))
} else {
Ok(offset as usize)
}
}
}
pub trait Seek {
fn seek(&mut self, seek: SeekFrom) -> EncodingResult<usize>;
}
impl<T: Write> Write for &mut T {
#[inline]
fn write(&mut self, buf: &[u8]) -> EncodingResult<()> {
<T as Write>::write(self, buf)
}
}
impl<T: Read> Read for &mut T {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> EncodingResult<()> {
<T as Read>::read(self, buf)
}
}
impl<T: Seek> Seek for &mut T {
#[inline]
fn seek(&mut self, seek: SeekFrom) -> EncodingResult<usize> {
<T as Seek>::seek(self, seek)
}
}
impl<'data, T: BorrowRead<'data>> BorrowRead<'data> for &mut T {
#[inline]
fn peek(&self, len: usize) -> EncodingResult<&'data [u8]> {
<T as BorrowRead<'data>>::peek(self, len)
}
#[inline]
fn borrow_read(&mut self, len: usize) -> EncodingResult<&'data [u8]> {
<T as BorrowRead<'data>>::borrow_read(self, len)
}
}