Add vectored read and write support
This functionality has lived for a while in the tokio ecosystem, where it can improve performance by minimizing copies.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use cmp;
|
||||
use io::{self, SeekFrom, Read, Initializer, Write, Seek, BufRead, Error, ErrorKind};
|
||||
use io::{self, SeekFrom, Read, Initializer, Write, Seek, BufRead, Error, ErrorKind, IoVecMut,
|
||||
IoVec};
|
||||
use fmt;
|
||||
use mem;
|
||||
|
||||
@@ -13,6 +14,11 @@ impl<'a, R: Read + ?Sized> Read for &'a mut R {
|
||||
(**self).read(buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
(**self).read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
(**self).initializer()
|
||||
@@ -38,6 +44,11 @@ impl<'a, W: Write + ?Sized> Write for &'a mut W {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
|
||||
|
||||
#[inline]
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
(**self).write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> { (**self).flush() }
|
||||
|
||||
@@ -82,6 +93,11 @@ impl<R: Read + ?Sized> Read for Box<R> {
|
||||
(**self).read(buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
(**self).read_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
(**self).initializer()
|
||||
@@ -107,6 +123,11 @@ impl<W: Write + ?Sized> Write for Box<W> {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
|
||||
|
||||
#[inline]
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
(**self).write_vectored(bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> { (**self).flush() }
|
||||
|
||||
@@ -171,6 +192,19 @@ impl<'a> Read for &'a [u8] {
|
||||
Ok(amt)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
let mut nread = 0;
|
||||
for buf in bufs {
|
||||
nread += self.read(buf.as_mut_slice())?;
|
||||
if self.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(nread)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn initializer(&self) -> Initializer {
|
||||
Initializer::nop()
|
||||
@@ -231,6 +265,19 @@ impl<'a> Write for &'a mut [u8] {
|
||||
Ok(amt)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
let mut nwritten = 0;
|
||||
for buf in bufs {
|
||||
nwritten += self.write(buf.as_slice())?;
|
||||
if self.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(nwritten)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
|
||||
if self.write(data)? == data.len() {
|
||||
@@ -254,6 +301,16 @@ impl Write for Vec<u8> {
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
let len = bufs.iter().map(|b| b.as_slice().len()).sum();
|
||||
self.reserve(len);
|
||||
for buf in bufs {
|
||||
self.extend_from_slice(buf.as_slice());
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
self.extend_from_slice(buf);
|
||||
|
||||
Reference in New Issue
Block a user