use core::cmp;
use core::fmt;
#[cfg(not(core_memchr))]
mod memchr;
#[cfg(all(feature="collections",core_memchr))]
use core::slice::memchr;
use core::ops::{Deref, DerefMut};
use core::ptr;
use core::slice;
use core::str;
#[cfg(feature="collections")] pub use self::buffered::IntoInnerError;
#[cfg(feature="collections")] pub use self::buffered::{BufReader, BufWriter, LineWriter};
pub use self::cursor::Cursor;
pub use self::error::{Error, ErrorKind, Result};
pub use self::util::{copy, empty, repeat, sink, Empty, Repeat, Sink};
#[cfg(feature="collections")] use collections::string::String;
#[cfg(feature="collections")] use collections::vec::Vec;
#[cfg(feature="collections")] mod buffered;
mod cursor;
mod error;
mod impls;
pub mod prelude;
mod util;
const DEFAULT_BUF_SIZE: usize = 8 * 1024;
#[cfg(feature="collections")]
struct Guard<'a> {
buf: &'a mut Vec<u8>,
len: usize,
}
#[cfg(feature="collections")]
impl Drop for Guard<'_> {
fn drop(&mut self) {
unsafe {
self.buf.set_len(self.len);
}
}
}
#[cfg(feature="collections")]
fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
where
F: FnOnce(&mut Vec<u8>) -> Result<usize>,
{
unsafe {
let mut g = Guard { len: buf.len(), buf: buf.as_mut_vec() };
let ret = f(g.buf);
if str::from_utf8(&g.buf[g.len..]).is_err() {
ret.and_then(|_| {
Err(Error::new(ErrorKind::InvalidData, "stream did not contain valid UTF-8"))
})
} else {
g.len = g.buf.len();
ret
}
}
}
#[cfg(feature="collections")]
fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
read_to_end_with_reservation(r, buf, |_| 32)
}
#[cfg(feature="collections")]
fn read_to_end_with_reservation<R, F>(
r: &mut R,
buf: &mut Vec<u8>,
mut reservation_size: F,
) -> Result<usize>
where
R: Read + ?Sized,
F: FnMut(&R) -> usize,
{
let start_len = buf.len();
let mut g = Guard { len: buf.len(), buf };
let ret;
loop {
if g.len == g.buf.len() {
unsafe {
g.buf.reserve(reservation_size(r));
let capacity = g.buf.capacity();
g.buf.set_len(capacity);
r.initializer().initialize(&mut g.buf[g.len..]);
}
}
match r.read(&mut g.buf[g.len..]) {
Ok(0) => {
ret = Ok(g.len - start_len);
break;
}
Ok(n) => g.len += n,
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => {
ret = Err(e);
break;
}
}
}
ret
}
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_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)
}
#[doc(spotlight)]
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
default_read_vectored(|b| self.read(b), bufs)
}
fn is_read_vectored(&self) -> bool {
false
}
#[inline]
unsafe fn initializer(&self) -> Initializer {
Initializer::zeroing()
}
#[cfg(feature="collections")]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
read_to_end(self, buf)
}
#[cfg(feature="collections")]
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
append_to_string(buf, |b| read_to_end(self, b))
}
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
}
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 }
}
}
#[derive(Copy, Clone)]
pub struct IoVecBuffer<'a>(&'a [u8]);
impl<'a> IoVecBuffer<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> IoVecBuffer<'a> {
IoVecBuffer(buf)
}
#[inline]
pub fn advance(&mut self, n: usize) {
self.0 = &self.0[n..]
}
#[inline]
pub fn as_slice(&self) -> &[u8] {
self.0
}
}
pub struct IoVecMutBuffer<'a>(&'a mut [u8]);
impl<'a> IoVecMutBuffer<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> IoVecMutBuffer<'a> {
IoVecMutBuffer(buf)
}
#[inline]
pub fn advance(&mut self, n: usize) {
let slice = core::mem::replace(&mut self.0, &mut []);
let (_, remaining) = slice.split_at_mut(n);
self.0 = remaining;
}
#[inline]
pub fn as_slice(&self) -> &[u8] {
self.0
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
self.0
}
}
#[repr(transparent)]
pub struct IoSliceMut<'a>(IoVecMutBuffer<'a>);
unsafe impl<'a> Send for IoSliceMut<'a> {}
unsafe impl<'a> Sync for IoSliceMut<'a> {}
impl<'a> fmt::Debug for IoSliceMut<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.0.as_slice(), fmt)
}
}
impl<'a> IoSliceMut<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
IoSliceMut(IoVecMutBuffer::new(buf))
}
#[inline]
pub fn advance<'b>(bufs: &'b mut [IoSliceMut<'a>], n: usize) -> &'b mut [IoSliceMut<'a>] {
let mut remove = 0;
let mut accumulated_len = 0;
for buf in bufs.iter() {
if accumulated_len + buf.len() > n {
break;
} else {
accumulated_len += buf.len();
remove += 1;
}
}
let bufs = &mut bufs[remove..];
if !bufs.is_empty() {
bufs[0].0.advance(n - accumulated_len)
}
bufs
}
}
impl<'a> Deref for IoSliceMut<'a> {
type Target = [u8];
#[inline]
fn deref(&self) -> &[u8] {
self.0.as_slice()
}
}
impl<'a> DerefMut for IoSliceMut<'a> {
#[inline]
fn deref_mut(&mut self) -> &mut [u8] {
self.0.as_mut_slice()
}
}
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct IoSlice<'a>(IoVecBuffer<'a>);
unsafe impl<'a> Send for IoSlice<'a> {}
unsafe impl<'a> Sync for IoSlice<'a> {}
impl<'a> fmt::Debug for IoSlice<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.0.as_slice(), fmt)
}
}
impl<'a> IoSlice<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
IoSlice(IoVecBuffer::new(buf))
}
#[inline]
pub fn advance<'b>(bufs: &'b mut [IoSlice<'a>], n: usize) -> &'b mut [IoSlice<'a>] {
let mut remove = 0;
let mut accumulated_len = 0;
for buf in bufs.iter() {
if accumulated_len + buf.len() > n {
break;
} else {
accumulated_len += buf.len();
remove += 1;
}
}
let bufs = &mut bufs[remove..];
if !bufs.is_empty() {
bufs[0].0.advance(n - accumulated_len)
}
bufs
}
}
impl<'a> Deref for IoSlice<'a> {
type Target = [u8];
#[inline]
fn deref(&self) -> &[u8] {
self.0.as_slice()
}
}
#[derive(Debug)]
pub struct Initializer(bool);
impl Initializer {
#[inline]
pub fn zeroing() -> Initializer {
Initializer(true)
}
#[inline]
pub unsafe fn nop() -> Initializer {
Initializer(false)
}
#[inline]
pub fn should_initialize(&self) -> bool {
self.0
}
#[inline]
pub fn initialize(&self, buf: &mut [u8]) {
if self.should_initialize() {
unsafe { ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len()) }
}
}
}
#[doc(spotlight)]
pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
default_write_vectored(|b| self.write(b), bufs)
}
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(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 write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
bufs = IoSlice::advance(bufs, 0);
while !bufs.is_empty() {
match self.write_vectored(bufs) {
Ok(0) => {
return Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer"));
}
Ok(n) => bufs = IoSlice::advance(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 Adaptor<'a, T: ?Sized + 'a> {
inner: &'a mut T,
error: Result<()>,
}
impl<T: Write + ?Sized> fmt::Write for Adaptor<'_, 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 = Adaptor { inner: self, error: Ok(()) };
match fmt::write(&mut output, fmt) {
Ok(()) => Ok(()),
Err(..) => {
if output.error.is_err() {
output.error
} else {
Err(Error::new(ErrorKind::Other, "formatter error"))
}
}
}
}
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
}
pub trait Seek {
fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
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(Copy, PartialEq, Eq, Clone, Debug)]
pub enum SeekFrom {
Start(u64),
End(i64),
Current(i64),
}
#[cfg(feature="collections")]
fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>) -> Result<usize> {
let mut read = 0;
loop {
let (done, used) = {
let available = match r.fill_buf() {
Ok(n) => n,
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
match memchr::memchr(delim, available) {
Some(i) => {
buf.extend_from_slice(&available[..=i]);
(true, i + 1)
}
None => {
buf.extend_from_slice(available);
(false, available.len())
}
}
};
r.consume(used);
read += used;
if done || used == 0 {
return Ok(read);
}
}
}
#[cfg(feature="collections")]
pub trait BufRead: Read {
fn fill_buf(&mut self) -> Result<&[u8]>;
fn consume(&mut self, amt: usize);
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
read_until(self, byte, buf)
}
fn read_line(&mut self, buf: &mut String) -> Result<usize> {
append_to_string(buf, |b| read_until(self, b'\n', b))
}
fn split(self, byte: u8) -> Split<Self>
where
Self: Sized,
{
Split { buf: self, delim: byte }
}
fn lines(self) -> Lines<Self>
where
Self: Sized,
{
Lines { buf: self }
}
}
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: fmt::Debug, U: fmt::Debug> fmt::Debug for Chain<T, U> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Chain").field("t", &self.first).field("u", &self.second).finish()
}
}
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)
}
unsafe fn initializer(&self) -> Initializer {
let initializer = self.first.initializer();
if initializer.should_initialize() { initializer } else { self.second.initializer() }
}
}
#[cfg(feature="collections")]
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) }
}
}
#[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)
}
unsafe fn initializer(&self) -> Initializer {
self.inner.initializer()
}
#[cfg(feature="collections")]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
read_to_end_with_reservation(self, buf, |self_| cmp::min(self_.limit, 32) as usize)
}
}
#[cfg(feature="collections")]
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 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)),
};
}
}
}
#[cfg(feature="collections")]
#[derive(Debug)]
pub struct Split<B> {
buf: B,
delim: u8,
}
#[cfg(feature="collections")]
impl<B: BufRead> Iterator for Split<B> {
type Item = Result<Vec<u8>>;
fn next(&mut self) -> Option<Result<Vec<u8>>> {
let mut buf = Vec::new();
match self.buf.read_until(self.delim, &mut buf) {
Ok(0) => None,
Ok(_n) => {
if buf[buf.len() - 1] == self.delim {
buf.pop();
}
Some(Ok(buf))
}
Err(e) => Some(Err(e)),
}
}
}
#[cfg(feature="collections")]
#[derive(Debug)]
pub struct Lines<B> {
buf: B,
}
#[cfg(feature="collections")]
impl<B: BufRead> Iterator for Lines<B> {
type Item = Result<String>;
fn next(&mut self) -> Option<Result<String>> {
let mut buf = String::new();
match self.buf.read_line(&mut buf) {
Ok(0) => None,
Ok(_n) => {
if buf.ends_with('\n') {
buf.pop();
if buf.ends_with('\r') {
buf.pop();
}
}
Some(Ok(buf))
}
Err(e) => Some(Err(e)),
}
}
}
#[cfg(test)]
mod tests {
use super::{repeat, Cursor, SeekFrom};
use crate::cmp::{self, min};
use crate::io::prelude::*;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::ops::Deref;
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn read_until() {
let mut buf = Cursor::new(&b"12"[..]);
let mut v = Vec::new();
assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2);
assert_eq!(v, b"12");
let mut buf = Cursor::new(&b"1233"[..]);
let mut v = Vec::new();
assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3);
assert_eq!(v, b"123");
v.truncate(0);
assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1);
assert_eq!(v, b"3");
v.truncate(0);
assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0);
assert_eq!(v, []);
}
#[test]
fn split() {
let buf = Cursor::new(&b"12"[..]);
let mut s = buf.split(b'3');
assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
assert!(s.next().is_none());
let buf = Cursor::new(&b"1233"[..]);
let mut s = buf.split(b'3');
assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
assert_eq!(s.next().unwrap().unwrap(), vec![]);
assert!(s.next().is_none());
}
#[test]
fn read_line() {
let mut buf = Cursor::new(&b"12"[..]);
let mut v = String::new();
assert_eq!(buf.read_line(&mut v).unwrap(), 2);
assert_eq!(v, "12");
let mut buf = Cursor::new(&b"12\n\n"[..]);
let mut v = String::new();
assert_eq!(buf.read_line(&mut v).unwrap(), 3);
assert_eq!(v, "12\n");
v.truncate(0);
assert_eq!(buf.read_line(&mut v).unwrap(), 1);
assert_eq!(v, "\n");
v.truncate(0);
assert_eq!(buf.read_line(&mut v).unwrap(), 0);
assert_eq!(v, "");
}
#[test]
fn lines() {
let buf = Cursor::new(&b"12\r"[..]);
let mut s = buf.lines();
assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string());
assert!(s.next().is_none());
let buf = Cursor::new(&b"12\r\n\n"[..]);
let mut s = buf.lines();
assert_eq!(s.next().unwrap().unwrap(), "12".to_string());
assert_eq!(s.next().unwrap().unwrap(), "".to_string());
assert!(s.next().is_none());
}
#[test]
fn read_to_end() {
let mut c = Cursor::new(&b""[..]);
let mut v = Vec::new();
assert_eq!(c.read_to_end(&mut v).unwrap(), 0);
assert_eq!(v, []);
let mut c = Cursor::new(&b"1"[..]);
let mut v = Vec::new();
assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
assert_eq!(v, b"1");
let cap = 1024 * 1024;
let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
let mut v = Vec::new();
let (a, b) = data.split_at(data.len() / 2);
assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len());
assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len());
assert_eq!(v, data);
}
#[test]
fn read_to_string() {
let mut c = Cursor::new(&b""[..]);
let mut v = String::new();
assert_eq!(c.read_to_string(&mut v).unwrap(), 0);
assert_eq!(v, "");
let mut c = Cursor::new(&b"1"[..]);
let mut v = String::new();
assert_eq!(c.read_to_string(&mut v).unwrap(), 1);
assert_eq!(v, "1");
let mut c = Cursor::new(&b"\xff"[..]);
let mut v = String::new();
assert!(c.read_to_string(&mut v).is_err());
}
#[test]
fn read_exact() {
let mut buf = [0; 4];
let mut c = Cursor::new(&b""[..]);
assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..]));
c.read_exact(&mut buf).unwrap();
assert_eq!(&buf, b"1234");
c.read_exact(&mut buf).unwrap();
assert_eq!(&buf, b"5678");
assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
}
#[test]
fn read_exact_slice() {
let mut buf = [0; 4];
let mut c = &b""[..];
assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
let mut c = &b"123"[..];
assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
assert_eq!(&buf, &[0; 4]);
let mut c = &b"1234"[..];
c.read_exact(&mut buf).unwrap();
assert_eq!(&buf, b"1234");
let mut c = &b"56789"[..];
c.read_exact(&mut buf).unwrap();
assert_eq!(&buf, b"5678");
assert_eq!(c, b"9");
}
#[test]
fn take_eof() {
struct R;
impl Read for R {
fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
Err(io::Error::new(io::ErrorKind::Other, ""))
}
}
impl BufRead for R {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Err(io::Error::new(io::ErrorKind::Other, ""))
}
fn consume(&mut self, _amt: usize) {}
}
let mut buf = [0; 1];
assert_eq!(0, R.take(0).read(&mut buf).unwrap());
assert_eq!(b"", R.take(0).fill_buf().unwrap());
}
fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) {
let mut cat = Vec::new();
loop {
let consume = {
let buf1 = br1.fill_buf().unwrap();
let buf2 = br2.fill_buf().unwrap();
let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() };
assert_eq!(buf1[..minlen], buf2[..minlen]);
cat.extend_from_slice(&buf1[..minlen]);
minlen
};
if consume == 0 {
break;
}
br1.consume(consume);
br2.consume(consume);
}
assert_eq!(br1.fill_buf().unwrap().len(), 0);
assert_eq!(br2.fill_buf().unwrap().len(), 0);
assert_eq!(&cat[..], &exp[..])
}
#[test]
fn chain_bufread() {
let testdata = b"ABCDEFGHIJKL";
let chain1 =
(&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]);
let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]);
cmp_bufread(chain1, chain2, &testdata[..]);
}
#[test]
fn chain_zero_length_read_is_not_eof() {
let a = b"A";
let b = b"B";
let mut s = String::new();
let mut chain = (&a[..]).chain(&b[..]);
chain.read(&mut []).unwrap();
chain.read_to_string(&mut s).unwrap();
assert_eq!("AB", s);
}
#[bench]
#[cfg_attr(target_os = "emscripten", ignore)]
fn bench_read_to_end(b: &mut test::Bencher) {
b.iter(|| {
let mut lr = repeat(1).take(10000000);
let mut vec = Vec::with_capacity(1024);
super::read_to_end(&mut lr, &mut vec)
});
}
#[test]
fn seek_len() -> io::Result<()> {
let mut c = Cursor::new(vec![0; 15]);
assert_eq!(c.stream_len()?, 15);
c.seek(SeekFrom::End(0))?;
let old_pos = c.stream_position()?;
assert_eq!(c.stream_len()?, 15);
assert_eq!(c.stream_position()?, old_pos);
c.seek(SeekFrom::Start(7))?;
c.seek(SeekFrom::Current(2))?;
let old_pos = c.stream_position()?;
assert_eq!(c.stream_len()?, 15);
assert_eq!(c.stream_position()?, old_pos);
Ok(())
}
#[test]
fn seek_position() -> io::Result<()> {
let mut c = Cursor::new(vec![0; 15]);
assert_eq!(c.stream_position()?, 0);
assert_eq!(c.stream_position()?, 0);
c.seek(SeekFrom::End(0))?;
assert_eq!(c.stream_position()?, 15);
assert_eq!(c.stream_position()?, 15);
c.seek(SeekFrom::Start(7))?;
c.seek(SeekFrom::Current(2))?;
assert_eq!(c.stream_position()?, 9);
assert_eq!(c.stream_position()?, 9);
c.seek(SeekFrom::End(-3))?;
c.seek(SeekFrom::Current(1))?;
c.seek(SeekFrom::Current(-5))?;
assert_eq!(c.stream_position()?, 8);
assert_eq!(c.stream_position()?, 8);
Ok(())
}
struct ExampleSliceReader<'a> {
slice: &'a [u8],
}
impl<'a> Read for ExampleSliceReader<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let len = cmp::min(self.slice.len(), buf.len());
buf[..len].copy_from_slice(&self.slice[..len]);
self.slice = &self.slice[len..];
Ok(len)
}
}
#[test]
fn test_read_to_end_capacity() -> io::Result<()> {
let input = &b"foo"[..];
let mut vec1 = Vec::with_capacity(input.len());
ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?;
assert_eq!(vec1.len(), input.len());
assert!(vec1.capacity() > input.len(), "allocated more");
let mut vec2 = Vec::with_capacity(input.len());
ExampleSliceReader { slice: input }.take(input.len() as u64).read_to_end(&mut vec2)?;
assert_eq!(vec2.len(), input.len());
assert_eq!(vec2.capacity(), input.len(), "did not allocate more");
Ok(())
}
#[test]
fn io_slice_mut_advance() {
let mut buf1 = [1; 8];
let mut buf2 = [2; 16];
let mut buf3 = [3; 8];
let mut bufs = &mut [
IoSliceMut::new(&mut buf1),
IoSliceMut::new(&mut buf2),
IoSliceMut::new(&mut buf3),
][..];
bufs = IoSliceMut::advance(bufs, 1);
assert_eq!(bufs[0].deref(), [1; 7].as_ref());
assert_eq!(bufs[1].deref(), [2; 16].as_ref());
assert_eq!(bufs[2].deref(), [3; 8].as_ref());
bufs = IoSliceMut::advance(bufs, 7);
assert_eq!(bufs[0].deref(), [2; 16].as_ref());
assert_eq!(bufs[1].deref(), [3; 8].as_ref());
bufs = IoSliceMut::advance(bufs, 18);
assert_eq!(bufs[0].deref(), [3; 6].as_ref());
}
#[test]
fn io_slice_mut_advance_empty_slice() {
let empty_bufs = &mut [][..];
IoSliceMut::advance(empty_bufs, 1);
}
#[test]
fn io_slice_mut_advance_beyond_total_length() {
let mut buf1 = [1; 8];
let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];
bufs = IoSliceMut::advance(bufs, 9);
assert!(bufs.is_empty());
}
#[test]
fn io_slice_advance() {
let buf1 = [1; 8];
let buf2 = [2; 16];
let buf3 = [3; 8];
let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..];
bufs = IoSlice::advance(bufs, 1);
assert_eq!(bufs[0].deref(), [1; 7].as_ref());
assert_eq!(bufs[1].deref(), [2; 16].as_ref());
assert_eq!(bufs[2].deref(), [3; 8].as_ref());
bufs = IoSlice::advance(bufs, 7);
assert_eq!(bufs[0].deref(), [2; 16].as_ref());
assert_eq!(bufs[1].deref(), [3; 8].as_ref());
bufs = IoSlice::advance(bufs, 18);
assert_eq!(bufs[0].deref(), [3; 6].as_ref());
}
#[test]
fn io_slice_advance_empty_slice() {
let empty_bufs = &mut [][..];
IoSlice::advance(empty_bufs, 1);
}
#[test]
fn io_slice_advance_beyond_total_length() {
let buf1 = [1; 8];
let mut bufs = &mut [IoSlice::new(&buf1)][..];
bufs = IoSlice::advance(bufs, 9);
assert!(bufs.is_empty());
}
fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
TestWriter { n_bufs, per_call, written: Vec::new() }
}
struct TestWriter {
n_bufs: usize,
per_call: usize,
written: Vec<u8>,
}
impl Write for TestWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.write_vectored(&[IoSlice::new(buf)])
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let mut left = self.per_call;
let mut written = 0;
for buf in bufs.iter().take(self.n_bufs) {
let n = min(left, buf.len());
self.written.extend_from_slice(&buf[0..n]);
left -= n;
written += n;
}
Ok(written)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[test]
fn test_writer_read_from_one_buf() {
let mut writer = test_writer(1, 2);
assert_eq!(writer.write(&[]).unwrap(), 0);
assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2);
let bufs = &[IoSlice::new(&[2, 2, 2])];
assert_eq!(writer.write_vectored(bufs).unwrap(), 2);
let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])];
assert_eq!(writer.write_vectored(bufs).unwrap(), 1);
assert_eq!(writer.written, &[1, 1, 2, 2, 3]);
}
#[test]
fn test_writer_read_from_multiple_bufs() {
let mut writer = test_writer(3, 3);
let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])];
assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])];
assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]);
}
#[test]
fn test_write_all_vectored() {
#[rustfmt::skip] let tests: Vec<(_, &'static [u8])> = vec![
(vec![], &[]),
(vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]),
(vec![IoSlice::new(&[1])], &[1]),
(vec![IoSlice::new(&[1, 2])], &[1, 2]),
(vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]),
(vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]),
(vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]),
(vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]),
(vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]),
(vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]),
(vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
(vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
(vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]),
(vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]),
(vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]),
(vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]),
(vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]),
(vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]),
(vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]),
];
let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)];
for (n_bufs, per_call) in writer_configs.iter().copied() {
for (mut input, wanted) in tests.clone().into_iter() {
let mut writer = test_writer(n_bufs, per_call);
assert!(writer.write_all_vectored(&mut *input).is_ok());
assert_eq!(&*writer.written, &*wanted);
}
}
}
}