2014-01-25 01:37:51 -06:00
|
|
|
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
2013-03-13 22:02:48 -05:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2014-02-22 17:53:54 -06:00
|
|
|
// FIXME: cover these topics:
|
|
|
|
// path, reader, writer, stream, raii (close not needed),
|
|
|
|
// stdio, print!, println!, file access, process spawning,
|
|
|
|
// error handling
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2014-02-22 17:53:54 -06:00
|
|
|
|
|
|
|
/*! I/O, including files, networking, timers, and processes
|
|
|
|
|
|
|
|
`std::io` provides Rust's basic I/O types,
|
|
|
|
for reading and writing to files, TCP, UDP,
|
|
|
|
and other types of sockets and pipes,
|
|
|
|
manipulating the file system, spawning processes and signal handling.
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
# Examples
|
|
|
|
|
|
|
|
Some examples of obvious things you might want to do
|
|
|
|
|
|
|
|
* Read lines from stdin
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
```rust
|
2014-02-20 11:11:56 -06:00
|
|
|
use std::io;
|
2013-12-22 15:31:23 -06:00
|
|
|
|
2014-02-20 11:11:56 -06:00
|
|
|
for line in io::stdin().lines() {
|
2014-01-09 04:06:55 -06:00
|
|
|
print!("{}", line);
|
2013-04-17 19:55:21 -05:00
|
|
|
}
|
2013-12-08 01:12:07 -06:00
|
|
|
```
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
* Read a complete file
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
```rust
|
2013-12-22 15:31:23 -06:00
|
|
|
use std::io::File;
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
let contents = File::open(&Path::new("message.txt")).read_to_end();
|
|
|
|
```
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
* Write a line to a file
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
```rust
|
2014-02-01 13:24:42 -06:00
|
|
|
# #[allow(unused_must_use)];
|
2013-12-22 15:31:23 -06:00
|
|
|
use std::io::File;
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
let mut file = File::create(&Path::new("message.txt"));
|
|
|
|
file.write(bytes!("hello, file!\n"));
|
2013-12-31 14:43:52 -06:00
|
|
|
# drop(file);
|
|
|
|
# ::std::io::fs::unlink(&Path::new("message.txt"));
|
2013-12-08 01:12:07 -06:00
|
|
|
```
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
* Iterate over the lines of a file
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
```rust
|
2014-01-15 15:25:09 -06:00
|
|
|
use std::io::BufferedReader;
|
2013-12-22 15:31:23 -06:00
|
|
|
use std::io::File;
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
let path = Path::new("message.txt");
|
|
|
|
let mut file = BufferedReader::new(File::open(&path));
|
|
|
|
for line in file.lines() {
|
2014-01-09 04:06:55 -06:00
|
|
|
print!("{}", line);
|
2013-12-08 01:12:07 -06:00
|
|
|
}
|
|
|
|
```
|
2013-04-19 20:47:31 -05:00
|
|
|
|
2013-04-17 19:55:21 -05:00
|
|
|
* Pull the lines of a file into a vector of strings
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
```rust
|
2014-01-15 15:25:09 -06:00
|
|
|
use std::io::BufferedReader;
|
2013-12-22 15:31:23 -06:00
|
|
|
use std::io::File;
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
let path = Path::new("message.txt");
|
|
|
|
let mut file = BufferedReader::new(File::open(&path));
|
|
|
|
let lines: ~[~str] = file.lines().collect();
|
|
|
|
```
|
2013-04-19 20:47:31 -05:00
|
|
|
|
2014-02-22 17:53:54 -06:00
|
|
|
* Make a simple TCP client connection and request
|
2013-04-19 20:47:31 -05:00
|
|
|
|
2013-12-23 00:33:39 -06:00
|
|
|
```rust,should_fail
|
2014-02-01 13:24:42 -06:00
|
|
|
# #[allow(unused_must_use)];
|
2013-12-22 15:31:23 -06:00
|
|
|
use std::io::net::ip::SocketAddr;
|
|
|
|
use std::io::net::tcp::TcpStream;
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
let addr = from_str::<SocketAddr>("127.0.0.1:8080").unwrap();
|
|
|
|
let mut socket = TcpStream::connect(addr).unwrap();
|
|
|
|
socket.write(bytes!("GET / HTTP/1.0\n\n"));
|
2013-04-19 20:47:31 -05:00
|
|
|
let response = socket.read_to_end();
|
2013-12-08 01:12:07 -06:00
|
|
|
```
|
2013-04-19 20:47:31 -05:00
|
|
|
|
2014-02-22 17:53:54 -06:00
|
|
|
* Make a simple TCP server
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
```rust
|
2014-02-22 17:53:54 -06:00
|
|
|
# fn main() { }
|
|
|
|
# fn foo() {
|
|
|
|
# #[allow(unused_must_use, dead_code)];
|
|
|
|
use std::io::net::tcp::TcpListener;
|
|
|
|
use std::io::net::ip::{Ipv4Addr, SocketAddr};
|
|
|
|
use std::io::{Acceptor, Listener};
|
|
|
|
|
|
|
|
let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 80 };
|
|
|
|
let listener = TcpListener::bind(addr);
|
|
|
|
|
|
|
|
// bind the listener to the specified address
|
|
|
|
let mut acceptor = listener.listen();
|
|
|
|
|
|
|
|
// accept connections and process them
|
|
|
|
# fn handle_client<T>(_: T) {}
|
|
|
|
for stream in acceptor.incoming() {
|
|
|
|
spawn(proc() {
|
|
|
|
handle_client(stream);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// close the socket server
|
|
|
|
drop(acceptor);
|
|
|
|
# }
|
2013-12-08 01:12:07 -06:00
|
|
|
```
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-04-23 21:21:37 -05:00
|
|
|
|
2013-04-17 19:55:21 -05:00
|
|
|
# Error Handling
|
|
|
|
|
2013-04-23 21:21:37 -05:00
|
|
|
I/O is an area where nearly every operation can result in unexpected
|
2014-01-30 18:55:20 -06:00
|
|
|
errors. Errors should be painfully visible when they happen, and handling them
|
|
|
|
should be easy to work with. It should be convenient to handle specific I/O
|
|
|
|
errors, and it should also be convenient to not deal with I/O errors.
|
2013-04-23 21:21:37 -05:00
|
|
|
|
|
|
|
Rust's I/O employs a combination of techniques to reduce boilerplate
|
|
|
|
while still providing feedback about errors. The basic strategy:
|
|
|
|
|
2014-01-30 18:55:20 -06:00
|
|
|
* All I/O operations return `IoResult<T>` which is equivalent to
|
2014-02-22 17:53:54 -06:00
|
|
|
`Result<T, IoError>`. The `Result` type is defined in the `std::result`
|
2014-01-30 18:55:20 -06:00
|
|
|
module.
|
|
|
|
* If the `Result` type goes unused, then the compiler will by default emit a
|
2014-02-22 17:53:54 -06:00
|
|
|
warning about the unused result. This is because `Result` has the
|
|
|
|
`#[must_use]` attribute.
|
2014-01-30 18:55:20 -06:00
|
|
|
* Common traits are implemented for `IoResult`, e.g.
|
|
|
|
`impl<R: Reader> Reader for IoResult<R>`, so that error values do not have
|
|
|
|
to be 'unwrapped' before use.
|
2013-04-23 21:21:37 -05:00
|
|
|
|
|
|
|
These features combine in the API to allow for expressions like
|
2014-01-02 06:35:08 -06:00
|
|
|
`File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"))`
|
|
|
|
without having to worry about whether "diary.txt" exists or whether
|
|
|
|
the write succeeds. As written, if either `new` or `write_line`
|
2014-01-30 18:55:20 -06:00
|
|
|
encounters an error then the result of the entire expression will
|
|
|
|
be an error.
|
2014-01-02 06:35:08 -06:00
|
|
|
|
|
|
|
If you wanted to handle the error though you might write:
|
|
|
|
|
|
|
|
```rust
|
2014-02-01 13:24:42 -06:00
|
|
|
# #[allow(unused_must_use)];
|
2014-01-02 06:35:08 -06:00
|
|
|
use std::io::File;
|
|
|
|
|
2014-01-30 18:55:20 -06:00
|
|
|
match File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n")) {
|
2014-02-22 17:53:54 -06:00
|
|
|
Ok(()) => (), // succeeded
|
2014-01-30 18:55:20 -06:00
|
|
|
Err(e) => println!("failed to write to my diary: {}", e),
|
2014-01-02 06:35:08 -06:00
|
|
|
}
|
2014-01-30 18:55:20 -06:00
|
|
|
|
2014-01-02 06:35:08 -06:00
|
|
|
# ::std::io::fs::unlink(&Path::new("diary.txt"));
|
|
|
|
```
|
2013-04-23 21:21:37 -05:00
|
|
|
|
2014-01-30 18:55:20 -06:00
|
|
|
So what actually happens if `create` encounters an error?
|
|
|
|
It's important to know that what `new` returns is not a `File`
|
|
|
|
but an `IoResult<File>`. If the file does not open, then `new` will simply
|
|
|
|
return `Err(..)`. Because there is an implementation of `Writer` (the trait
|
|
|
|
required ultimately required for types to implement `write_line`) there is no
|
|
|
|
need to inspect or unwrap the `IoResult<File>` and we simply call `write_line`
|
|
|
|
on it. If `new` returned an `Err(..)` then the followup call to `write_line`
|
|
|
|
will also return an error.
|
2013-04-23 21:21:37 -05:00
|
|
|
|
2013-04-17 19:55:21 -05:00
|
|
|
*/
|
|
|
|
|
2014-01-30 16:10:53 -06:00
|
|
|
#[deny(unused_must_use)];
|
2013-11-11 00:46:32 -06:00
|
|
|
|
2013-10-25 20:08:45 -05:00
|
|
|
use cast;
|
2014-01-04 07:26:03 -06:00
|
|
|
use char::Char;
|
2013-11-11 00:46:32 -06:00
|
|
|
use container::Container;
|
2014-01-29 18:33:57 -06:00
|
|
|
use fmt;
|
2013-10-25 20:08:45 -05:00
|
|
|
use int;
|
2013-11-11 00:46:32 -06:00
|
|
|
use iter::Iterator;
|
2013-10-25 19:04:37 -05:00
|
|
|
use option::{Option, Some, None};
|
2013-11-11 00:46:32 -06:00
|
|
|
use path::Path;
|
2013-10-25 19:04:37 -05:00
|
|
|
use result::{Ok, Err, Result};
|
2013-11-11 00:46:32 -06:00
|
|
|
use str::{StrSlice, OwnedStr};
|
2014-01-29 18:33:57 -06:00
|
|
|
use str;
|
2013-10-25 20:08:45 -05:00
|
|
|
use uint;
|
2014-02-07 05:33:11 -06:00
|
|
|
use unstable::finally::try_finally;
|
2014-01-28 16:40:36 -06:00
|
|
|
use vec::{OwnedVector, MutableVector, ImmutableVector, OwnedCloneableVector};
|
2013-10-25 20:08:45 -05:00
|
|
|
use vec;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
// Reexports
|
|
|
|
pub use self::stdio::stdin;
|
|
|
|
pub use self::stdio::stdout;
|
|
|
|
pub use self::stdio::stderr;
|
|
|
|
pub use self::stdio::print;
|
|
|
|
pub use self::stdio::println;
|
|
|
|
|
2013-10-31 17:15:30 -05:00
|
|
|
pub use self::fs::File;
|
2013-07-19 18:03:02 -05:00
|
|
|
pub use self::timer::Timer;
|
2013-04-17 19:55:21 -05:00
|
|
|
pub use self::net::ip::IpAddr;
|
|
|
|
pub use self::net::tcp::TcpListener;
|
|
|
|
pub use self::net::tcp::TcpStream;
|
|
|
|
pub use self::net::udp::UdpStream;
|
2013-09-16 17:28:56 -05:00
|
|
|
pub use self::pipe::PipeStream;
|
2014-02-18 14:04:51 -06:00
|
|
|
pub use self::process::{Process, ProcessConfig};
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2014-01-15 15:25:09 -06:00
|
|
|
pub use self::mem::{MemReader, BufReader, MemWriter, BufWriter};
|
|
|
|
pub use self::buffered::{BufferedReader, BufferedWriter, BufferedStream,
|
|
|
|
LineBufferedWriter};
|
|
|
|
pub use self::comm_adapters::{PortReader, ChanWriter};
|
|
|
|
|
2013-12-13 13:30:59 -06:00
|
|
|
pub mod test;
|
2013-12-12 23:38:57 -06:00
|
|
|
|
2013-10-31 17:15:30 -05:00
|
|
|
pub mod fs;
|
2013-03-13 22:02:48 -05:00
|
|
|
|
2013-09-16 17:28:56 -05:00
|
|
|
pub mod pipe;
|
|
|
|
|
|
|
|
pub mod process;
|
|
|
|
|
2013-09-05 16:16:17 -05:00
|
|
|
pub mod net;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2014-01-15 15:25:09 -06:00
|
|
|
mod mem;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
|
|
|
pub mod stdio;
|
|
|
|
|
2014-01-29 18:33:57 -06:00
|
|
|
mod result;
|
2013-04-22 16:52:40 -05:00
|
|
|
|
2013-10-09 01:36:26 -05:00
|
|
|
pub mod extensions;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-07-19 18:22:13 -05:00
|
|
|
pub mod timer;
|
2013-07-19 18:03:02 -05:00
|
|
|
|
2014-01-15 15:25:09 -06:00
|
|
|
mod buffered;
|
2013-09-10 00:38:43 -05:00
|
|
|
|
2013-09-18 23:03:50 -05:00
|
|
|
pub mod signal;
|
|
|
|
|
2013-12-10 00:53:09 -06:00
|
|
|
pub mod util;
|
|
|
|
|
2014-01-15 15:25:09 -06:00
|
|
|
mod comm_adapters;
|
2013-12-19 17:42:44 -06:00
|
|
|
|
2013-05-13 18:56:16 -05:00
|
|
|
/// The default buffer size for various I/O operations
|
2014-01-15 15:25:09 -06:00
|
|
|
// libuv recommends 64k buffers to maximize throughput
|
|
|
|
// https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
|
2013-10-15 22:55:50 -05:00
|
|
|
static DEFAULT_BUF_SIZE: uint = 1024 * 64;
|
2013-05-13 18:56:16 -05:00
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// A convenient typedef of the return value of any I/O action.
|
2014-01-29 18:33:57 -06:00
|
|
|
pub type IoResult<T> = Result<T, IoError>;
|
|
|
|
|
2013-04-17 19:55:21 -05:00
|
|
|
/// The type passed to I/O condition handlers to indicate error
|
|
|
|
///
|
2014-01-26 02:43:42 -06:00
|
|
|
/// # FIXME
|
2013-04-17 19:55:21 -05:00
|
|
|
///
|
|
|
|
/// Is something like this sufficient? It's kind of archaic
|
2014-01-29 18:33:57 -06:00
|
|
|
#[deriving(Eq, Clone)]
|
2013-04-17 19:55:21 -05:00
|
|
|
pub struct IoError {
|
2014-02-24 02:31:08 -06:00
|
|
|
/// An enumeration which can be matched against for determining the flavor
|
|
|
|
/// of error.
|
2013-04-17 19:55:21 -05:00
|
|
|
kind: IoErrorKind,
|
2014-02-24 02:31:08 -06:00
|
|
|
/// A human-readable description about the error
|
2013-04-17 19:55:21 -05:00
|
|
|
desc: &'static str,
|
2014-02-24 02:31:08 -06:00
|
|
|
/// Detailed information about this error, not always available
|
2013-04-17 19:55:21 -05:00
|
|
|
detail: Option<~str>
|
|
|
|
}
|
|
|
|
|
2014-02-01 13:24:42 -06:00
|
|
|
impl fmt::Show for IoError {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
2014-02-19 12:07:49 -06:00
|
|
|
try!(fmt.buf.write_str(self.desc));
|
2014-02-05 06:55:13 -06:00
|
|
|
match self.detail {
|
2014-01-29 18:33:57 -06:00
|
|
|
Some(ref s) => write!(fmt.buf, " ({})", *s),
|
|
|
|
None => Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-19 20:56:33 -06:00
|
|
|
#[deriving(Eq, Clone, Show)]
|
2014-02-24 02:31:08 -06:00
|
|
|
#[allow(missing_doc)]
|
2013-04-17 19:55:21 -05:00
|
|
|
pub enum IoErrorKind {
|
2013-04-24 22:20:03 -05:00
|
|
|
OtherIoError,
|
|
|
|
EndOfFile,
|
2013-04-17 19:55:21 -05:00
|
|
|
FileNotFound,
|
2013-04-24 22:20:03 -05:00
|
|
|
PermissionDenied,
|
2013-04-17 19:55:21 -05:00
|
|
|
ConnectionFailed,
|
|
|
|
Closed,
|
2013-04-24 22:20:03 -05:00
|
|
|
ConnectionRefused,
|
2013-05-14 23:18:47 -05:00
|
|
|
ConnectionReset,
|
2013-10-26 18:04:05 -05:00
|
|
|
ConnectionAborted,
|
2013-10-04 16:10:02 -05:00
|
|
|
NotConnected,
|
2013-09-15 14:23:53 -05:00
|
|
|
BrokenPipe,
|
|
|
|
PathAlreadyExists,
|
|
|
|
PathDoesntExist,
|
2013-10-16 19:05:28 -05:00
|
|
|
MismatchedFileTypeForOperation,
|
2013-10-17 19:04:51 -05:00
|
|
|
ResourceUnavailable,
|
2013-10-16 19:05:28 -05:00
|
|
|
IoUnavailable,
|
2013-12-08 13:12:25 -06:00
|
|
|
InvalidInput,
|
2013-04-17 19:55:21 -05:00
|
|
|
}
|
2013-03-13 22:02:48 -05:00
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// A trait for objects which are byte-oriented streams. Readers are defined by
|
|
|
|
/// one method, `read`. This function will block until data is available,
|
|
|
|
/// filling in the provided buffer with any data read.
|
|
|
|
///
|
|
|
|
/// Readers are intended to be composable with one another. Many objects
|
|
|
|
/// throughout the I/O and related libraries take and provide types which
|
|
|
|
/// implement the `Reader` trait.
|
2013-04-17 19:55:21 -05:00
|
|
|
pub trait Reader {
|
2013-10-25 20:08:45 -05:00
|
|
|
|
2014-01-30 18:55:20 -06:00
|
|
|
// Only method which need to get implemented for this trait
|
2013-10-25 20:08:45 -05:00
|
|
|
|
2013-04-17 19:55:21 -05:00
|
|
|
/// Read bytes, up to the length of `buf` and place them in `buf`.
|
2013-05-12 23:24:48 -05:00
|
|
|
/// Returns the number of bytes read. The number of bytes read my
|
2014-01-30 18:55:20 -06:00
|
|
|
/// be less than the number requested, even 0. Returns `Err` on EOF.
|
2013-03-13 22:02:48 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-04-17 19:55:21 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// If an error occurs during this I/O operation, then it is returned as
|
|
|
|
/// `Err(IoError)`. Note that end-of-file is considered an error, and can be
|
|
|
|
/// inspected for in the error's `kind` field. Also note that reading 0
|
|
|
|
/// bytes is not considered an error in all circumstances
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
|
2013-03-13 22:02:48 -05:00
|
|
|
|
2013-10-25 20:08:45 -05:00
|
|
|
// Convenient helper methods based on the above methods
|
|
|
|
|
2014-01-30 18:55:20 -06:00
|
|
|
/// Reads a single byte. Returns `Err` on EOF.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_byte(&mut self) -> IoResult<u8> {
|
2013-10-25 20:08:45 -05:00
|
|
|
let mut buf = [0];
|
2014-01-29 18:33:57 -06:00
|
|
|
loop {
|
|
|
|
match self.read(buf) {
|
|
|
|
Ok(0) => {
|
|
|
|
debug!("read 0 bytes. trying again");
|
|
|
|
}
|
|
|
|
Ok(1) => return Ok(buf[0]),
|
|
|
|
Ok(_) => unreachable!(),
|
|
|
|
Err(e) => return Err(e)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads `len` bytes and appends them to a vector.
|
|
|
|
///
|
|
|
|
/// May push fewer than the requested number of bytes on error
|
2014-01-30 18:55:20 -06:00
|
|
|
/// or EOF. If `Ok(())` is returned, then all of the requested bytes were
|
|
|
|
/// pushed on to the vector, otherwise the amount `len` bytes couldn't be
|
|
|
|
/// read (an error was encountered), and the error is returned.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> IoResult<()> {
|
2014-02-07 05:33:11 -06:00
|
|
|
struct State<'a> {
|
|
|
|
buf: &'a mut ~[u8],
|
|
|
|
total_read: uint
|
|
|
|
}
|
|
|
|
|
2014-01-29 18:33:57 -06:00
|
|
|
let start_len = buf.len();
|
2014-02-07 05:33:11 -06:00
|
|
|
let mut s = State { buf: buf, total_read: 0 };
|
|
|
|
|
|
|
|
s.buf.reserve_additional(len);
|
|
|
|
unsafe { s.buf.set_len(start_len + len); }
|
|
|
|
|
|
|
|
try_finally(
|
|
|
|
&mut s, (),
|
|
|
|
|s, _| {
|
|
|
|
while s.total_read < len {
|
|
|
|
let len = s.buf.len();
|
|
|
|
let slice = s.buf.mut_slice(start_len + s.total_read, len);
|
|
|
|
match self.read(slice) {
|
|
|
|
Ok(nread) => {
|
|
|
|
s.total_read += nread;
|
|
|
|
}
|
|
|
|
Err(e) => return Err(e)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
}
|
2014-02-07 05:33:11 -06:00
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
|s| unsafe { s.buf.set_len(start_len + s.total_read) })
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads `len` bytes and gives you back a new vector of length `len`
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-10-25 20:08:45 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// Fails with the same conditions as `read`. Additionally returns error on
|
|
|
|
/// on EOF. Note that if an error is returned, then some number of bytes may
|
|
|
|
/// have already been consumed from the underlying reader, and they are lost
|
|
|
|
/// (not returned as part of the error). If this is unacceptable, then it is
|
|
|
|
/// recommended to use the `push_bytes` or `read` methods.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_bytes(&mut self, len: uint) -> IoResult<~[u8]> {
|
2013-10-25 20:08:45 -05:00
|
|
|
let mut buf = vec::with_capacity(len);
|
2014-01-30 18:55:20 -06:00
|
|
|
match self.push_bytes(&mut buf, len) {
|
|
|
|
Ok(()) => Ok(buf),
|
|
|
|
Err(e) => Err(e),
|
|
|
|
}
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads all remaining bytes from the stream.
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
|
|
|
///
|
|
|
|
/// Returns any non-EOF error immediately. Previously read bytes are
|
|
|
|
/// discarded when an error is returned.
|
2013-10-25 20:08:45 -05:00
|
|
|
///
|
2014-02-01 13:24:42 -06:00
|
|
|
/// When EOF is encountered, all bytes read up to that point are returned.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_to_end(&mut self) -> IoResult<~[u8]> {
|
2013-10-25 20:08:45 -05:00
|
|
|
let mut buf = vec::with_capacity(DEFAULT_BUF_SIZE);
|
2014-01-29 18:33:57 -06:00
|
|
|
loop {
|
|
|
|
match self.push_bytes(&mut buf, DEFAULT_BUF_SIZE) {
|
|
|
|
Ok(()) => {}
|
2014-02-01 13:24:42 -06:00
|
|
|
Err(ref e) if e.kind == EndOfFile => break,
|
2014-01-29 18:33:57 -06:00
|
|
|
Err(e) => return Err(e)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
2014-01-29 18:33:57 -06:00
|
|
|
}
|
|
|
|
return Ok(buf);
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
2013-12-08 13:12:25 -06:00
|
|
|
/// Reads all of the remaining bytes of this stream, interpreting them as a
|
|
|
|
/// UTF-8 encoded stream. The corresponding string is returned.
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-12-08 13:12:25 -06:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// This function returns all of the same errors as `read_to_end` with an
|
|
|
|
/// additional error if the reader's contents are not a valid sequence of
|
|
|
|
/// UTF-8 bytes.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_to_str(&mut self) -> IoResult<~str> {
|
|
|
|
self.read_to_end().and_then(|s| {
|
|
|
|
match str::from_utf8_owned(s) {
|
|
|
|
Some(s) => Ok(s),
|
|
|
|
None => Err(standard_error(InvalidInput)),
|
2013-12-08 13:12:25 -06:00
|
|
|
}
|
2014-01-29 18:33:57 -06:00
|
|
|
})
|
2013-12-08 13:12:25 -06:00
|
|
|
}
|
|
|
|
|
2013-10-25 20:08:45 -05:00
|
|
|
/// Create an iterator that reads a single byte on
|
|
|
|
/// each iteration, until EOF.
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-10-25 20:08:45 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// The iterator protocol causes all specifics about errors encountered to
|
|
|
|
/// be swallowed. All errors will be signified by returning `None` from the
|
|
|
|
/// iterator. If this is undesirable, it is recommended to use the
|
|
|
|
/// `read_byte` method.
|
2014-01-14 21:32:24 -06:00
|
|
|
fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, Self> {
|
|
|
|
extensions::Bytes::new(self)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Byte conversion helpers
|
|
|
|
|
|
|
|
/// Reads `n` little-endian unsigned integer bytes.
|
|
|
|
///
|
|
|
|
/// `n` must be between 1 and 8, inclusive.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
|
2013-10-25 20:08:45 -05:00
|
|
|
assert!(nbytes > 0 && nbytes <= 8);
|
|
|
|
|
|
|
|
let mut val = 0u64;
|
|
|
|
let mut pos = 0;
|
|
|
|
let mut i = nbytes;
|
|
|
|
while i > 0 {
|
2014-02-19 12:07:49 -06:00
|
|
|
val += (try!(self.read_u8()) as u64) << pos;
|
2013-10-25 20:08:45 -05:00
|
|
|
pos += 8;
|
|
|
|
i -= 1;
|
|
|
|
}
|
2014-01-29 18:33:57 -06:00
|
|
|
Ok(val)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads `n` little-endian signed integer bytes.
|
|
|
|
///
|
|
|
|
/// `n` must be between 1 and 8, inclusive.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
|
|
|
|
self.read_le_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads `n` big-endian unsigned integer bytes.
|
|
|
|
///
|
|
|
|
/// `n` must be between 1 and 8, inclusive.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
|
2013-10-25 20:08:45 -05:00
|
|
|
assert!(nbytes > 0 && nbytes <= 8);
|
|
|
|
|
|
|
|
let mut val = 0u64;
|
|
|
|
let mut i = nbytes;
|
|
|
|
while i > 0 {
|
|
|
|
i -= 1;
|
2014-02-19 12:07:49 -06:00
|
|
|
val += (try!(self.read_u8()) as u64) << i * 8;
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
2014-01-29 18:33:57 -06:00
|
|
|
Ok(val)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads `n` big-endian signed integer bytes.
|
|
|
|
///
|
|
|
|
/// `n` must be between 1 and 8, inclusive.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
|
|
|
|
self.read_be_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian unsigned integer.
|
|
|
|
///
|
|
|
|
/// The number of bytes returned is system-dependant.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_uint(&mut self) -> IoResult<uint> {
|
|
|
|
self.read_le_uint_n(uint::BYTES).map(|i| i as uint)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian integer.
|
|
|
|
///
|
|
|
|
/// The number of bytes returned is system-dependant.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_int(&mut self) -> IoResult<int> {
|
|
|
|
self.read_le_int_n(int::BYTES).map(|i| i as int)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian unsigned integer.
|
|
|
|
///
|
|
|
|
/// The number of bytes returned is system-dependant.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_uint(&mut self) -> IoResult<uint> {
|
|
|
|
self.read_be_uint_n(uint::BYTES).map(|i| i as uint)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian integer.
|
|
|
|
///
|
|
|
|
/// The number of bytes returned is system-dependant.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_int(&mut self) -> IoResult<int> {
|
|
|
|
self.read_be_int_n(int::BYTES).map(|i| i as int)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian `u64`.
|
|
|
|
///
|
|
|
|
/// `u64`s are 8 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_u64(&mut self) -> IoResult<u64> {
|
2013-12-24 17:53:05 -06:00
|
|
|
self.read_be_uint_n(8)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian `u32`.
|
|
|
|
///
|
|
|
|
/// `u32`s are 4 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_u32(&mut self) -> IoResult<u32> {
|
|
|
|
self.read_be_uint_n(4).map(|i| i as u32)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian `u16`.
|
|
|
|
///
|
|
|
|
/// `u16`s are 2 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_u16(&mut self) -> IoResult<u16> {
|
|
|
|
self.read_be_uint_n(2).map(|i| i as u16)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian `i64`.
|
|
|
|
///
|
|
|
|
/// `i64`s are 8 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_i64(&mut self) -> IoResult<i64> {
|
2013-12-24 17:53:05 -06:00
|
|
|
self.read_be_int_n(8)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian `i32`.
|
|
|
|
///
|
|
|
|
/// `i32`s are 4 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_i32(&mut self) -> IoResult<i32> {
|
|
|
|
self.read_be_int_n(4).map(|i| i as i32)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian `i16`.
|
|
|
|
///
|
|
|
|
/// `i16`s are 2 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_i16(&mut self) -> IoResult<i16> {
|
|
|
|
self.read_be_int_n(2).map(|i| i as i16)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian `f64`.
|
|
|
|
///
|
|
|
|
/// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_f64(&mut self) -> IoResult<f64> {
|
|
|
|
self.read_be_u64().map(|i| unsafe {
|
|
|
|
cast::transmute::<u64, f64>(i)
|
|
|
|
})
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big-endian `f32`.
|
|
|
|
///
|
|
|
|
/// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_be_f32(&mut self) -> IoResult<f32> {
|
|
|
|
self.read_be_u32().map(|i| unsafe {
|
|
|
|
cast::transmute::<u32, f32>(i)
|
|
|
|
})
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian `u64`.
|
|
|
|
///
|
|
|
|
/// `u64`s are 8 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_u64(&mut self) -> IoResult<u64> {
|
2013-12-24 17:53:05 -06:00
|
|
|
self.read_le_uint_n(8)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian `u32`.
|
|
|
|
///
|
|
|
|
/// `u32`s are 4 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_u32(&mut self) -> IoResult<u32> {
|
|
|
|
self.read_le_uint_n(4).map(|i| i as u32)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian `u16`.
|
|
|
|
///
|
|
|
|
/// `u16`s are 2 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_u16(&mut self) -> IoResult<u16> {
|
|
|
|
self.read_le_uint_n(2).map(|i| i as u16)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian `i64`.
|
|
|
|
///
|
|
|
|
/// `i64`s are 8 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_i64(&mut self) -> IoResult<i64> {
|
2013-12-24 17:53:05 -06:00
|
|
|
self.read_le_int_n(8)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian `i32`.
|
|
|
|
///
|
|
|
|
/// `i32`s are 4 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_i32(&mut self) -> IoResult<i32> {
|
|
|
|
self.read_le_int_n(4).map(|i| i as i32)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian `i16`.
|
|
|
|
///
|
|
|
|
/// `i16`s are 2 bytes long.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_i16(&mut self) -> IoResult<i16> {
|
|
|
|
self.read_le_int_n(2).map(|i| i as i16)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian `f64`.
|
|
|
|
///
|
|
|
|
/// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_f64(&mut self) -> IoResult<f64> {
|
|
|
|
self.read_le_u64().map(|i| unsafe {
|
|
|
|
cast::transmute::<u64, f64>(i)
|
|
|
|
})
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a little-endian `f32`.
|
|
|
|
///
|
|
|
|
/// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_le_f32(&mut self) -> IoResult<f32> {
|
|
|
|
self.read_le_u32().map(|i| unsafe {
|
|
|
|
cast::transmute::<u32, f32>(i)
|
|
|
|
})
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Read a u8.
|
|
|
|
///
|
|
|
|
/// `u8`s are 1 byte.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_u8(&mut self) -> IoResult<u8> {
|
|
|
|
self.read_byte()
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Read an i8.
|
|
|
|
///
|
|
|
|
/// `i8`s are 1 byte.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_i8(&mut self) -> IoResult<i8> {
|
|
|
|
self.read_byte().map(|i| i as i8)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
2014-02-13 22:27:53 -06:00
|
|
|
/// Creates a wrapper around a mutable reference to the reader.
|
|
|
|
///
|
|
|
|
/// This is useful to allow applying adaptors while still
|
|
|
|
/// retaining ownership of the original value.
|
|
|
|
fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> {
|
|
|
|
RefReader { inner: self }
|
|
|
|
}
|
2013-04-17 19:55:21 -05:00
|
|
|
}
|
2013-03-13 22:02:48 -05:00
|
|
|
|
2013-10-06 18:08:56 -05:00
|
|
|
impl Reader for ~Reader {
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
|
2013-10-06 18:08:56 -05:00
|
|
|
}
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
impl<'a> Reader for &'a mut Reader {
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
|
2013-10-06 18:08:56 -05:00
|
|
|
}
|
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// A `RefReader` is a struct implementing `Reader` which contains a reference
|
|
|
|
/// to another reader. This is often useful when composing streams.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # fn main() {}
|
|
|
|
/// # fn process_input<R: Reader>(r: R) {}
|
|
|
|
/// # fn foo() {
|
|
|
|
/// use std::io;
|
|
|
|
/// use std::io::util::LimitReader;
|
|
|
|
///
|
|
|
|
/// let mut stream = io::stdin();
|
|
|
|
///
|
|
|
|
/// // Only allow the function to process at most one kilobyte of input
|
|
|
|
/// {
|
|
|
|
/// let stream = LimitReader::new(stream.by_ref(), 1024);
|
|
|
|
/// process_input(stream);
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// // 'stream' is still available for use here
|
|
|
|
///
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2014-02-13 22:27:53 -06:00
|
|
|
pub struct RefReader<'a, R> {
|
2014-02-24 02:31:08 -06:00
|
|
|
/// The underlying reader which this is referencing
|
|
|
|
inner: &'a mut R
|
2014-02-13 22:27:53 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, R: Reader> Reader for RefReader<'a, R> {
|
|
|
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
|
|
|
|
}
|
|
|
|
|
2013-10-25 20:08:45 -05:00
|
|
|
fn extend_sign(val: u64, nbytes: uint) -> i64 {
|
|
|
|
let shift = (8 - nbytes) * 8;
|
|
|
|
(val << shift) as i64 >> shift
|
|
|
|
}
|
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// A trait for objects which are byte-oriented streams. Writers are defined by
|
|
|
|
/// one method, `write`. This function will block until the provided buffer of
|
|
|
|
/// bytes has been entirely written, and it will return any failurs which occur.
|
|
|
|
///
|
|
|
|
/// Another commonly overriden method is the `flush` method for writers such as
|
|
|
|
/// buffered writers.
|
|
|
|
///
|
|
|
|
/// Writers are intended to be composable with one another. Many objects
|
|
|
|
/// throughout the I/O and related libraries take and provide types which
|
|
|
|
/// implement the `Writer` trait.
|
2013-04-17 19:55:21 -05:00
|
|
|
pub trait Writer {
|
2014-01-30 18:55:20 -06:00
|
|
|
/// Write the entirety of a given buffer
|
2013-03-13 22:02:48 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Errors
|
2013-03-13 22:02:48 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// If an error happens during the I/O operation, the error is returned as
|
|
|
|
/// `Err`. Note that it is considered an error if the entire buffer could
|
|
|
|
/// not be written, and if an error is returned then it is unknown how much
|
|
|
|
/// data (if any) was actually written.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write(&mut self, buf: &[u8]) -> IoResult<()>;
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-10-30 17:10:32 -05:00
|
|
|
/// Flush this output stream, ensuring that all intermediately buffered
|
|
|
|
/// contents reach their destination.
|
|
|
|
///
|
2013-12-14 23:26:09 -06:00
|
|
|
/// This is by default a no-op and implementers of the `Writer` trait should
|
2013-10-30 17:10:32 -05:00
|
|
|
/// decide whether their stream needs to be buffered or not.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn flush(&mut self) -> IoResult<()> { Ok(()) }
|
2013-10-25 20:08:45 -05:00
|
|
|
|
2013-12-08 13:12:25 -06:00
|
|
|
/// Write a rust string into this sink.
|
|
|
|
///
|
|
|
|
/// The bytes written will be the UTF-8 encoded version of the input string.
|
|
|
|
/// If other encodings are desired, it is recommended to compose this stream
|
|
|
|
/// with another performing the conversion, or to use `write` with a
|
|
|
|
/// converted byte-array instead.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_str(&mut self, s: &str) -> IoResult<()> {
|
|
|
|
self.write(s.as_bytes())
|
2013-12-08 13:12:25 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Writes a string into this sink, and then writes a literal newline (`\n`)
|
|
|
|
/// byte afterwards. Note that the writing of the newline is *not* atomic in
|
|
|
|
/// the sense that the call to `write` is invoked twice (once with the
|
|
|
|
/// string and once with a newline character).
|
|
|
|
///
|
|
|
|
/// If other encodings or line ending flavors are desired, it is recommended
|
|
|
|
/// that the `write` method is used specifically instead.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_line(&mut self, s: &str) -> IoResult<()> {
|
|
|
|
self.write_str(s).and_then(|()| self.write(['\n' as u8]))
|
2013-12-08 13:12:25 -06:00
|
|
|
}
|
|
|
|
|
2014-01-04 07:26:03 -06:00
|
|
|
/// Write a single char, encoded as UTF-8.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_char(&mut self, c: char) -> IoResult<()> {
|
2014-01-04 07:26:03 -06:00
|
|
|
let mut buf = [0u8, ..4];
|
|
|
|
let n = c.encode_utf8(buf.as_mut_slice());
|
2014-01-29 18:33:57 -06:00
|
|
|
self.write(buf.slice_to(n))
|
2014-01-04 07:26:03 -06:00
|
|
|
}
|
|
|
|
|
2013-10-25 20:08:45 -05:00
|
|
|
/// Write the result of passing n through `int::to_str_bytes`.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_int(&mut self, n: int) -> IoResult<()> {
|
2014-02-21 10:53:18 -06:00
|
|
|
write!(self, "{:d}", n)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write the result of passing n through `uint::to_str_bytes`.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_uint(&mut self, n: uint) -> IoResult<()> {
|
2014-02-21 10:53:18 -06:00
|
|
|
write!(self, "{:u}", n)
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian uint (number of bytes depends on system).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
|
2014-01-25 01:37:51 -06:00
|
|
|
extensions::u64_to_le_bytes(n as u64, uint::BYTES, |v| self.write(v))
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian int (number of bytes depends on system).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_int(&mut self, n: int) -> IoResult<()> {
|
2014-01-25 01:37:51 -06:00
|
|
|
extensions::u64_to_le_bytes(n as u64, int::BYTES, |v| self.write(v))
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian uint (number of bytes depends on system).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
|
2014-01-25 01:37:51 -06:00
|
|
|
extensions::u64_to_be_bytes(n as u64, uint::BYTES, |v| self.write(v))
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian int (number of bytes depends on system).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_int(&mut self, n: int) -> IoResult<()> {
|
2014-01-25 01:37:51 -06:00
|
|
|
extensions::u64_to_be_bytes(n as u64, int::BYTES, |v| self.write(v))
|
2013-10-25 20:08:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian u64 (8 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_u64(&mut self, n: u64) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_be_bytes(n, 8u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian u32 (4 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_u32(&mut self, n: u32) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian u16 (2 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_u16(&mut self, n: u16) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian i64 (8 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_i64(&mut self, n: i64) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian i32 (4 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_i32(&mut self, n: i32) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian i16 (2 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_i16(&mut self, n: i16) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_f64(&mut self, f: f64) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
unsafe {
|
|
|
|
self.write_be_u64(cast::transmute(f))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_be_f32(&mut self, f: f32) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
unsafe {
|
|
|
|
self.write_be_u32(cast::transmute(f))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian u64 (8 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_u64(&mut self, n: u64) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_le_bytes(n, 8u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian u32 (4 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_u32(&mut self, n: u32) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian u16 (2 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_u16(&mut self, n: u16) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian i64 (8 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_i64(&mut self, n: i64) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian i32 (4 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_i32(&mut self, n: i32) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian i16 (2 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_i16(&mut self, n: i16) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian IEEE754 double-precision floating-point
|
|
|
|
/// (8 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_f64(&mut self, f: f64) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
unsafe {
|
|
|
|
self.write_le_u64(cast::transmute(f))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a little-endian IEEE754 single-precision floating-point
|
|
|
|
/// (4 bytes).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_le_f32(&mut self, f: f32) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
unsafe {
|
|
|
|
self.write_le_u32(cast::transmute(f))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a u8 (1 byte).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_u8(&mut self, n: u8) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
self.write([n])
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a i8 (1 byte).
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write_i8(&mut self, n: i8) -> IoResult<()> {
|
2013-10-25 20:08:45 -05:00
|
|
|
self.write([n as u8])
|
|
|
|
}
|
2014-02-13 22:27:53 -06:00
|
|
|
|
|
|
|
/// Creates a wrapper around a mutable reference to the writer.
|
|
|
|
///
|
|
|
|
/// This is useful to allow applying wrappers while still
|
|
|
|
/// retaining ownership of the original value.
|
|
|
|
fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
|
|
|
|
RefWriter { inner: self }
|
|
|
|
}
|
2013-04-17 19:55:21 -05:00
|
|
|
}
|
|
|
|
|
2013-10-06 18:08:56 -05:00
|
|
|
impl Writer for ~Writer {
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
|
|
|
|
fn flush(&mut self) -> IoResult<()> { self.flush() }
|
2013-10-06 18:08:56 -05:00
|
|
|
}
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
impl<'a> Writer for &'a mut Writer {
|
2014-01-29 18:33:57 -06:00
|
|
|
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
|
|
|
|
fn flush(&mut self) -> IoResult<()> { self.flush() }
|
2013-10-06 18:08:56 -05:00
|
|
|
}
|
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// A `RefWriter` is a struct implementing `Writer` which contains a reference
|
|
|
|
/// to another writer. This is often useful when composing streams.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # fn main() {}
|
|
|
|
/// # fn process_input<R: Reader>(r: R) {}
|
|
|
|
/// # fn foo () {
|
|
|
|
/// use std::io::util::TeeReader;
|
|
|
|
/// use std::io::{stdin, MemWriter};
|
|
|
|
///
|
|
|
|
/// let mut output = MemWriter::new();
|
|
|
|
///
|
|
|
|
/// {
|
|
|
|
/// // Don't give ownership of 'output' to the 'tee'. Instead we keep a
|
|
|
|
/// // handle to it in the outer scope
|
|
|
|
/// let mut tee = TeeReader::new(stdin(), output.by_ref());
|
|
|
|
/// process_input(tee);
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// println!("input processed: {}", output.unwrap());
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2014-02-13 22:27:53 -06:00
|
|
|
pub struct RefWriter<'a, W> {
|
2014-02-24 02:31:08 -06:00
|
|
|
/// The underlying writer which this is referencing
|
2014-02-13 22:27:53 -06:00
|
|
|
inner: &'a mut W
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, W: Writer> Writer for RefWriter<'a, W> {
|
|
|
|
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
|
|
|
|
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// A Stream is a readable and a writable object. Data written is typically
|
|
|
|
/// received by the object which reads receive data from.
|
2013-04-24 20:26:49 -05:00
|
|
|
pub trait Stream: Reader + Writer { }
|
2013-04-17 19:55:21 -05:00
|
|
|
|
2013-09-19 14:09:52 -05:00
|
|
|
impl<T: Reader + Writer> Stream for T {}
|
2013-09-04 19:52:18 -05:00
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
/// An iterator that reads a line on each iteration,
|
|
|
|
/// until `.read_line()` returns `None`.
|
|
|
|
///
|
|
|
|
/// # Notes about the Iteration Protocol
|
|
|
|
///
|
2014-01-14 21:32:24 -06:00
|
|
|
/// The `Lines` may yield `None` and thus terminate
|
2013-12-08 01:12:07 -06:00
|
|
|
/// an iteration, but continue to yield elements if iteration
|
|
|
|
/// is attempted again.
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-12-08 01:12:07 -06:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// This iterator will swallow all I/O errors, transforming `Err` values to
|
|
|
|
/// `None`. If errors need to be handled, it is recommended to use the
|
|
|
|
/// `read_line` method directly.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct Lines<'r, T> {
|
2013-12-08 01:12:07 -06:00
|
|
|
priv buffer: &'r mut T,
|
|
|
|
}
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
impl<'r, T: Buffer> Iterator<~str> for Lines<'r, T> {
|
2013-12-08 01:12:07 -06:00
|
|
|
fn next(&mut self) -> Option<~str> {
|
2014-01-29 18:33:57 -06:00
|
|
|
self.buffer.read_line().ok()
|
2013-12-08 01:12:07 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-08 23:40:38 -06:00
|
|
|
/// An iterator that reads a utf8-encoded character on each iteration,
|
|
|
|
/// until `.read_char()` returns `None`.
|
|
|
|
///
|
|
|
|
/// # Notes about the Iteration Protocol
|
|
|
|
///
|
|
|
|
/// The `Chars` may yield `None` and thus terminate
|
|
|
|
/// an iteration, but continue to yield elements if iteration
|
|
|
|
/// is attempted again.
|
|
|
|
///
|
|
|
|
/// # Error
|
|
|
|
///
|
|
|
|
/// This iterator will swallow all I/O errors, transforming `Err` values to
|
|
|
|
/// `None`. If errors need to be handled, it is recommended to use the
|
|
|
|
/// `read_char` method directly.
|
|
|
|
pub struct Chars<'r, T> {
|
|
|
|
priv buffer: &'r mut T
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'r, T: Buffer> Iterator<char> for Chars<'r, T> {
|
|
|
|
fn next(&mut self) -> Option<char> {
|
|
|
|
self.buffer.read_char().ok()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-13 13:17:58 -06:00
|
|
|
/// A Buffer is a type of reader which has some form of internal buffering to
|
|
|
|
/// allow certain kinds of reading operations to be more optimized than others.
|
|
|
|
/// This type extends the `Reader` trait with a few methods that are not
|
|
|
|
/// possible to reasonably implement with purely a read interface.
|
|
|
|
pub trait Buffer: Reader {
|
|
|
|
/// Fills the internal buffer of this object, returning the buffer contents.
|
|
|
|
/// Note that none of the contents will be "read" in the sense that later
|
|
|
|
/// calling `read` may return the same contents.
|
|
|
|
///
|
|
|
|
/// The `consume` function must be called with the number of bytes that are
|
|
|
|
/// consumed from this buffer returned to ensure that the bytes are never
|
|
|
|
/// returned twice.
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-11-13 13:17:58 -06:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// This function will return an I/O error if the underlying reader was
|
|
|
|
/// read, but returned an error. Note that it is not an error to return a
|
|
|
|
/// 0-length buffer.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]>;
|
2013-11-13 13:17:58 -06:00
|
|
|
|
|
|
|
/// Tells this buffer that `amt` bytes have been consumed from the buffer,
|
|
|
|
/// so they should no longer be returned in calls to `fill` or `read`.
|
|
|
|
fn consume(&mut self, amt: uint);
|
|
|
|
|
2013-12-08 13:12:25 -06:00
|
|
|
/// Reads the next line of input, interpreted as a sequence of UTF-8
|
2013-11-13 13:17:58 -06:00
|
|
|
/// encoded unicode codepoints. If a newline is encountered, then the
|
|
|
|
/// newline is contained in the returned string.
|
|
|
|
///
|
2014-01-02 06:35:08 -06:00
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2014-02-20 11:11:56 -06:00
|
|
|
/// use std::io;
|
2014-01-02 06:35:08 -06:00
|
|
|
///
|
2014-02-20 11:11:56 -06:00
|
|
|
/// let mut reader = io::stdin();
|
2014-01-30 18:55:20 -06:00
|
|
|
/// let input = reader.read_line().ok().unwrap_or(~"nothing");
|
2014-01-02 06:35:08 -06:00
|
|
|
/// ```
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
|
|
|
///
|
|
|
|
/// This function has the same error semantics as `read_until`:
|
|
|
|
///
|
|
|
|
/// * All non-EOF errors will be returned immediately
|
|
|
|
/// * If an error is returned previously consumed bytes are lost
|
|
|
|
/// * EOF is only returned if no bytes have been read
|
|
|
|
/// * Reach EOF may mean that the delimiter is not present in the return
|
|
|
|
/// value
|
2013-11-13 13:17:58 -06:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// Additionally, this function can fail if the line of input read is not a
|
|
|
|
/// valid UTF-8 sequence of bytes.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_line(&mut self) -> IoResult<~str> {
|
2014-01-30 18:55:20 -06:00
|
|
|
self.read_until('\n' as u8).and_then(|line|
|
|
|
|
match str::from_utf8_owned(line) {
|
|
|
|
Some(s) => Ok(s),
|
|
|
|
None => Err(standard_error(InvalidInput)),
|
|
|
|
}
|
|
|
|
)
|
2013-11-13 13:17:58 -06:00
|
|
|
}
|
|
|
|
|
2013-12-08 01:12:07 -06:00
|
|
|
/// Create an iterator that reads a line on each iteration until EOF.
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-12-08 01:12:07 -06:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// This iterator will transform all error values to `None`, discarding the
|
|
|
|
/// cause of the error. If this is undesirable, it is recommended to call
|
|
|
|
/// `read_line` directly.
|
2014-01-14 21:32:24 -06:00
|
|
|
fn lines<'r>(&'r mut self) -> Lines<'r, Self> {
|
2014-01-30 18:55:20 -06:00
|
|
|
Lines { buffer: self }
|
2013-12-08 01:12:07 -06:00
|
|
|
}
|
|
|
|
|
2013-12-14 23:26:09 -06:00
|
|
|
/// Reads a sequence of bytes leading up to a specified delimiter. Once the
|
2013-11-13 13:17:58 -06:00
|
|
|
/// specified byte is encountered, reading ceases and the bytes up to and
|
|
|
|
/// including the delimiter are returned.
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-11-13 13:17:58 -06:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// If any I/O error is encountered other than EOF, the error is immediately
|
|
|
|
/// returned. Note that this may discard bytes which have already been read,
|
|
|
|
/// and those bytes will *not* be returned. It is recommended to use other
|
|
|
|
/// methods if this case is worrying.
|
|
|
|
///
|
|
|
|
/// If EOF is encountered, then this function will return EOF if 0 bytes
|
|
|
|
/// have been read, otherwise the pending byte buffer is returned. This
|
|
|
|
/// is the reason that the byte buffer returned may not always contain the
|
|
|
|
/// delimiter.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_until(&mut self, byte: u8) -> IoResult<~[u8]> {
|
2013-11-13 13:17:58 -06:00
|
|
|
let mut res = ~[];
|
2013-12-08 01:12:07 -06:00
|
|
|
|
2014-01-29 18:33:57 -06:00
|
|
|
let mut used;
|
|
|
|
loop {
|
|
|
|
{
|
2014-01-30 18:55:20 -06:00
|
|
|
let available = match self.fill() {
|
|
|
|
Ok(n) => n,
|
|
|
|
Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
|
|
|
|
used = 0;
|
|
|
|
break
|
|
|
|
}
|
|
|
|
Err(e) => return Err(e)
|
|
|
|
};
|
2014-01-29 18:33:57 -06:00
|
|
|
match available.iter().position(|&b| b == byte) {
|
|
|
|
Some(i) => {
|
|
|
|
res.push_all(available.slice_to(i + 1));
|
|
|
|
used = i + 1;
|
|
|
|
break
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
res.push_all(available);
|
|
|
|
used = available.len();
|
2013-11-13 13:17:58 -06:00
|
|
|
}
|
|
|
|
}
|
2014-01-29 18:33:57 -06:00
|
|
|
}
|
2013-11-13 13:17:58 -06:00
|
|
|
self.consume(used);
|
2014-01-29 18:33:57 -06:00
|
|
|
}
|
|
|
|
self.consume(used);
|
|
|
|
Ok(res)
|
2013-11-13 13:17:58 -06:00
|
|
|
}
|
2013-11-13 13:36:21 -06:00
|
|
|
|
|
|
|
/// Reads the next utf8-encoded character from the underlying stream.
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-11-13 13:36:21 -06:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// If an I/O error occurs, or EOF, then this function will return `Err`.
|
|
|
|
/// This function will also return error if the stream does not contain a
|
|
|
|
/// valid utf-8 encoded codepoint as the next few bytes in the stream.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn read_char(&mut self) -> IoResult<char> {
|
2014-02-19 12:07:49 -06:00
|
|
|
let first_byte = try!(self.read_byte());
|
2014-01-30 16:10:53 -06:00
|
|
|
let width = str::utf8_char_width(first_byte);
|
|
|
|
if width == 1 { return Ok(first_byte as char) }
|
|
|
|
if width == 0 { return Err(standard_error(InvalidInput)) } // not utf8
|
|
|
|
let mut buf = [first_byte, 0, 0, 0];
|
2014-01-07 10:48:44 -06:00
|
|
|
{
|
2014-01-30 16:10:53 -06:00
|
|
|
let mut start = 1;
|
|
|
|
while start < width {
|
2014-02-19 12:07:49 -06:00
|
|
|
match try!(self.read(buf.mut_slice(start, width))) {
|
2014-01-29 18:33:57 -06:00
|
|
|
n if n == width - start => break,
|
|
|
|
n if n < width - start => { start += n; }
|
|
|
|
_ => return Err(standard_error(InvalidInput)),
|
2014-01-07 10:48:44 -06:00
|
|
|
}
|
|
|
|
}
|
2013-11-13 13:36:21 -06:00
|
|
|
}
|
2013-12-23 10:30:49 -06:00
|
|
|
match str::from_utf8(buf.slice_to(width)) {
|
2014-01-29 18:33:57 -06:00
|
|
|
Some(s) => Ok(s.char_at(0)),
|
|
|
|
None => Err(standard_error(InvalidInput))
|
2013-11-13 13:36:21 -06:00
|
|
|
}
|
|
|
|
}
|
2014-02-08 23:40:38 -06:00
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// Create an iterator that reads a utf8-encoded character on each iteration
|
|
|
|
/// until EOF.
|
2014-02-08 23:40:38 -06:00
|
|
|
///
|
|
|
|
/// # Error
|
|
|
|
///
|
|
|
|
/// This iterator will transform all error values to `None`, discarding the
|
|
|
|
/// cause of the error. If this is undesirable, it is recommended to call
|
|
|
|
/// `read_char` directly.
|
|
|
|
fn chars<'r>(&'r mut self) -> Chars<'r, Self> {
|
|
|
|
Chars { buffer: self }
|
|
|
|
}
|
2013-11-13 13:17:58 -06:00
|
|
|
}
|
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// When seeking, the resulting cursor is offset from a base by the offset given
|
|
|
|
/// to the `seek` function. The base used is specified by this enumeration.
|
2013-04-17 19:55:21 -05:00
|
|
|
pub enum SeekStyle {
|
|
|
|
/// Seek from the beginning of the stream
|
|
|
|
SeekSet,
|
|
|
|
/// Seek from the end of the stream
|
|
|
|
SeekEnd,
|
|
|
|
/// Seek from the current position
|
|
|
|
SeekCur,
|
|
|
|
}
|
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// An object implementing `Seek` internally has some form of cursor which can
|
|
|
|
/// be moved within a stream of bytes. The stream typically has a fixed size,
|
|
|
|
/// allowing seeking relative to either end.
|
2013-04-19 16:58:21 -05:00
|
|
|
pub trait Seek {
|
2013-08-20 17:38:41 -05:00
|
|
|
/// Return position of file cursor in the stream
|
2014-01-29 18:33:57 -06:00
|
|
|
fn tell(&self) -> IoResult<u64>;
|
2013-04-20 19:25:00 -05:00
|
|
|
|
|
|
|
/// Seek to an offset in a stream
|
|
|
|
///
|
2014-02-11 22:13:46 -06:00
|
|
|
/// A successful seek clears the EOF indicator. Seeking beyond EOF is
|
|
|
|
/// allowed, but seeking before position 0 is not allowed.
|
2013-04-20 19:25:00 -05:00
|
|
|
///
|
2014-02-11 22:13:46 -06:00
|
|
|
/// # Errors
|
2013-04-20 19:25:00 -05:00
|
|
|
///
|
2014-02-11 22:13:46 -06:00
|
|
|
/// * Seeking to a negative offset is considered an error
|
|
|
|
/// * Seeking past the end of the stream does not modify the underlying
|
|
|
|
/// stream, but the next write may cause the previous data to be filled in
|
|
|
|
/// with a bit pattern.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>;
|
2013-04-17 19:55:21 -05:00
|
|
|
}
|
|
|
|
|
2014-01-30 18:55:20 -06:00
|
|
|
/// A listener is a value that can consume itself to start listening for
|
|
|
|
/// connections.
|
|
|
|
///
|
2013-08-27 12:01:17 -05:00
|
|
|
/// Doing so produces some sort of Acceptor.
|
|
|
|
pub trait Listener<T, A: Acceptor<T>> {
|
2013-12-14 23:26:09 -06:00
|
|
|
/// Spin up the listener and start queuing incoming connections
|
2013-04-22 15:26:37 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
2013-04-22 15:26:37 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// Returns `Err` if this listener could not be bound to listen for
|
|
|
|
/// connections. In all cases, this listener is consumed.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn listen(self) -> IoResult<A>;
|
2013-08-27 12:01:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// An acceptor is a value that presents incoming connections
|
|
|
|
pub trait Acceptor<T> {
|
|
|
|
/// Wait for and accept an incoming connection
|
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// # Error
|
|
|
|
///
|
|
|
|
/// Returns `Err` if an I/O error is encountered.
|
2014-01-29 18:33:57 -06:00
|
|
|
fn accept(&mut self) -> IoResult<T>;
|
2013-08-27 12:01:17 -05:00
|
|
|
|
2014-01-30 18:55:20 -06:00
|
|
|
/// Create an iterator over incoming connection attempts.
|
|
|
|
///
|
|
|
|
/// Note that I/O errors will be yielded by the iterator itself.
|
2014-01-14 21:32:24 -06:00
|
|
|
fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
|
|
|
|
IncomingConnections { inc: self }
|
2013-08-27 12:01:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An infinite iterator over incoming connection attempts.
|
|
|
|
/// Calling `next` will block the task until a connection is attempted.
|
2013-09-05 18:49:38 -05:00
|
|
|
///
|
2014-01-30 18:55:20 -06:00
|
|
|
/// Since connection attempts can continue forever, this iterator always returns
|
|
|
|
/// `Some`. The `Some` contains the `IoResult` representing whether the
|
2014-02-17 05:53:45 -06:00
|
|
|
/// connection attempt was successful. A successful connection will be wrapped
|
2014-01-30 18:55:20 -06:00
|
|
|
/// in `Ok`. A failed connection is represented as an `Err`.
|
2014-01-25 20:25:02 -06:00
|
|
|
pub struct IncomingConnections<'a, A> {
|
2013-12-10 01:16:18 -06:00
|
|
|
priv inc: &'a mut A,
|
2013-08-27 12:01:17 -05:00
|
|
|
}
|
|
|
|
|
2014-01-29 18:33:57 -06:00
|
|
|
impl<'a, T, A: Acceptor<T>> Iterator<IoResult<T>> for IncomingConnections<'a, A> {
|
|
|
|
fn next(&mut self) -> Option<IoResult<T>> {
|
2013-09-05 18:49:38 -05:00
|
|
|
Some(self.inc.accept())
|
2013-08-27 12:01:17 -05:00
|
|
|
}
|
2013-04-22 15:26:37 -05:00
|
|
|
}
|
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// Creates a standard error for a commonly used flavor of error. The `detail`
|
|
|
|
/// field of the returned error will always be `None`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::io;
|
|
|
|
///
|
|
|
|
/// let eof = io::standard_error(io::EndOfFile);
|
|
|
|
/// let einval = io::standard_error(io::InvalidInput);
|
|
|
|
/// ```
|
2013-04-22 16:52:40 -05:00
|
|
|
pub fn standard_error(kind: IoErrorKind) -> IoError {
|
2013-12-08 13:12:25 -06:00
|
|
|
let desc = match kind {
|
|
|
|
EndOfFile => "end of file",
|
|
|
|
IoUnavailable => "I/O is unavailable",
|
|
|
|
InvalidInput => "invalid input",
|
2013-10-21 15:08:31 -05:00
|
|
|
_ => fail!()
|
2013-12-08 13:12:25 -06:00
|
|
|
};
|
|
|
|
IoError {
|
|
|
|
kind: kind,
|
|
|
|
desc: desc,
|
|
|
|
detail: None,
|
2013-04-22 16:52:40 -05:00
|
|
|
}
|
|
|
|
}
|
2013-05-09 19:37:31 -05:00
|
|
|
|
2013-10-30 01:31:07 -05:00
|
|
|
/// A mode specifies how a file should be opened or created. These modes are
|
|
|
|
/// passed to `File::open_mode` and are used to control where the file is
|
|
|
|
/// positioned when it is initially opened.
|
2013-08-22 18:31:23 -05:00
|
|
|
pub enum FileMode {
|
2013-10-30 01:31:07 -05:00
|
|
|
/// Opens a file positioned at the beginning.
|
2013-08-22 18:31:23 -05:00
|
|
|
Open,
|
2013-10-30 01:31:07 -05:00
|
|
|
/// Opens a file positioned at EOF.
|
2013-08-22 18:31:23 -05:00
|
|
|
Append,
|
2013-10-30 01:31:07 -05:00
|
|
|
/// Opens a file, truncating it if it already exists.
|
2013-08-22 18:31:23 -05:00
|
|
|
Truncate,
|
|
|
|
}
|
|
|
|
|
2013-10-30 01:31:07 -05:00
|
|
|
/// Access permissions with which the file should be opened. `File`s
|
2014-01-30 18:55:20 -06:00
|
|
|
/// opened with `Read` will return an error if written to.
|
2013-08-22 18:31:23 -05:00
|
|
|
pub enum FileAccess {
|
2014-02-24 02:31:08 -06:00
|
|
|
/// Read-only access, requests to write will result in an error
|
2013-08-22 18:31:23 -05:00
|
|
|
Read,
|
2014-02-24 02:31:08 -06:00
|
|
|
/// Write-only access, requests to read will result in an error
|
2013-08-22 18:31:23 -05:00
|
|
|
Write,
|
2014-02-24 02:31:08 -06:00
|
|
|
/// Read-write access, no requests are denied by default
|
2013-10-30 01:31:07 -05:00
|
|
|
ReadWrite,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Different kinds of files which can be identified by a call to stat
|
2014-02-28 03:23:06 -06:00
|
|
|
#[deriving(Eq, Show)]
|
2013-10-30 01:31:07 -05:00
|
|
|
pub enum FileType {
|
2014-02-24 02:31:08 -06:00
|
|
|
/// This is a normal file, corresponding to `S_IFREG`
|
2013-10-30 01:31:07 -05:00
|
|
|
TypeFile,
|
2014-02-24 02:31:08 -06:00
|
|
|
|
|
|
|
/// This file is a directory, corresponding to `S_IFDIR`
|
2013-10-30 01:31:07 -05:00
|
|
|
TypeDirectory,
|
2014-02-24 02:31:08 -06:00
|
|
|
|
|
|
|
/// This file is a named pipe, corresponding to `S_IFIFO`
|
2013-10-30 01:31:07 -05:00
|
|
|
TypeNamedPipe,
|
2014-02-24 02:31:08 -06:00
|
|
|
|
|
|
|
/// This file is a block device, corresponding to `S_IFBLK`
|
2013-10-30 01:31:07 -05:00
|
|
|
TypeBlockSpecial,
|
2014-02-24 02:31:08 -06:00
|
|
|
|
|
|
|
/// This file is a symbolic link to another file, corresponding to `S_IFLNK`
|
2013-10-30 01:31:07 -05:00
|
|
|
TypeSymlink,
|
2014-02-24 02:31:08 -06:00
|
|
|
|
|
|
|
/// The type of this file is not recognized as one of the other categories
|
2013-10-30 01:31:07 -05:00
|
|
|
TypeUnknown,
|
2013-08-22 18:31:23 -05:00
|
|
|
}
|
2013-08-26 09:24:10 -05:00
|
|
|
|
2014-02-24 02:31:08 -06:00
|
|
|
/// A structure used to describe metadata information about a file. This
|
|
|
|
/// structure is created through the `stat` method on a `Path`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # fn main() {}
|
|
|
|
/// # fn foo() {
|
|
|
|
/// let info = match Path::new("foo.txt").stat() {
|
|
|
|
/// Ok(stat) => stat,
|
|
|
|
/// Err(e) => fail!("couldn't read foo.txt: {}", e),
|
|
|
|
/// };
|
|
|
|
///
|
|
|
|
/// println!("path: {}", info.path.display());
|
|
|
|
/// println!("byte size: {}", info.size);
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2013-08-26 09:24:10 -05:00
|
|
|
pub struct FileStat {
|
2013-10-30 01:31:07 -05:00
|
|
|
/// The path that this stat structure is describing
|
2013-08-26 09:24:10 -05:00
|
|
|
path: Path,
|
2013-10-30 01:31:07 -05:00
|
|
|
/// The size of the file, in bytes
|
2013-08-26 09:24:10 -05:00
|
|
|
size: u64,
|
2013-10-30 01:31:07 -05:00
|
|
|
/// The kind of file this path points to (directory, file, pipe, etc.)
|
|
|
|
kind: FileType,
|
|
|
|
/// The file permissions currently on the file
|
|
|
|
perm: FilePermission,
|
|
|
|
|
2013-11-05 17:48:27 -06:00
|
|
|
// FIXME(#10301): These time fields are pretty useless without an actual
|
|
|
|
// time representation, what are the milliseconds relative
|
|
|
|
// to?
|
2013-10-30 01:31:07 -05:00
|
|
|
|
|
|
|
/// The time that the file was created at, in platform-dependent
|
|
|
|
/// milliseconds
|
2013-08-26 09:24:10 -05:00
|
|
|
created: u64,
|
2013-10-30 01:31:07 -05:00
|
|
|
/// The time that this file was last modified, in platform-dependent
|
|
|
|
/// milliseconds
|
2013-08-26 09:24:10 -05:00
|
|
|
modified: u64,
|
2013-10-30 01:31:07 -05:00
|
|
|
/// The time that this file was last accessed, in platform-dependent
|
|
|
|
/// milliseconds
|
2013-08-26 09:24:10 -05:00
|
|
|
accessed: u64,
|
2013-10-30 01:31:07 -05:00
|
|
|
|
2013-10-31 17:15:30 -05:00
|
|
|
/// Information returned by stat() which is not guaranteed to be
|
|
|
|
/// platform-independent. This information may be useful on some platforms,
|
|
|
|
/// but it may have different meanings or no meaning at all on other
|
|
|
|
/// platforms.
|
|
|
|
///
|
|
|
|
/// Usage of this field is discouraged, but if access is desired then the
|
|
|
|
/// fields are located here.
|
|
|
|
#[unstable]
|
|
|
|
unstable: UnstableFileStat,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This structure represents all of the possible information which can be
|
|
|
|
/// returned from a `stat` syscall which is not contained in the `FileStat`
|
|
|
|
/// structure. This information is not necessarily platform independent, and may
|
|
|
|
/// have different meanings or no meaning at all on some platforms.
|
|
|
|
#[unstable]
|
2014-02-24 02:31:08 -06:00
|
|
|
#[allow(missing_doc)]
|
2013-10-31 17:15:30 -05:00
|
|
|
pub struct UnstableFileStat {
|
2013-10-30 01:31:07 -05:00
|
|
|
device: u64,
|
|
|
|
inode: u64,
|
|
|
|
rdev: u64,
|
|
|
|
nlink: u64,
|
|
|
|
uid: u64,
|
|
|
|
gid: u64,
|
|
|
|
blksize: u64,
|
|
|
|
blocks: u64,
|
|
|
|
flags: u64,
|
|
|
|
gen: u64,
|
2013-08-26 09:24:10 -05:00
|
|
|
}
|
2013-10-25 19:04:37 -05:00
|
|
|
|
2013-10-30 01:31:07 -05:00
|
|
|
/// A set of permissions for a file or directory is represented by a set of
|
|
|
|
/// flags which are or'd together.
|
2013-10-25 19:04:37 -05:00
|
|
|
pub type FilePermission = u32;
|
2013-10-30 01:31:07 -05:00
|
|
|
|
|
|
|
// Each permission bit
|
|
|
|
pub static UserRead: FilePermission = 0x100;
|
|
|
|
pub static UserWrite: FilePermission = 0x080;
|
|
|
|
pub static UserExecute: FilePermission = 0x040;
|
|
|
|
pub static GroupRead: FilePermission = 0x020;
|
|
|
|
pub static GroupWrite: FilePermission = 0x010;
|
|
|
|
pub static GroupExecute: FilePermission = 0x008;
|
|
|
|
pub static OtherRead: FilePermission = 0x004;
|
|
|
|
pub static OtherWrite: FilePermission = 0x002;
|
|
|
|
pub static OtherExecute: FilePermission = 0x001;
|
|
|
|
|
|
|
|
// Common combinations of these bits
|
|
|
|
pub static UserRWX: FilePermission = UserRead | UserWrite | UserExecute;
|
|
|
|
pub static GroupRWX: FilePermission = GroupRead | GroupWrite | GroupExecute;
|
|
|
|
pub static OtherRWX: FilePermission = OtherRead | OtherWrite | OtherExecute;
|
|
|
|
|
|
|
|
/// A set of permissions for user owned files, this is equivalent to 0644 on
|
|
|
|
/// unix-like systems.
|
|
|
|
pub static UserFile: FilePermission = UserRead | UserWrite | GroupRead | OtherRead;
|
|
|
|
/// A set of permissions for user owned directories, this is equivalent to 0755
|
|
|
|
/// on unix-like systems.
|
|
|
|
pub static UserDir: FilePermission = UserRWX | GroupRead | GroupExecute |
|
|
|
|
OtherRead | OtherExecute;
|
|
|
|
/// A set of permissions for user owned executables, this is equivalent to 0755
|
|
|
|
/// on unix-like systems.
|
|
|
|
pub static UserExec: FilePermission = UserDir;
|
|
|
|
|
|
|
|
/// A mask for all possible permission bits
|
|
|
|
pub static AllPermissions: FilePermission = 0x1ff;
|