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:
parent
eabfc160f8
commit
d46c99abe8
@ -22,7 +22,6 @@ use ffi::OsString;
|
||||
use io::{self, SeekFrom, Seek, Read, Write};
|
||||
use path::{Path, PathBuf};
|
||||
use sys::fs as fs_imp;
|
||||
use sys_common::io::read_to_end_uninitialized;
|
||||
use sys_common::{AsInnerMut, FromInner, AsInner, IntoInner};
|
||||
use vec::Vec;
|
||||
use time::SystemTime;
|
||||
@ -351,7 +350,7 @@ impl Read for File {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
unsafe { read_to_end_uninitialized(self, buf) }
|
||||
self.inner.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -372,6 +371,9 @@ impl<'a> Read for &'a File {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
self.inner.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> Write for &'a File {
|
||||
|
@ -18,7 +18,6 @@ use io::lazy::Lazy;
|
||||
use io::{self, BufReader, LineWriter};
|
||||
use sync::{Arc, Mutex, MutexGuard};
|
||||
use sys::stdio;
|
||||
use sys_common::io::{read_to_end_uninitialized};
|
||||
use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
|
||||
use thread::LocalKeyState;
|
||||
|
||||
@ -78,6 +77,9 @@ fn stderr_raw() -> io::Result<StderrRaw> { stdio::Stderr::new().map(StderrRaw) }
|
||||
|
||||
impl Read for StdinRaw {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
self.0.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
impl Write for StdoutRaw {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
|
||||
@ -116,6 +118,12 @@ impl<R: io::Read> io::Read for Maybe<R> {
|
||||
Maybe::Fake => Ok(0)
|
||||
}
|
||||
}
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
match *self {
|
||||
Maybe::Real(ref mut r) => handle_ebadf(r.read_to_end(buf), 0),
|
||||
Maybe::Fake => Ok(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
|
||||
@ -294,7 +302,7 @@ impl<'a> Read for StdinLock<'a> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
unsafe { read_to_end_uninitialized(self, buf) }
|
||||
self.inner.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@ use io::prelude::*;
|
||||
use fmt;
|
||||
use io;
|
||||
use net::{ToSocketAddrs, SocketAddr, Shutdown};
|
||||
use sys_common::io::read_to_end_uninitialized;
|
||||
use sys_common::net as net_imp;
|
||||
use sys_common::{AsInner, FromInner, IntoInner};
|
||||
use time::Duration;
|
||||
@ -269,7 +268,7 @@ impl TcpStream {
|
||||
impl Read for TcpStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
unsafe { read_to_end_uninitialized(self, buf) }
|
||||
self.0.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -281,7 +280,7 @@ impl Write for TcpStream {
|
||||
impl<'a> Read for &'a TcpStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
unsafe { read_to_end_uninitialized(self, buf) }
|
||||
self.0.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -134,6 +134,9 @@ impl Read for ChildStdout {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
self.inner.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<AnonPipe> for ChildStdout {
|
||||
@ -161,6 +164,9 @@ impl Read for ChildStderr {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
self.inner.read_to_end(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<AnonPipe> for ChildStderr {
|
||||
|
@ -225,6 +225,10 @@ impl TcpStream {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
self.inner.read_to_end(buf)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
|
||||
let ret = try!(cvt(unsafe {
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use prelude::v1::*;
|
||||
use io::prelude::*;
|
||||
use os::windows::prelude::*;
|
||||
|
||||
@ -312,6 +313,10 @@ impl File {
|
||||
self.handle.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
self.handle.read_to_end(buf)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.handle.write(buf)
|
||||
}
|
||||
|
@ -8,14 +8,17 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use prelude::v1::*;
|
||||
|
||||
use cmp;
|
||||
use io::ErrorKind;
|
||||
use io::{ErrorKind, Read};
|
||||
use io;
|
||||
use mem;
|
||||
use ops::Deref;
|
||||
use ptr;
|
||||
use sys::c;
|
||||
use sys::cvt;
|
||||
use sys_common::io::read_to_end_uninitialized;
|
||||
use u32;
|
||||
|
||||
/// An owned container for `HANDLE` object, closing them on Drop.
|
||||
@ -87,6 +90,11 @@ impl RawHandle {
|
||||
}
|
||||
}
|
||||
|
||||
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 mut amt = 0;
|
||||
// WriteFile takes a DWORD (u32) for the length so it only supports
|
||||
@ -111,3 +119,14 @@ impl RawHandle {
|
||||
Ok(Handle::new(ret))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
|
||||
impl<'a> Read for &'a RawHandle {
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,10 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use prelude::v1::*;
|
||||
|
||||
use cmp;
|
||||
use io;
|
||||
use io::{self, Read};
|
||||
use libc::{c_int, c_void, c_ulong};
|
||||
use mem;
|
||||
use net::{SocketAddr, Shutdown};
|
||||
@ -20,6 +22,7 @@ use sync::Once;
|
||||
use sys::c;
|
||||
use sys;
|
||||
use sys_common::{self, AsInner, FromInner, IntoInner};
|
||||
use sys_common::io::read_to_end_uninitialized;
|
||||
use sys_common::net;
|
||||
use time::Duration;
|
||||
|
||||
@ -142,6 +145,11 @@ impl Socket {
|
||||
}
|
||||
}
|
||||
|
||||
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 set_timeout(&self, dur: Option<Duration>,
|
||||
kind: c_int) -> io::Result<()> {
|
||||
let timeout = match dur {
|
||||
@ -206,6 +214,17 @@ impl Socket {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
|
||||
impl<'a> Read for &'a Socket {
|
||||
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 Drop for Socket {
|
||||
fn drop(&mut self) {
|
||||
let _ = unsafe { c::closesocket(self.0) };
|
||||
|
@ -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 ptr;
|
||||
use sys::cvt;
|
||||
@ -41,6 +43,10 @@ impl AnonPipe {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
self.inner.read_to_end(buf)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.write(buf)
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use sync::Mutex;
|
||||
use sys::c;
|
||||
use sys::cvt;
|
||||
use sys::handle::Handle;
|
||||
use sys_common::io::read_to_end_uninitialized;
|
||||
|
||||
pub struct NoClose(Option<Handle>);
|
||||
|
||||
@ -113,6 +114,22 @@ impl Stdin {
|
||||
// MemReader shouldn't error here since we just filled it
|
||||
utf8.read(buf)
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
let mut me = self;
|
||||
(&mut me).read_to_end(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
|
||||
impl<'a> Read for &'a Stdin {
|
||||
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 Stdout {
|
||||
|
Loading…
x
Reference in New Issue
Block a user