use crate::{cmp, convert::TryInto, mem, vec::Vec};
mod error;
pub use error::*;
pub mod prelude {
pub use super::{Read, Result, Write};
}
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
while !buf.is_empty() {
match self.read(buf) {
Ok(0) => break,
Ok(n) => {
let tmp = buf;
buf = &mut tmp[n..];
},
Err(ref e) if e.kind() == ErrorKind::Interrupted => {},
Err(e) => return Err(e),
}
}
if !buf.is_empty() {
Err(Error::new(
ErrorKind::UnexpectedEof,
"failed to fill whole buffer",
))
} else {
Ok(())
}
}
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
}
pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn flush(&mut self) -> Result<()>;
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => {
return Err(Error::new(
ErrorKind::WriteZero,
"failed to write whole buffer",
))
},
Ok(n) => buf = &buf[n..],
Err(ref e) if e.kind() == ErrorKind::Interrupted => {},
Err(e) => return Err(e),
}
}
Ok(())
}
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
}
impl<R: Read + ?Sized> Read for &mut R {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
(**self).read(buf)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
(**self).read_exact(buf)
}
}
impl Read for &[u8] {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let amt = cmp::min(buf.len(), self.len());
let (a, b) = self.split_at(amt);
if amt == 1 {
buf[0] = a[0];
} else {
buf[..amt].copy_from_slice(a);
}
*self = b;
Ok(amt)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
if buf.len() > self.len() {
return Err(Error::new(
ErrorKind::UnexpectedEof,
"failed to fill whole buffer",
));
}
let (a, b) = self.split_at(buf.len());
if buf.len() == 1 {
buf[0] = a[0];
} else {
buf.copy_from_slice(a);
}
*self = b;
Ok(())
}
}
impl<W: Write + ?Sized> Write for &mut W {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
(**self).write(buf)
}
#[inline]
fn flush(&mut self) -> Result<()> {
(**self).flush()
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
(**self).write_all(buf)
}
}
impl Write for &mut [u8] {
fn write(&mut self, data: &[u8]) -> Result<usize> {
let amt = cmp::min(data.len(), self.len());
let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
a.copy_from_slice(&data[..amt]);
*self = b;
Ok(amt)
}
#[inline]
fn write_all(&mut self, data: &[u8]) -> Result<()> {
if self.write(data)? == data.len() {
Ok(())
} else {
Err(Error::new(
ErrorKind::WriteZero,
"failed to write whole buffer",
))
}
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl Write for Vec<u8> {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.extend_from_slice(buf);
Ok(buf.len())
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.extend_from_slice(buf);
Ok(())
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
pub struct Cursor<T> {
inner: T,
pos: u64,
}
impl<T> Cursor<T> {
pub fn new(inner: T) -> Self {
Cursor { inner, pos: 0 }
}
pub fn into_inner(self) -> T {
self.inner
}
pub fn get_ref(&self) -> &T {
&self.inner
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
pub fn position(&self) -> u64 {
self.pos
}
pub fn set_position(&mut self, pos: u64) {
self.pos = pos;
}
}
impl<T> Read for Cursor<T>
where
T: AsRef<[u8]>,
{
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let n = Read::read(&mut self.get_buf()?, buf)?;
self.pos += n as u64;
Ok(n)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
let n = buf.len();
Read::read_exact(&mut self.get_buf()?, buf)?;
self.pos += n as u64;
Ok(())
}
}
impl<T> Cursor<T>
where
T: AsRef<[u8]>,
{
fn get_buf(&mut self) -> Result<&[u8]> {
let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
Ok(&self.inner.as_ref()[(amt as usize)..])
}
}
impl Write for Cursor<&mut [u8]> {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
slice_write(&mut self.pos, self.inner, buf)
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl Write for Cursor<Vec<u8>> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
vec_write(&mut self.pos, &mut self.inner, buf)
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
#[inline]
fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> Result<usize> {
let pos = cmp::min(*pos_mut, slice.len() as u64);
let amt = (&mut slice[(pos as usize)..]).write(buf)?;
*pos_mut += amt as u64;
Ok(amt)
}
fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> Result<usize> {
let pos: usize = (*pos_mut).try_into().map_err(|_| {
Error::new(
ErrorKind::InvalidInput,
"cursor position exceeds maximum possible vector length",
)
})?;
let len = vec.len();
if len < pos {
vec.resize(pos, 0);
}
{
let space = vec.len() - pos;
let (left, right) = buf.split_at(cmp::min(space, buf.len()));
vec[pos..pos + left.len()].copy_from_slice(left);
vec.extend_from_slice(right);
}
*pos_mut = (pos + buf.len()) as u64;
Ok(buf.len())
}