Tweak the interface of std::io
* Reexport io::mem and io::buffered structs directly under io, make mem/buffered private modules * Remove with_mem_writer * Remove DEFAULT_CAPACITY and use DEFAULT_BUF_SIZE (in io::buffered)
This commit is contained in:
parent
77eeddaa48
commit
295b46fc08
41 changed files with 204 additions and 180 deletions
|
|
@ -9,59 +9,37 @@
|
|||
// except according to those terms.
|
||||
|
||||
//! Buffering wrappers for I/O traits
|
||||
//!
|
||||
//! It can be excessively inefficient to work directly with a `Reader` or
|
||||
//! `Writer`. Every call to `read` or `write` on `TcpStream` results in a
|
||||
//! system call, for example. This module provides structures that wrap
|
||||
//! `Readers`, `Writers`, and `Streams` and buffer input and output to them.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```
|
||||
//! let tcp_stream = TcpStream::connect(addr);
|
||||
//! let reader = BufferedReader::new(tcp_stream);
|
||||
//!
|
||||
//! let mut buf: ~[u8] = vec::from_elem(100, 0u8);
|
||||
//! match reader.read(buf.as_slice()) {
|
||||
//! Some(nread) => println!("Read {} bytes", nread),
|
||||
//! None => println!("At the end of the stream!")
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ```
|
||||
//! let tcp_stream = TcpStream::connect(addr);
|
||||
//! let writer = BufferedWriter::new(tcp_stream);
|
||||
//!
|
||||
//! writer.write("hello, world".as_bytes());
|
||||
//! writer.flush();
|
||||
//! ```
|
||||
//!
|
||||
//! ```
|
||||
//! let tcp_stream = TcpStream::connect(addr);
|
||||
//! let stream = BufferedStream::new(tcp_stream);
|
||||
//!
|
||||
//! stream.write("hello, world".as_bytes());
|
||||
//! stream.flush();
|
||||
//!
|
||||
//! let mut buf = vec::from_elem(100, 0u8);
|
||||
//! match stream.read(buf.as_slice()) {
|
||||
//! Some(nread) => println!("Read {} bytes", nread),
|
||||
//! None => println!("At the end of the stream!")
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
|
||||
use prelude::*;
|
||||
|
||||
use container::Container;
|
||||
use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE};
|
||||
use iter::ExactSize;
|
||||
use num;
|
||||
use option::{Option, Some, None};
|
||||
use vec::{OwnedVector, ImmutableVector, MutableVector};
|
||||
use vec;
|
||||
use super::Stream;
|
||||
|
||||
// libuv recommends 64k buffers to maximize throughput
|
||||
// https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
|
||||
static DEFAULT_CAPACITY: uint = 64 * 1024;
|
||||
|
||||
/// Wraps a Reader and buffers input from it
|
||||
///
|
||||
/// It can be excessively inefficient to work directly with a `Reader` or
|
||||
/// `Writer`. Every call to `read` or `write` on `TcpStream` results in a
|
||||
/// system call, for example. This module provides structures that wrap
|
||||
/// `Readers`, `Writers`, and `Streams` and buffer input and output to them.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::{BufferedReader, File};
|
||||
///
|
||||
/// # let _g = ::std::io::ignore_io_error();
|
||||
/// let file = File::open(&Path::new("message.txt"));
|
||||
/// let mut reader = BufferedReader::new(file);
|
||||
///
|
||||
/// let mut buf = [0, ..100];
|
||||
/// match reader.read(buf) {
|
||||
/// Some(nread) => println!("Read {} bytes", nread),
|
||||
/// None => println!("At the end of the file!")
|
||||
/// }
|
||||
/// ```
|
||||
pub struct BufferedReader<R> {
|
||||
priv inner: R,
|
||||
priv buf: ~[u8],
|
||||
|
|
@ -92,7 +70,7 @@ impl<R: Reader> BufferedReader<R> {
|
|||
|
||||
/// Creates a new `BufferedReader` with a default buffer capacity
|
||||
pub fn new(inner: R) -> BufferedReader<R> {
|
||||
BufferedReader::with_capacity(DEFAULT_CAPACITY, inner)
|
||||
BufferedReader::with_capacity(DEFAULT_BUF_SIZE, inner)
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying reader.
|
||||
|
|
@ -146,6 +124,19 @@ impl<R: Reader> Reader for BufferedReader<R> {
|
|||
/// Wraps a Writer and buffers output to it
|
||||
///
|
||||
/// Note that `BufferedWriter` will NOT flush its buffer when dropped.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::{BufferedWriter, File};
|
||||
///
|
||||
/// # let _g = ::std::io::ignore_io_error();
|
||||
/// let file = File::open(&Path::new("message.txt"));
|
||||
/// let mut writer = BufferedWriter::new(file);
|
||||
///
|
||||
/// writer.write_str("hello, world");
|
||||
/// writer.flush();
|
||||
/// ```
|
||||
pub struct BufferedWriter<W> {
|
||||
priv inner: W,
|
||||
priv buf: ~[u8],
|
||||
|
|
@ -167,7 +158,7 @@ impl<W: Writer> BufferedWriter<W> {
|
|||
|
||||
/// Creates a new `BufferedWriter` with a default buffer capacity
|
||||
pub fn new(inner: W) -> BufferedWriter<W> {
|
||||
BufferedWriter::with_capacity(DEFAULT_CAPACITY, inner)
|
||||
BufferedWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
|
||||
}
|
||||
|
||||
fn flush_buf(&mut self) {
|
||||
|
|
@ -273,6 +264,25 @@ impl<W: Reader> Reader for InternalBufferedWriter<W> {
|
|||
/// Wraps a Stream and buffers input and output to and from it
|
||||
///
|
||||
/// Note that `BufferedStream` will NOT flush its output buffer when dropped.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::{BufferedStream, File};
|
||||
///
|
||||
/// # let _g = ::std::io::ignore_io_error();
|
||||
/// let file = File::open(&Path::new("message.txt"));
|
||||
/// let mut stream = BufferedStream::new(file);
|
||||
///
|
||||
/// stream.write("hello, world".as_bytes());
|
||||
/// stream.flush();
|
||||
///
|
||||
/// let mut buf = [0, ..100];
|
||||
/// match stream.read(buf) {
|
||||
/// Some(nread) => println!("Read {} bytes", nread),
|
||||
/// None => println!("At the end of the stream!")
|
||||
/// }
|
||||
/// ```
|
||||
pub struct BufferedStream<S> {
|
||||
priv inner: BufferedReader<InternalBufferedWriter<S>>
|
||||
}
|
||||
|
|
@ -292,7 +302,7 @@ impl<S: Stream> BufferedStream<S> {
|
|||
/// Creates a new buffered stream with the default reader/writer buffer
|
||||
/// capacities.
|
||||
pub fn new(inner: S) -> BufferedStream<S> {
|
||||
BufferedStream::with_capacities(DEFAULT_CAPACITY, DEFAULT_CAPACITY,
|
||||
BufferedStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE,
|
||||
inner)
|
||||
}
|
||||
|
||||
|
|
@ -337,9 +347,9 @@ mod test {
|
|||
use super::super::mem::{MemReader, MemWriter, BufReader};
|
||||
use Harness = extra::test::BenchHarness;
|
||||
|
||||
/// A type, free to create, primarily intended for benchmarking creation of wrappers that, just
|
||||
/// for construction, don't need a Reader/Writer that does anything useful. Is equivalent to
|
||||
/// `/dev/null` in semantics.
|
||||
/// A type, free to create, primarily intended for benchmarking creation of
|
||||
/// wrappers that, just for construction, don't need a Reader/Writer that
|
||||
/// does anything useful. Is equivalent to `/dev/null` in semantics.
|
||||
#[deriving(Clone,Eq,Ord)]
|
||||
pub struct NullStream;
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ pub fn u64_from_be_bytes(data: &[u8],
|
|||
mod test {
|
||||
use unstable::finally::Finally;
|
||||
use prelude::*;
|
||||
use io::mem::{MemReader, MemWriter};
|
||||
use io::{MemReader, MemWriter};
|
||||
use io::{io_error, placeholder_error};
|
||||
|
||||
struct InitialZeroByteReader {
|
||||
|
|
|
|||
|
|
@ -9,18 +9,28 @@
|
|||
// except according to those terms.
|
||||
|
||||
//! Readers and Writers for in-memory buffers
|
||||
//!
|
||||
//! # XXX
|
||||
//!
|
||||
//! * Should probably have something like this for strings.
|
||||
//! * Should they implement Closable? Would take extra state.
|
||||
|
||||
use cmp::max;
|
||||
use cmp::min;
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
use container::Container;
|
||||
use option::{Option, Some, None};
|
||||
use super::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, io_error,
|
||||
OtherIoError};
|
||||
use vec;
|
||||
use vec::{Vector, ImmutableVector, MutableVector, OwnedCopyableVector};
|
||||
|
||||
/// Writes to an owned, growable byte vector
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::MemWriter;
|
||||
///
|
||||
/// let mut w = MemWriter::new();
|
||||
/// w.write([0, 1, 2]);
|
||||
///
|
||||
/// assert_eq!(w.unwrap(), ~[0, 1, 2]);
|
||||
/// ```
|
||||
pub struct MemWriter {
|
||||
priv buf: ~[u8],
|
||||
priv pos: uint,
|
||||
|
|
@ -96,6 +106,16 @@ impl Seek for MemWriter {
|
|||
}
|
||||
|
||||
/// Reads from an owned byte vector
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::MemReader;
|
||||
///
|
||||
/// let mut r = MemReader::new(~[0, 1, 2]);
|
||||
///
|
||||
/// assert_eq!(r.read_to_end(), ~[0, 1, 2]);
|
||||
/// ```
|
||||
pub struct MemReader {
|
||||
priv buf: ~[u8],
|
||||
priv pos: uint
|
||||
|
|
@ -159,6 +179,19 @@ impl Buffer for MemReader {
|
|||
///
|
||||
/// If a write will not fit in the buffer, it raises the `io_error`
|
||||
/// condition and does not write any data.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::BufWriter;
|
||||
///
|
||||
/// let mut buf = [0, ..4];
|
||||
/// {
|
||||
/// let mut w = BufWriter::new(buf);
|
||||
/// w.write([0, 1, 2]);
|
||||
/// }
|
||||
/// assert_eq!(buf, [0, 1, 2, 0]);
|
||||
/// ```
|
||||
pub struct BufWriter<'a> {
|
||||
priv buf: &'a mut [u8],
|
||||
priv pos: uint
|
||||
|
|
@ -209,12 +242,24 @@ impl<'a> Seek for BufWriter<'a> {
|
|||
|
||||
|
||||
/// Reads from a fixed-size byte slice
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::BufReader;
|
||||
///
|
||||
/// let mut buf = [0, 1, 2, 3];
|
||||
/// let mut r = BufReader::new(buf);
|
||||
///
|
||||
/// assert_eq!(r.read_to_end(), ~[0, 1, 2, 3]);
|
||||
/// ```
|
||||
pub struct BufReader<'a> {
|
||||
priv buf: &'a [u8],
|
||||
priv pos: uint
|
||||
}
|
||||
|
||||
impl<'a> BufReader<'a> {
|
||||
/// Creates a new buffered reader which will read the specified buffer
|
||||
pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
|
||||
BufReader {
|
||||
buf: buf,
|
||||
|
|
@ -257,14 +302,6 @@ impl<'a> Buffer for BufReader<'a> {
|
|||
fn consume(&mut self, amt: uint) { self.pos += amt; }
|
||||
}
|
||||
|
||||
///Calls a function with a MemWriter and returns
|
||||
///the writer's stored vector.
|
||||
pub fn with_mem_writer(writeFn: |&mut MemWriter|) -> ~[u8] {
|
||||
let mut writer = MemWriter::new();
|
||||
writeFn(&mut writer);
|
||||
writer.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use prelude::*;
|
||||
|
|
@ -398,12 +435,6 @@ mod test {
|
|||
assert_eq!(reader.read(buf), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_mem_writer() {
|
||||
let buf = with_mem_writer(|wr| wr.write([1,2,3,4,5,6,7]));
|
||||
assert_eq!(buf, ~[1,2,3,4,5,6,7]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_char() {
|
||||
let mut r = BufReader::new(bytes!("Việt"));
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ Some examples of obvious things you might want to do
|
|||
* Read lines from stdin
|
||||
|
||||
```rust
|
||||
use std::io::buffered::BufferedReader;
|
||||
use std::io::BufferedReader;
|
||||
use std::io::stdin;
|
||||
|
||||
# let _g = ::std::io::ignore_io_error();
|
||||
|
|
@ -60,7 +60,7 @@ Some examples of obvious things you might want to do
|
|||
* Iterate over the lines of a file
|
||||
|
||||
```rust
|
||||
use std::io::buffered::BufferedReader;
|
||||
use std::io::BufferedReader;
|
||||
use std::io::File;
|
||||
|
||||
# let _g = ::std::io::ignore_io_error();
|
||||
|
|
@ -74,7 +74,7 @@ Some examples of obvious things you might want to do
|
|||
* Pull the lines of a file into a vector of strings
|
||||
|
||||
```rust
|
||||
use std::io::buffered::BufferedReader;
|
||||
use std::io::BufferedReader;
|
||||
use std::io::File;
|
||||
|
||||
# let _g = ::std::io::ignore_io_error();
|
||||
|
|
@ -321,6 +321,11 @@ pub use self::net::udp::UdpStream;
|
|||
pub use self::pipe::PipeStream;
|
||||
pub use self::process::Process;
|
||||
|
||||
pub use self::mem::{MemReader, BufReader, MemWriter, BufWriter};
|
||||
pub use self::buffered::{BufferedReader, BufferedWriter, BufferedStream,
|
||||
LineBufferedWriter};
|
||||
pub use self::comm_adapters::{PortReader, ChanWriter};
|
||||
|
||||
/// Various utility functions useful for writing I/O tests
|
||||
pub mod test;
|
||||
|
||||
|
|
@ -337,7 +342,7 @@ pub mod process;
|
|||
pub mod net;
|
||||
|
||||
/// Readers and Writers for memory buffers and strings.
|
||||
pub mod mem;
|
||||
mod mem;
|
||||
|
||||
/// Non-blocking access to stdin, stdout, stderr
|
||||
pub mod stdio;
|
||||
|
|
@ -345,9 +350,6 @@ pub mod stdio;
|
|||
/// Implementations for Option
|
||||
mod option;
|
||||
|
||||
/// Basic stream compression. XXX: Belongs with other flate code
|
||||
pub mod flate;
|
||||
|
||||
/// Extension traits
|
||||
pub mod extensions;
|
||||
|
||||
|
|
@ -355,7 +357,7 @@ pub mod extensions;
|
|||
pub mod timer;
|
||||
|
||||
/// Buffered I/O wrappers
|
||||
pub mod buffered;
|
||||
mod buffered;
|
||||
|
||||
/// Signal handling
|
||||
pub mod signal;
|
||||
|
|
@ -364,9 +366,11 @@ pub mod signal;
|
|||
pub mod util;
|
||||
|
||||
/// Adapatation of Chan/Port types to a Writer/Reader type.
|
||||
pub mod comm_adapters;
|
||||
mod comm_adapters;
|
||||
|
||||
/// The default buffer size for various I/O operations
|
||||
// libuv recommends 64k buffers to maximize throughput
|
||||
// https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
|
||||
static DEFAULT_BUF_SIZE: uint = 1024 * 64;
|
||||
|
||||
/// The type passed to I/O condition handlers to indicate error
|
||||
|
|
@ -1098,11 +1102,10 @@ pub trait Buffer: Reader {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::buffered::BufferedReader;
|
||||
/// use std::io;
|
||||
/// use std::io::{BufferedReader, stdin};
|
||||
/// # let _g = ::std::io::ignore_io_error();
|
||||
///
|
||||
/// let mut reader = BufferedReader::new(io::stdin());
|
||||
/// let mut reader = BufferedReader::new(stdin());
|
||||
///
|
||||
/// let input = reader.read_line().unwrap_or(~"nothing");
|
||||
/// ```
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ out.write(bytes!("Hello, world!"));
|
|||
|
||||
use container::Container;
|
||||
use fmt;
|
||||
use io::buffered::LineBufferedWriter;
|
||||
use io::{Reader, Writer, io_error, IoError, OtherIoError,
|
||||
standard_error, EndOfFile};
|
||||
standard_error, EndOfFile, LineBufferedWriter};
|
||||
use libc;
|
||||
use option::{Option, Some, None};
|
||||
use prelude::drop;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use io::mem::{MemReader, MemWriter};
|
||||
use io::{MemReader, MemWriter};
|
||||
use super::*;
|
||||
use prelude::*;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue