use core::{cmp, fmt, mem, slice};
#[cfg(feature = "alloc")]
use alloc::{string::String, vec::Vec};
#[cfg(feature = "alloc")]
use crate::{io_alloc, Lines, Split};
use crate::{Error, ErrorKind, IoSlice, IoSliceMut, Result};
pub(crate) fn default_read_vectored<F>(read: F, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>
where
F: FnOnce(&mut [u8]) -> Result<usize>,
{
let buf = bufs
.iter_mut()
.find(|b| !b.is_empty())
.map_or(&mut [][..], |b| &mut **b);
read(buf)
}
pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [u8]) -> Result<()> {
while !buf.is_empty() {
match this.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_const(
ErrorKind::UnexpectedEof,
&"failed to fill whole buffer",
))
} else {
Ok(())
}
}
pub struct Bytes<R> {
inner: R,
}
impl<R: Read> Iterator for Bytes<R> {
type Item = Result<u8>;
fn next(&mut self) -> Option<Result<u8>> {
let mut byte = 0;
loop {
return match self.inner.read(slice::from_mut(&mut byte)) {
Ok(0) => None,
Ok(..) => Some(Ok(byte)),
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => Some(Err(e)),
};
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
Read::size_hint(&self.inner)
}
}
#[derive(Debug)]
pub struct Take<T> {
inner: T,
limit: u64,
}
impl<T> Take<T> {
pub fn limit(&self) -> u64 {
self.limit
}
pub fn set_limit(&mut self, limit: u64) {
self.limit = limit;
}
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
}
}
impl<T: Read> Read for Take<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
if self.limit == 0 {
return Ok(0);
}
let max = cmp::min(buf.len() as u64, self.limit) as usize;
let n = self.inner.read(&mut buf[..max])?;
self.limit -= n as u64;
Ok(n)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (min, max) = self.inner.size_hint();
(
cmp::min(self.limit, min as u64) as usize,
max.map(|x| cmp::min(x as u64, self.limit) as usize)
.or_else(|| self.limit.try_into().ok()),
)
}
}
impl<T: BufRead> BufRead for Take<T> {
fn fill_buf(&mut self) -> Result<&[u8]> {
if self.limit == 0 {
return Ok(&[]);
}
let buf = self.inner.fill_buf()?;
let cap = cmp::min(buf.len() as u64, self.limit) as usize;
Ok(&buf[..cap])
}
fn consume(&mut self, amt: usize) {
let amt = cmp::min(amt as u64, self.limit) as usize;
self.limit -= amt as u64;
self.inner.consume(amt);
}
}
#[derive(Debug)]
pub struct Chain<T, U> {
first: T,
second: U,
done_first: bool,
}
impl<T, U> Chain<T, U> {
pub fn into_inner(self) -> (T, U) {
(self.first, self.second)
}
pub fn get_ref(&self) -> (&T, &U) {
(&self.first, &self.second)
}
pub fn get_mut(&mut self) -> (&mut T, &mut U) {
(&mut self.first, &mut self.second)
}
}
impl<T: Read, U: Read> Read for Chain<T, U> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
if !self.done_first {
match self.first.read(buf)? {
0 if !buf.is_empty() => self.done_first = true,
n => return Ok(n),
}
}
self.second.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
if !self.done_first {
match self.first.read_vectored(bufs)? {
0 if bufs.iter().any(|b| !b.is_empty()) => self.done_first = true,
n => return Ok(n),
}
}
self.second.read_vectored(bufs)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (min1, max1) = self.first.size_hint();
let (min2, max2) = self.second.size_hint();
(
min1 + min2,
max1.map(|x| max2.map(|y| x.checked_add(y)).flatten())
.flatten(),
)
}
}
impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
fn fill_buf(&mut self) -> Result<&[u8]> {
if !self.done_first {
match self.first.fill_buf()? {
buf if buf.is_empty() => {
self.done_first = true;
}
buf => return Ok(buf),
}
}
self.second.fill_buf()
}
fn consume(&mut self, amt: usize) {
if !self.done_first {
self.first.consume(amt)
} else {
self.second.consume(amt)
}
}
}
pub trait Read {
fn read(&mut self, dst: &mut [u8]) -> Result<usize>;
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
default_read_vectored(|b| self.read(b), bufs)
}
#[doc(hidden)]
fn is_read_vectored(&self) -> bool {
false
}
#[cfg(feature = "alloc")]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
io_alloc::default_read_to_end(self, buf)
}
#[cfg(feature = "alloc")]
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
io_alloc::default_read_to_string(self, buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
default_read_exact(self, buf)
}
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
fn bytes(self) -> Bytes<Self>
where
Self: Sized,
{
Bytes { inner: self }
}
fn chain<R: Read>(self, next: R) -> Chain<Self, R>
where
Self: Sized,
{
Chain {
first: self,
second: next,
done_first: false,
}
}
fn take(self, limit: u64) -> Take<Self>
where
Self: Sized,
{
Take { inner: self, limit }
}
#[doc(hidden)]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<R: Read> Read for &mut R {
fn read(&mut self, dst: &mut [u8]) -> Result<usize> {
(*self).read(dst)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
(*self).read_exact(buf)
}
}
impl Read for &[u8] {
#[inline]
fn read(&mut self, dst: &mut [u8]) -> Result<usize> {
let copy_len = cmp::min(dst.len(), self.len());
let (src, rem) = self.split_at(copy_len);
if copy_len == 1 {
dst[0] = src[0];
} else {
dst[..copy_len].copy_from_slice(src);
}
*self = rem;
Ok(copy_len)
}
#[inline]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
let mut nread = 0;
for buf in bufs {
nread += self.read(buf)?;
if self.is_empty() {
break;
}
}
Ok(nread)
}
#[inline]
fn is_read_vectored(&self) -> bool {
true
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
if buf.len() > self.len() {
return Err(Error::new_const(
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(())
}
#[inline]
#[cfg(feature = "alloc")]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
buf.extend_from_slice(*self);
let len = self.len();
*self = &self[len..];
Ok(len)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}
pub trait BufRead {
fn fill_buf(&mut self) -> Result<&[u8]>;
fn consume(&mut self, amt: usize);
#[cfg(feature = "alloc")]
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
io_alloc::read_until(self, byte, buf)
}
#[cfg(feature = "alloc")]
fn read_line(&mut self, buf: &mut String) -> Result<usize> {
unsafe { io_alloc::append_to_string(buf, |b| io_alloc::read_until(self, b'\n', b)) }
}
#[cfg(feature = "alloc")]
fn split(self, byte: u8) -> Split<Self>
where
Self: Sized,
{
Split {
buf: self,
delim: byte,
}
}
#[cfg(feature = "alloc")]
fn lines(self) -> Lines<Self>
where
Self: Sized,
{
Lines { buf: self }
}
}
impl BufRead for &[u8] {
#[inline]
fn fill_buf(&mut self) -> Result<&[u8]> {
Ok(*self)
}
#[inline]
fn consume(&mut self, amt: usize) {
*self = &self[amt..]
}
}
impl<B: BufRead + ?Sized> BufRead for &mut B {
#[inline]
fn fill_buf(&mut self) -> Result<&[u8]> {
(**self).fill_buf()
}
#[inline]
fn consume(&mut self, amt: usize) {
(**self).consume(amt)
}
#[cfg(feature = "alloc")]
#[inline]
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
(**self).read_until(byte, buf)
}
#[cfg(feature = "alloc")]
#[inline]
fn read_line(&mut self, buf: &mut String) -> Result<usize> {
(**self).read_line(buf)
}
}
impl<T> BufRead for Cursor<T>
where
T: AsRef<[u8]>,
{
fn fill_buf(&mut self) -> Result<&[u8]> {
Ok(self.remaining_slice())
}
fn consume(&mut self, amt: usize) {
self.pos += amt as u64;
}
}
pub(crate) fn default_write_vectored<F>(write: F, bufs: &[IoSlice<'_>]) -> Result<usize>
where
F: FnOnce(&[u8]) -> Result<usize>,
{
let buf = bufs
.iter()
.find(|b| !b.is_empty())
.map_or(&[][..], |b| &**b);
write(buf)
}
pub trait Write {
fn write(&mut self, src: &[u8]) -> Result<usize>;
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
default_write_vectored(|b| self.write(b), bufs)
}
#[doc(hidden)]
fn is_write_vectored(&self) -> bool {
false
}
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_const(
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(())
}
#[doc(hidden)]
fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
IoSlice::advance_slices(&mut bufs, 0);
while !bufs.is_empty() {
match self.write_vectored(bufs) {
Ok(0) => {
return Err(Error::new_const(
ErrorKind::WriteZero,
&"failed to write whole buffer",
));
}
Ok(n) => IoSlice::advance_slices(&mut bufs, n),
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
struct Adapter<'a, T: ?Sized + 'a> {
inner: &'a mut T,
error: Result<()>,
}
impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
match self.inner.write_all(s.as_bytes()) {
Ok(()) => Ok(()),
Err(e) => {
self.error = Err(e);
Err(fmt::Error)
}
}
}
}
let mut output = Adapter {
inner: self,
error: Ok(()),
};
match fmt::write(&mut output, fmt) {
Ok(()) => Ok(()),
Err(..) => {
if output.error.is_err() {
output.error
} else {
Err(Error::new_const(
ErrorKind::Uncategorized,
&"formatter error",
))
}
}
}
}
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
}
impl Write for &mut [u8] {
#[inline]
fn write(&mut self, src: &[u8]) -> Result<usize> {
let copy_len = cmp::min(src.len(), self.len());
let (dst, rem) = mem::take(self).split_at_mut(copy_len);
dst.copy_from_slice(&src[..copy_len]);
*self = rem;
Ok(copy_len)
}
#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
let mut nwritten = 0;
for buf in bufs {
nwritten += self.write(buf)?;
if self.is_empty() {
break;
}
}
Ok(nwritten)
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn write_all(&mut self, data: &[u8]) -> Result<()> {
if self.write(data)? == data.len() {
Ok(())
} else {
Err(Error::new_const(
ErrorKind::WriteZero,
&"failed to write whole buffer",
))
}
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SeekFrom {
Start(u64),
End(i64),
Current(i64),
}
pub trait Seek {
fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
fn rewind(&mut self) -> Result<()> {
self.seek(SeekFrom::Start(0))?;
Ok(())
}
fn stream_len(&mut self) -> Result<u64> {
let old_pos = self.stream_position()?;
let len = self.seek(SeekFrom::End(0))?;
if old_pos != len {
self.seek(SeekFrom::Start(old_pos))?;
}
Ok(len)
}
fn stream_position(&mut self) -> Result<u64> {
self.seek(SeekFrom::Current(0))
}
}
#[derive(Debug, Default, Eq, PartialEq)]
pub struct Cursor<T> {
pub(crate) inner: T,
pub(crate) pos: u64,
}
impl<T> Cursor<T> {
pub const fn new(inner: T) -> Cursor<T> {
Cursor { inner, pos: 0 }
}
pub fn into_inner(self) -> T {
self.inner
}
pub const fn get_ref(&self) -> &T {
&self.inner
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
pub const fn position(&self) -> u64 {
self.pos
}
pub fn set_position(&mut self, pos: u64) {
self.pos = pos;
}
}
impl<T> Cursor<T>
where
T: AsRef<[u8]>,
{
pub fn remaining_slice(&self) -> &[u8] {
let len = self.pos.min(self.inner.as_ref().len() as u64);
&self.inner.as_ref()[(len as usize)..]
}
pub fn is_empty(&self) -> bool {
self.pos >= self.inner.as_ref().len() as u64
}
}
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.remaining_slice(), buf)?;
self.pos += n as u64;
Ok(n)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
let mut nread = 0;
for buf in bufs {
let n = self.read(buf)?;
nread += n;
if n < buf.len() {
break;
}
}
Ok(nread)
}
fn is_read_vectored(&self) -> bool {
true
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
let n = buf.len();
Read::read_exact(&mut self.remaining_slice(), buf)?;
self.pos += n as u64;
Ok(())
}
}
#[inline]
pub(crate) 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)
}
#[inline]
pub(crate) fn slice_write_vectored(
pos_mut: &mut u64,
slice: &mut [u8],
bufs: &[IoSlice<'_>],
) -> Result<usize> {
let mut nwritten = 0;
for buf in bufs {
let n = slice_write(pos_mut, slice, buf)?;
nwritten += n;
if n < buf.len() {
break;
}
}
Ok(nwritten)
}
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 write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
slice_write_vectored(&mut self.pos, self.inner, bufs)
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl<A> Seek for Cursor<A>
where
A: AsRef<[u8]>,
{
fn seek(&mut self, style: SeekFrom) -> Result<u64> {
let (base_pos, offset) = match style {
SeekFrom::Start(n) => {
self.pos = n;
return Ok(n);
}
SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n),
SeekFrom::Current(n) => (self.pos, n),
};
let end_pos = {
let (p, overflowed) = base_pos.overflowing_add(offset as u64);
if overflowed ^ (offset < 0) {
None
} else {
Some(p)
}
};
match end_pos {
Some(n) => {
self.pos = n;
Ok(self.pos)
}
None => Err(Error::new_const(
ErrorKind::InvalidInput,
&"invalid seek to a negative or overflowing position",
)),
}
}
fn stream_len(&mut self) -> Result<u64> {
Ok(self.inner.as_ref().len() as u64)
}
fn stream_position(&mut self) -> Result<u64> {
Ok(self.pos)
}
}