提交 d46c99ab 编写于 作者: A Alex Crichton

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`.
上级 eabfc160
......@@ -22,7 +22,6 @@
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 @@ 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> {
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::{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 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
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 @@ 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> {
unsafe { read_to_end_uninitialized(self, buf) }
self.inner.read_to_end(buf)
}
}
......
......@@ -14,7 +14,6 @@
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 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
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 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
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 @@ pub fn duplicate(&self) -> io::Result<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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
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 @@ pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<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 mut amt = 0;
// WriteFile takes a DWORD (u32) for the length so it only supports
......@@ -111,3 +119,14 @@ pub fn duplicate(&self, access: c::DWORD, inherit: bool,
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 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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<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 set_timeout(&self, dur: Option<Duration>,
kind: c_int) -> io::Result<()> {
let timeout = match dur {
......@@ -206,6 +214,17 @@ pub fn nodelay(&self) -> io::Result<bool> {
}
}
#[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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
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 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 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
// 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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册