std: Funnel read_to_end through to one location

This pushes the implementation detail of proxying `read_to_end` through to
`read_to_end_uninitialized` all the way down to the `FileDesc` and `Handle`
implementations on Unix/Windows. This way intermediate layers will also be able
to take advantage of this optimized implementation.

This commit also adds the optimized implementation for `ChildStdout` and
`ChildStderr`.
This commit is contained in:
Alex Crichton 2016-02-12 00:17:24 -08:00
parent eabfc160f8
commit d46c99abe8
15 changed files with 136 additions and 11 deletions

View file

@ -8,12 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use io;
use prelude::v1::*;
use io::{self, Read};
use libc::{self, c_int, size_t, c_void};
use mem;
use sync::atomic::{AtomicBool, Ordering};
use sys::cvt;
use sys_common::AsInner;
use sync::atomic::{AtomicBool, Ordering};
use sys_common::io::read_to_end_uninitialized;
pub struct FileDesc {
fd: c_int,
@ -42,6 +45,11 @@ impl FileDesc {
Ok(ret as usize)
}
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
let mut me = self;
(&mut me).read_to_end(buf)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let ret = try!(cvt(unsafe {
libc::write(self.fd,
@ -118,6 +126,17 @@ impl FileDesc {
}
}
#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
impl<'a> Read for &'a FileDesc {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(**self).read(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
unsafe { read_to_end_uninitialized(self, buf) }
}
}
impl AsInner<c_int> for FileDesc {
fn as_inner(&self) -> &c_int { &self.fd }
}

View file

@ -486,6 +486,10 @@ impl File {
self.0.read(buf)
}
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}

View file

@ -116,6 +116,10 @@ impl Socket {
self.0.read(buf)
}
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
let timeout = match dur {
Some(dur) => {

View file

@ -57,6 +57,10 @@ impl AnonPipe {
self.0.read(buf)
}
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use prelude::v1::*;
use io;
use libc;
use sys::fd::FileDesc;
@ -25,6 +27,13 @@ impl Stdin {
fd.into_raw();
ret
}
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
let fd = FileDesc::new(libc::STDIN_FILENO);
let ret = fd.read_to_end(buf);
fd.into_raw();
ret
}
}
impl Stdout {