(index<- ) ./libstd/io/mod.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // FIXME: cover these topics:
12 // path, reader, writer, stream, raii (close not needed),
13 // stdio, print!, println!, file access, process spawning,
14 // error handling
15
16
17 /*! I/O, including files, networking, timers, and processes
18
19 `std::io` provides Rust's basic I/O types,
20 for reading and writing to files, TCP, UDP,
21 and other types of sockets and pipes,
22 manipulating the file system, spawning processes and signal handling.
23
24 # Examples
25
26 Some examples of obvious things you might want to do
27
28 * Read lines from stdin
29
30 ```rust
31 use std::io;
32
33 for line in io::stdin().lines() {
34 print!("{}", line.unwrap());
35 }
36 ```
37
38 * Read a complete file
39
40 ```rust
41 use std::io::File;
42
43 let contents = File::open(&Path::new("message.txt")).read_to_end();
44 ```
45
46 * Write a line to a file
47
48 ```rust
49 # #![allow(unused_must_use)]
50 use std::io::File;
51
52 let mut file = File::create(&Path::new("message.txt"));
53 file.write(bytes!("hello, file!\n"));
54 # drop(file);
55 # ::std::io::fs::unlink(&Path::new("message.txt"));
56 ```
57
58 * Iterate over the lines of a file
59
60 ```rust,no_run
61 use std::io::BufferedReader;
62 use std::io::File;
63
64 let path = Path::new("message.txt");
65 let mut file = BufferedReader::new(File::open(&path));
66 for line in file.lines() {
67 print!("{}", line.unwrap());
68 }
69 ```
70
71 * Pull the lines of a file into a vector of strings
72
73 ```rust,no_run
74 use std::io::BufferedReader;
75 use std::io::File;
76
77 let path = Path::new("message.txt");
78 let mut file = BufferedReader::new(File::open(&path));
79 let lines: Vec<~str> = file.lines().map(|x| x.unwrap()).collect();
80 ```
81
82 * Make a simple TCP client connection and request
83
84 ```rust,should_fail
85 # #![allow(unused_must_use)]
86 use std::io::net::ip::SocketAddr;
87 use std::io::net::tcp::TcpStream;
88
89 let addr = from_str::<SocketAddr>("127.0.0.1:8080").unwrap();
90 let mut socket = TcpStream::connect(addr).unwrap();
91 socket.write(bytes!("GET / HTTP/1.0\n\n"));
92 let response = socket.read_to_end();
93 ```
94
95 * Make a simple TCP server
96
97 ```rust
98 # fn main() { }
99 # fn foo() {
100 # #![allow(dead_code)]
101 use std::io::{TcpListener, TcpStream};
102 use std::io::net::ip::{Ipv4Addr, SocketAddr};
103 use std::io::{Acceptor, Listener};
104
105 let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 80 };
106 let listener = TcpListener::bind(addr);
107
108 // bind the listener to the specified address
109 let mut acceptor = listener.listen();
110
111 fn handle_client(mut stream: TcpStream) {
112 // ...
113 # &mut stream; // silence unused mutability/variable warning
114 }
115 // accept connections and process them, spawning a new tasks for each one
116 for stream in acceptor.incoming() {
117 match stream {
118 Err(e) => { /* connection failed */ }
119 Ok(stream) => spawn(proc() {
120 // connection succeeded
121 handle_client(stream)
122 })
123 }
124 }
125
126 // close the socket server
127 drop(acceptor);
128 # }
129 ```
130
131
132 # Error Handling
133
134 I/O is an area where nearly every operation can result in unexpected
135 errors. Errors should be painfully visible when they happen, and handling them
136 should be easy to work with. It should be convenient to handle specific I/O
137 errors, and it should also be convenient to not deal with I/O errors.
138
139 Rust's I/O employs a combination of techniques to reduce boilerplate
140 while still providing feedback about errors. The basic strategy:
141
142 * All I/O operations return `IoResult<T>` which is equivalent to
143 `Result<T, IoError>`. The `Result` type is defined in the `std::result`
144 module.
145 * If the `Result` type goes unused, then the compiler will by default emit a
146 warning about the unused result. This is because `Result` has the
147 `#[must_use]` attribute.
148 * Common traits are implemented for `IoResult`, e.g.
149 `impl<R: Reader> Reader for IoResult<R>`, so that error values do not have
150 to be 'unwrapped' before use.
151
152 These features combine in the API to allow for expressions like
153 `File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"))`
154 without having to worry about whether "diary.txt" exists or whether
155 the write succeeds. As written, if either `new` or `write_line`
156 encounters an error then the result of the entire expression will
157 be an error.
158
159 If you wanted to handle the error though you might write:
160
161 ```rust
162 # #![allow(unused_must_use)]
163 use std::io::File;
164
165 match File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n")) {
166 Ok(()) => (), // succeeded
167 Err(e) => println!("failed to write to my diary: {}", e),
168 }
169
170 # ::std::io::fs::unlink(&Path::new("diary.txt"));
171 ```
172
173 So what actually happens if `create` encounters an error?
174 It's important to know that what `new` returns is not a `File`
175 but an `IoResult<File>`. If the file does not open, then `new` will simply
176 return `Err(..)`. Because there is an implementation of `Writer` (the trait
177 required ultimately required for types to implement `write_line`) there is no
178 need to inspect or unwrap the `IoResult<File>` and we simply call `write_line`
179 on it. If `new` returned an `Err(..)` then the followup call to `write_line`
180 will also return an error.
181
182 ## `try!`
183
184 Explicit pattern matching on `IoResult`s can get quite verbose, especially
185 when performing many I/O operations. Some examples (like those above) are
186 alleviated with extra methods implemented on `IoResult`, but others have more
187 complex interdependencies among each I/O operation.
188
189 The `try!` macro from `std::macros` is provided as a method of early-return
190 inside `Result`-returning functions. It expands to an early-return on `Err`
191 and otherwise unwraps the contained `Ok` value.
192
193 If you wanted to read several `u32`s from a file and return their product:
194
195 ```rust
196 use std::io::{File, IoResult};
197
198 fn file_product(p: &Path) -> IoResult<u32> {
199 let mut f = File::open(p);
200 let x1 = try!(f.read_le_u32());
201 let x2 = try!(f.read_le_u32());
202
203 Ok(x1 * x2)
204 }
205
206 match file_product(&Path::new("numbers.bin")) {
207 Ok(x) => println!("{}", x),
208 Err(e) => println!("Failed to read numbers!")
209 }
210 ```
211
212 With `try!` in `file_product`, each `read_le_u32` need not be directly
213 concerned with error handling; instead its caller is responsible for
214 responding to errors that may occur while attempting to read the numbers.
215
216 */
217
218 #![deny(unused_must_use)]
219
220 use cast;
221 use char::Char;
222 use container::Container;
223 use fmt;
224 use int;
225 use iter::Iterator;
226 use libc;
227 use ops::{BitOr, BitAnd, Sub};
228 use os;
229 use option::{Option, Some, None};
230 use owned::Box;
231 use path::Path;
232 use result::{Ok, Err, Result};
233 use str::{StrSlice, StrAllocating};
234 use str;
235 use uint;
236 use unstable::finally::try_finally;
237 use slice::{Vector, MutableVector, ImmutableVector};
238 use vec::Vec;
239
240 // Reexports
241 pub use self::stdio::stdin;
242 pub use self::stdio::stdout;
243 pub use self::stdio::stderr;
244 pub use self::stdio::print;
245 pub use self::stdio::println;
246
247 pub use self::fs::File;
248 pub use self::timer::Timer;
249 pub use self::net::ip::IpAddr;
250 pub use self::net::tcp::TcpListener;
251 pub use self::net::tcp::TcpStream;
252 pub use self::net::udp::UdpStream;
253 pub use self::pipe::PipeStream;
254 pub use self::process::{Process, ProcessConfig};
255 pub use self::tempfile::TempDir;
256
257 pub use self::mem::{MemReader, BufReader, MemWriter, BufWriter};
258 pub use self::buffered::{BufferedReader, BufferedWriter, BufferedStream,
259 LineBufferedWriter};
260 pub use self::comm_adapters::{ChanReader, ChanWriter};
261
262 // this comes first to get the iotest! macro
263 pub mod test;
264
265 mod buffered;
266 mod comm_adapters;
267 mod mem;
268 mod result;
269 mod tempfile;
270 pub mod extensions;
271 pub mod fs;
272 pub mod net;
273 pub mod pipe;
274 pub mod process;
275 pub mod signal;
276 pub mod stdio;
277 pub mod timer;
278 pub mod util;
279
280 /// The default buffer size for various I/O operations
281 // libuv recommends 64k buffers to maximize throughput
282 // https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
283 static DEFAULT_BUF_SIZE: uint = 1024 * 64;
284
285 /// A convenient typedef of the return value of any I/O action.
286 pub type IoResult<T> = Result<T, IoError>;
287
288 /// The type passed to I/O condition handlers to indicate error
289 ///
290 /// # FIXME
291 ///
292 /// Is something like this sufficient? It's kind of archaic
293 #[deriving(Eq, Clone)]
294 pub struct IoError {
295 /// An enumeration which can be matched against for determining the flavor
296 /// of error.
297 pub kind: IoErrorKind,
298 /// A human-readable description about the error
299 pub desc: &'static str,
300 /// Detailed information about this error, not always available
301 pub detail: Option<~str>
302 }
303
304 impl IoError {
305 /// Convert an `errno` value into an `IoError`.
306 ///
307 /// If `detail` is `true`, the `detail` field of the `IoError`
308 /// struct is filled with an allocated string describing the error
309 /// in more detail, retrieved from the operating system.
310 pub fn from_errno(errno: uint, detail: bool) -> IoError {
311 #[cfg(windows)]
312 fn get_err(errno: i32) -> (IoErrorKind, &'static str) {
313 match errno {
314 libc::EOF => (EndOfFile, "end of file"),
315 libc::ERROR_NO_DATA => (BrokenPipe, "the pipe is being closed"),
316 libc::ERROR_FILE_NOT_FOUND => (FileNotFound, "file not found"),
317 libc::ERROR_INVALID_NAME => (InvalidInput, "invalid file name"),
318 libc::WSAECONNREFUSED => (ConnectionRefused, "connection refused"),
319 libc::WSAECONNRESET => (ConnectionReset, "connection reset"),
320 libc::WSAEACCES => (PermissionDenied, "permission denied"),
321 libc::WSAEWOULDBLOCK => {
322 (ResourceUnavailable, "resource temporarily unavailable")
323 }
324 libc::WSAENOTCONN => (NotConnected, "not connected"),
325 libc::WSAECONNABORTED => (ConnectionAborted, "connection aborted"),
326 libc::WSAEADDRNOTAVAIL => (ConnectionRefused, "address not available"),
327 libc::WSAEADDRINUSE => (ConnectionRefused, "address in use"),
328 libc::ERROR_BROKEN_PIPE => (EndOfFile, "the pipe has ended"),
329 libc::ERROR_OPERATION_ABORTED =>
330 (TimedOut, "operation timed out"),
331
332 // libuv maps this error code to EISDIR. we do too. if it is found
333 // to be incorrect, we can add in some more machinery to only
334 // return this message when ERROR_INVALID_FUNCTION after certain
335 // win32 calls.
336 libc::ERROR_INVALID_FUNCTION => (InvalidInput,
337 "illegal operation on a directory"),
338
339 _ => (OtherIoError, "unknown error")
340 }
341 }
342
343 #[cfg(not(windows))]
344 fn get_err(errno: i32) -> (IoErrorKind, &'static str) {
345 // FIXME: this should probably be a bit more descriptive...
346 match errno {
347 libc::EOF => (EndOfFile, "end of file"),
348 libc::ECONNREFUSED => (ConnectionRefused, "connection refused"),
349 libc::ECONNRESET => (ConnectionReset, "connection reset"),
350 libc::EPERM | libc::EACCES =>
351 (PermissionDenied, "permission denied"),
352 libc::EPIPE => (BrokenPipe, "broken pipe"),
353 libc::ENOTCONN => (NotConnected, "not connected"),
354 libc::ECONNABORTED => (ConnectionAborted, "connection aborted"),
355 libc::EADDRNOTAVAIL => (ConnectionRefused, "address not available"),
356 libc::EADDRINUSE => (ConnectionRefused, "address in use"),
357 libc::ENOENT => (FileNotFound, "no such file or directory"),
358 libc::EISDIR => (InvalidInput, "illegal operation on a directory"),
359
360 // These two constants can have the same value on some systems, but
361 // different values on others, so we can't use a match clause
362 x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
363 (ResourceUnavailable, "resource temporarily unavailable"),
364
365 _ => (OtherIoError, "unknown error")
366 }
367 }
368
369 let (kind, desc) = get_err(errno as i32);
370 IoError {
371 kind: kind,
372 desc: desc,
373 detail: if detail {Some(os::error_string(errno))} else {None},
374 }
375 }
376
377 /// Retrieve the last error to occur as a (detailed) IoError.
378 ///
379 /// This uses the OS `errno`, and so there should not be any task
380 /// descheduling or migration (other than that performed by the
381 /// operating system) between the call(s) for which errors are
382 /// being checked and the call of this function.
383 pub fn last_error() -> IoError {
384 IoError::from_errno(os::errno() as uint, true)
385 }
386 }
387
388 impl fmt::Show for IoError {
389 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
390 try!(fmt.buf.write_str(self.desc));
391 match self.detail {
392 Some(ref s) => write!(fmt.buf, " ({})", *s),
393 None => Ok(())
394 }
395 }
396 }
397
398 /// A list specifying general categories of I/O error.
399 #[deriving(Eq, Clone, Show)]
400 pub enum IoErrorKind {
401 /// Any I/O error not part of this list.
402 OtherIoError,
403 /// The operation could not complete because end of file was reached.
404 EndOfFile,
405 /// The file was not found.
406 FileNotFound,
407 /// The file permissions disallowed access to this file.
408 PermissionDenied,
409 /// A network connection failed for some reason not specified in this list.
410 ConnectionFailed,
411 /// The network operation failed because the network connection was cloesd.
412 Closed,
413 /// The connection was refused by the remote server.
414 ConnectionRefused,
415 /// The connection was reset by the remote server.
416 ConnectionReset,
417 /// The connection was aborted (terminated) by the remote server.
418 ConnectionAborted,
419 /// The network operation failed because it was not connected yet.
420 NotConnected,
421 /// The operation failed because a pipe was closed.
422 BrokenPipe,
423 /// A file already existed with that name.
424 PathAlreadyExists,
425 /// No file exists at that location.
426 PathDoesntExist,
427 /// The path did not specify the type of file that this operation required. For example,
428 /// attempting to copy a directory with the `fs::copy()` operation will fail with this error.
429 MismatchedFileTypeForOperation,
430 /// The operation temporarily failed (for example, because a signal was received), and retrying
431 /// may succeed.
432 ResourceUnavailable,
433 /// No I/O functionality is available for this task.
434 IoUnavailable,
435 /// A parameter was incorrect in a way that caused an I/O error not part of this list.
436 InvalidInput,
437 /// The I/O operation's timeout expired, causing it to be canceled.
438 TimedOut,
439 /// This write operation failed to write all of its data.
440 ///
441 /// Normally the write() method on a Writer guarantees that all of its data
442 /// has been written, but some operations may be terminated after only
443 /// partially writing some data. An example of this is a timed out write
444 /// which successfully wrote a known number of bytes, but bailed out after
445 /// doing so.
446 ///
447 /// The payload contained as part of this variant is the number of bytes
448 /// which are known to have been successfully written.
449 ShortWrite(uint),
450 }
451
452 /// A trait for objects which are byte-oriented streams. Readers are defined by
453 /// one method, `read`. This function will block until data is available,
454 /// filling in the provided buffer with any data read.
455 ///
456 /// Readers are intended to be composable with one another. Many objects
457 /// throughout the I/O and related libraries take and provide types which
458 /// implement the `Reader` trait.
459 pub trait Reader {
460
461 // Only method which need to get implemented for this trait
462
463 /// Read bytes, up to the length of `buf` and place them in `buf`.
464 /// Returns the number of bytes read. The number of bytes read my
465 /// be less than the number requested, even 0. Returns `Err` on EOF.
466 ///
467 /// # Error
468 ///
469 /// If an error occurs during this I/O operation, then it is returned as
470 /// `Err(IoError)`. Note that end-of-file is considered an error, and can be
471 /// inspected for in the error's `kind` field. Also note that reading 0
472 /// bytes is not considered an error in all circumstances
473 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
474
475 // Convenient helper methods based on the above methods
476
477 /// Reads a single byte. Returns `Err` on EOF.
478 fn read_byte(&mut self) -> IoResult<u8> {
479 let mut buf = [0];
480 loop {
481 match self.read(buf) {
482 Ok(0) => {}
483 Ok(1) => return Ok(buf[0]),
484 Ok(_) => unreachable!(),
485 Err(e) => return Err(e)
486 }
487 }
488 }
489
490 /// Fills the provided slice with bytes from this reader
491 ///
492 /// This will continue to call `read` until the slice has been completely
493 /// filled with bytes.
494 ///
495 /// # Error
496 ///
497 /// If an error occurs at any point, that error is returned, and no further
498 /// bytes are read.
499 fn fill(&mut self, buf: &mut [u8]) -> IoResult<()> {
500 let mut read = 0;
501 while read < buf.len() {
502 read += try!(self.read(buf.mut_slice_from(read)));
503 }
504 Ok(())
505 }
506
507 /// Reads exactly `len` bytes and appends them to a vector.
508 ///
509 /// May push fewer than the requested number of bytes on error
510 /// or EOF. If `Ok(())` is returned, then all of the requested bytes were
511 /// pushed on to the vector, otherwise the amount `len` bytes couldn't be
512 /// read (an error was encountered), and the error is returned.
513 fn push_exact(&mut self, buf: &mut Vec<u8>, len: uint) -> IoResult<()> {
514 struct State<'a> {
515 buf: &'a mut Vec<u8>,
516 total_read: uint
517 }
518
519 let start_len = buf.len();
520 let mut s = State { buf: buf, total_read: 0 };
521
522 s.buf.reserve_additional(len);
523 unsafe { s.buf.set_len(start_len + len); }
524
525 try_finally(
526 &mut s, (),
527 |s, _| {
528 while s.total_read < len {
529 let len = s.buf.len();
530 let slice = s.buf.mut_slice(start_len + s.total_read, len);
531 match self.read(slice) {
532 Ok(nread) => {
533 s.total_read += nread;
534 }
535 Err(e) => return Err(e)
536 }
537 }
538 Ok(())
539 },
540 |s| unsafe { s.buf.set_len(start_len + s.total_read) })
541 }
542
543 /// Reads exactly `len` bytes and gives you back a new vector of length
544 /// `len`
545 ///
546 /// # Error
547 ///
548 /// Fails with the same conditions as `read`. Additionally returns error
549 /// on EOF. Note that if an error is returned, then some number of bytes may
550 /// have already been consumed from the underlying reader, and they are lost
551 /// (not returned as part of the error). If this is unacceptable, then it is
552 /// recommended to use the `push_exact` or `read` methods.
553 fn read_exact(&mut self, len: uint) -> IoResult<Vec<u8>> {
554 let mut buf = Vec::with_capacity(len);
555 match self.push_exact(&mut buf, len) {
556 Ok(()) => Ok(buf),
557 Err(e) => Err(e),
558 }
559 }
560
561 /// Reads all remaining bytes from the stream.
562 ///
563 /// # Error
564 ///
565 /// Returns any non-EOF error immediately. Previously read bytes are
566 /// discarded when an error is returned.
567 ///
568 /// When EOF is encountered, all bytes read up to that point are returned.
569 fn read_to_end(&mut self) -> IoResult<Vec<u8>> {
570 let mut buf = Vec::with_capacity(DEFAULT_BUF_SIZE);
571 loop {
572 match self.push_exact(&mut buf, DEFAULT_BUF_SIZE) {
573 Ok(()) => {}
574 Err(ref e) if e.kind == EndOfFile => break,
575 Err(e) => return Err(e)
576 }
577 }
578 return Ok(buf);
579 }
580
581 /// Reads all of the remaining bytes of this stream, interpreting them as a
582 /// UTF-8 encoded stream. The corresponding string is returned.
583 ///
584 /// # Error
585 ///
586 /// This function returns all of the same errors as `read_to_end` with an
587 /// additional error if the reader's contents are not a valid sequence of
588 /// UTF-8 bytes.
589 fn read_to_str(&mut self) -> IoResult<~str> {
590 self.read_to_end().and_then(|s| {
591 match str::from_utf8(s.as_slice()) {
592 Some(s) => Ok(s.to_owned()),
593 None => Err(standard_error(InvalidInput)),
594 }
595 })
596 }
597
598 /// Create an iterator that reads a single byte on
599 /// each iteration, until EOF.
600 ///
601 /// # Error
602 ///
603 /// Any error other than `EndOfFile` that is produced by the underlying Reader
604 /// is returned by the iterator and should be handled by the caller.
605 fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, Self> {
606 extensions::Bytes::new(self)
607 }
608
609 // Byte conversion helpers
610
611 /// Reads `n` little-endian unsigned integer bytes.
612 ///
613 /// `n` must be between 1 and 8, inclusive.
614 fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
615 assert!(nbytes > 0 && nbytes <= 8);
616
617 let mut val = 0u64;
618 let mut pos = 0;
619 let mut i = nbytes;
620 while i > 0 {
621 val += (try!(self.read_u8()) as u64) << pos;
622 pos += 8;
623 i -= 1;
624 }
625 Ok(val)
626 }
627
628 /// Reads `n` little-endian signed integer bytes.
629 ///
630 /// `n` must be between 1 and 8, inclusive.
631 fn read_le_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
632 self.read_le_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
633 }
634
635 /// Reads `n` big-endian unsigned integer bytes.
636 ///
637 /// `n` must be between 1 and 8, inclusive.
638 fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
639 assert!(nbytes > 0 && nbytes <= 8);
640
641 let mut val = 0u64;
642 let mut i = nbytes;
643 while i > 0 {
644 i -= 1;
645 val += (try!(self.read_u8()) as u64) << i * 8;
646 }
647 Ok(val)
648 }
649
650 /// Reads `n` big-endian signed integer bytes.
651 ///
652 /// `n` must be between 1 and 8, inclusive.
653 fn read_be_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
654 self.read_be_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
655 }
656
657 /// Reads a little-endian unsigned integer.
658 ///
659 /// The number of bytes returned is system-dependent.
660 fn read_le_uint(&mut self) -> IoResult<uint> {
661 self.read_le_uint_n(uint::BYTES).map(|i| i as uint)
662 }
663
664 /// Reads a little-endian integer.
665 ///
666 /// The number of bytes returned is system-dependent.
667 fn read_le_int(&mut self) -> IoResult<int> {
668 self.read_le_int_n(int::BYTES).map(|i| i as int)
669 }
670
671 /// Reads a big-endian unsigned integer.
672 ///
673 /// The number of bytes returned is system-dependent.
674 fn read_be_uint(&mut self) -> IoResult<uint> {
675 self.read_be_uint_n(uint::BYTES).map(|i| i as uint)
676 }
677
678 /// Reads a big-endian integer.
679 ///
680 /// The number of bytes returned is system-dependent.
681 fn read_be_int(&mut self) -> IoResult<int> {
682 self.read_be_int_n(int::BYTES).map(|i| i as int)
683 }
684
685 /// Reads a big-endian `u64`.
686 ///
687 /// `u64`s are 8 bytes long.
688 fn read_be_u64(&mut self) -> IoResult<u64> {
689 self.read_be_uint_n(8)
690 }
691
692 /// Reads a big-endian `u32`.
693 ///
694 /// `u32`s are 4 bytes long.
695 fn read_be_u32(&mut self) -> IoResult<u32> {
696 self.read_be_uint_n(4).map(|i| i as u32)
697 }
698
699 /// Reads a big-endian `u16`.
700 ///
701 /// `u16`s are 2 bytes long.
702 fn read_be_u16(&mut self) -> IoResult<u16> {
703 self.read_be_uint_n(2).map(|i| i as u16)
704 }
705
706 /// Reads a big-endian `i64`.
707 ///
708 /// `i64`s are 8 bytes long.
709 fn read_be_i64(&mut self) -> IoResult<i64> {
710 self.read_be_int_n(8)
711 }
712
713 /// Reads a big-endian `i32`.
714 ///
715 /// `i32`s are 4 bytes long.
716 fn read_be_i32(&mut self) -> IoResult<i32> {
717 self.read_be_int_n(4).map(|i| i as i32)
718 }
719
720 /// Reads a big-endian `i16`.
721 ///
722 /// `i16`s are 2 bytes long.
723 fn read_be_i16(&mut self) -> IoResult<i16> {
724 self.read_be_int_n(2).map(|i| i as i16)
725 }
726
727 /// Reads a big-endian `f64`.
728 ///
729 /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
730 fn read_be_f64(&mut self) -> IoResult<f64> {
731 self.read_be_u64().map(|i| unsafe {
732 cast::transmute::<u64, f64>(i)
733 })
734 }
735
736 /// Reads a big-endian `f32`.
737 ///
738 /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
739 fn read_be_f32(&mut self) -> IoResult<f32> {
740 self.read_be_u32().map(|i| unsafe {
741 cast::transmute::<u32, f32>(i)
742 })
743 }
744
745 /// Reads a little-endian `u64`.
746 ///
747 /// `u64`s are 8 bytes long.
748 fn read_le_u64(&mut self) -> IoResult<u64> {
749 self.read_le_uint_n(8)
750 }
751
752 /// Reads a little-endian `u32`.
753 ///
754 /// `u32`s are 4 bytes long.
755 fn read_le_u32(&mut self) -> IoResult<u32> {
756 self.read_le_uint_n(4).map(|i| i as u32)
757 }
758
759 /// Reads a little-endian `u16`.
760 ///
761 /// `u16`s are 2 bytes long.
762 fn read_le_u16(&mut self) -> IoResult<u16> {
763 self.read_le_uint_n(2).map(|i| i as u16)
764 }
765
766 /// Reads a little-endian `i64`.
767 ///
768 /// `i64`s are 8 bytes long.
769 fn read_le_i64(&mut self) -> IoResult<i64> {
770 self.read_le_int_n(8)
771 }
772
773 /// Reads a little-endian `i32`.
774 ///
775 /// `i32`s are 4 bytes long.
776 fn read_le_i32(&mut self) -> IoResult<i32> {
777 self.read_le_int_n(4).map(|i| i as i32)
778 }
779
780 /// Reads a little-endian `i16`.
781 ///
782 /// `i16`s are 2 bytes long.
783 fn read_le_i16(&mut self) -> IoResult<i16> {
784 self.read_le_int_n(2).map(|i| i as i16)
785 }
786
787 /// Reads a little-endian `f64`.
788 ///
789 /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
790 fn read_le_f64(&mut self) -> IoResult<f64> {
791 self.read_le_u64().map(|i| unsafe {
792 cast::transmute::<u64, f64>(i)
793 })
794 }
795
796 /// Reads a little-endian `f32`.
797 ///
798 /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
799 fn read_le_f32(&mut self) -> IoResult<f32> {
800 self.read_le_u32().map(|i| unsafe {
801 cast::transmute::<u32, f32>(i)
802 })
803 }
804
805 /// Read a u8.
806 ///
807 /// `u8`s are 1 byte.
808 fn read_u8(&mut self) -> IoResult<u8> {
809 self.read_byte()
810 }
811
812 /// Read an i8.
813 ///
814 /// `i8`s are 1 byte.
815 fn read_i8(&mut self) -> IoResult<i8> {
816 self.read_byte().map(|i| i as i8)
817 }
818
819 /// Creates a wrapper around a mutable reference to the reader.
820 ///
821 /// This is useful to allow applying adaptors while still
822 /// retaining ownership of the original value.
823 fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> {
824 RefReader { inner: self }
825 }
826 }
827
828 impl Reader for Box<Reader> {
829 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
830 }
831
832 impl<'a> Reader for &'a mut Reader {
833 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
834 }
835
836 /// A `RefReader` is a struct implementing `Reader` which contains a reference
837 /// to another reader. This is often useful when composing streams.
838 ///
839 /// # Example
840 ///
841 /// ```
842 /// # fn main() {}
843 /// # fn process_input<R: Reader>(r: R) {}
844 /// # fn foo() {
845 /// use std::io;
846 /// use std::io::util::LimitReader;
847 ///
848 /// let mut stream = io::stdin();
849 ///
850 /// // Only allow the function to process at most one kilobyte of input
851 /// {
852 /// let stream = LimitReader::new(stream.by_ref(), 1024);
853 /// process_input(stream);
854 /// }
855 ///
856 /// // 'stream' is still available for use here
857 ///
858 /// # }
859 /// ```
860 pub struct RefReader<'a, R> {
861 /// The underlying reader which this is referencing
862 inner: &'a mut R
863 }
864
865 impl<'a, R: Reader> Reader for RefReader<'a, R> {
866 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
867 }
868
869 impl<'a, R: Buffer> Buffer for RefReader<'a, R> {
870 fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
871 fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
872 }
873
874 fn extend_sign(val: u64, nbytes: uint) -> i64 {
875 let shift = (8 - nbytes) * 8;
876 (val << shift) as i64 >> shift
877 }
878
879 /// A trait for objects which are byte-oriented streams. Writers are defined by
880 /// one method, `write`. This function will block until the provided buffer of
881 /// bytes has been entirely written, and it will return any failurs which occur.
882 ///
883 /// Another commonly overriden method is the `flush` method for writers such as
884 /// buffered writers.
885 ///
886 /// Writers are intended to be composable with one another. Many objects
887 /// throughout the I/O and related libraries take and provide types which
888 /// implement the `Writer` trait.
889 pub trait Writer {
890 /// Write the entirety of a given buffer
891 ///
892 /// # Errors
893 ///
894 /// If an error happens during the I/O operation, the error is returned as
895 /// `Err`. Note that it is considered an error if the entire buffer could
896 /// not be written, and if an error is returned then it is unknown how much
897 /// data (if any) was actually written.
898 fn write(&mut self, buf: &[u8]) -> IoResult<()>;
899
900 /// Flush this output stream, ensuring that all intermediately buffered
901 /// contents reach their destination.
902 ///
903 /// This is by default a no-op and implementers of the `Writer` trait should
904 /// decide whether their stream needs to be buffered or not.
905 fn flush(&mut self) -> IoResult<()> { Ok(()) }
906
907 /// Write a rust string into this sink.
908 ///
909 /// The bytes written will be the UTF-8 encoded version of the input string.
910 /// If other encodings are desired, it is recommended to compose this stream
911 /// with another performing the conversion, or to use `write` with a
912 /// converted byte-array instead.
913 fn write_str(&mut self, s: &str) -> IoResult<()> {
914 self.write(s.as_bytes())
915 }
916
917 /// Writes a string into this sink, and then writes a literal newline (`\n`)
918 /// byte afterwards. Note that the writing of the newline is *not* atomic in
919 /// the sense that the call to `write` is invoked twice (once with the
920 /// string and once with a newline character).
921 ///
922 /// If other encodings or line ending flavors are desired, it is recommended
923 /// that the `write` method is used specifically instead.
924 fn write_line(&mut self, s: &str) -> IoResult<()> {
925 self.write_str(s).and_then(|()| self.write(['\n' as u8]))
926 }
927
928 /// Write a single char, encoded as UTF-8.
929 fn write_char(&mut self, c: char) -> IoResult<()> {
930 let mut buf = [0u8, ..4];
931 let n = c.encode_utf8(buf.as_mut_slice());
932 self.write(buf.slice_to(n))
933 }
934
935 /// Write the result of passing n through `int::to_str_bytes`.
936 fn write_int(&mut self, n: int) -> IoResult<()> {
937 write!(self, "{:d}", n)
938 }
939
940 /// Write the result of passing n through `uint::to_str_bytes`.
941 fn write_uint(&mut self, n: uint) -> IoResult<()> {
942 write!(self, "{:u}", n)
943 }
944
945 /// Write a little-endian uint (number of bytes depends on system).
946 fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
947 extensions::u64_to_le_bytes(n as u64, uint::BYTES, |v| self.write(v))
948 }
949
950 /// Write a little-endian int (number of bytes depends on system).
951 fn write_le_int(&mut self, n: int) -> IoResult<()> {
952 extensions::u64_to_le_bytes(n as u64, int::BYTES, |v| self.write(v))
953 }
954
955 /// Write a big-endian uint (number of bytes depends on system).
956 fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
957 extensions::u64_to_be_bytes(n as u64, uint::BYTES, |v| self.write(v))
958 }
959
960 /// Write a big-endian int (number of bytes depends on system).
961 fn write_be_int(&mut self, n: int) -> IoResult<()> {
962 extensions::u64_to_be_bytes(n as u64, int::BYTES, |v| self.write(v))
963 }
964
965 /// Write a big-endian u64 (8 bytes).
966 fn write_be_u64(&mut self, n: u64) -> IoResult<()> {
967 extensions::u64_to_be_bytes(n, 8u, |v| self.write(v))
968 }
969
970 /// Write a big-endian u32 (4 bytes).
971 fn write_be_u32(&mut self, n: u32) -> IoResult<()> {
972 extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
973 }
974
975 /// Write a big-endian u16 (2 bytes).
976 fn write_be_u16(&mut self, n: u16) -> IoResult<()> {
977 extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
978 }
979
980 /// Write a big-endian i64 (8 bytes).
981 fn write_be_i64(&mut self, n: i64) -> IoResult<()> {
982 extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
983 }
984
985 /// Write a big-endian i32 (4 bytes).
986 fn write_be_i32(&mut self, n: i32) -> IoResult<()> {
987 extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
988 }
989
990 /// Write a big-endian i16 (2 bytes).
991 fn write_be_i16(&mut self, n: i16) -> IoResult<()> {
992 extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
993 }
994
995 /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
996 fn write_be_f64(&mut self, f: f64) -> IoResult<()> {
997 unsafe {
998 self.write_be_u64(cast::transmute(f))
999 }
1000 }
1001
1002 /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
1003 fn write_be_f32(&mut self, f: f32) -> IoResult<()> {
1004 unsafe {
1005 self.write_be_u32(cast::transmute(f))
1006 }
1007 }
1008
1009 /// Write a little-endian u64 (8 bytes).
1010 fn write_le_u64(&mut self, n: u64) -> IoResult<()> {
1011 extensions::u64_to_le_bytes(n, 8u, |v| self.write(v))
1012 }
1013
1014 /// Write a little-endian u32 (4 bytes).
1015 fn write_le_u32(&mut self, n: u32) -> IoResult<()> {
1016 extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1017 }
1018
1019 /// Write a little-endian u16 (2 bytes).
1020 fn write_le_u16(&mut self, n: u16) -> IoResult<()> {
1021 extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1022 }
1023
1024 /// Write a little-endian i64 (8 bytes).
1025 fn write_le_i64(&mut self, n: i64) -> IoResult<()> {
1026 extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
1027 }
1028
1029 /// Write a little-endian i32 (4 bytes).
1030 fn write_le_i32(&mut self, n: i32) -> IoResult<()> {
1031 extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
1032 }
1033
1034 /// Write a little-endian i16 (2 bytes).
1035 fn write_le_i16(&mut self, n: i16) -> IoResult<()> {
1036 extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
1037 }
1038
1039 /// Write a little-endian IEEE754 double-precision floating-point
1040 /// (8 bytes).
1041 fn write_le_f64(&mut self, f: f64) -> IoResult<()> {
1042 unsafe {
1043 self.write_le_u64(cast::transmute(f))
1044 }
1045 }
1046
1047 /// Write a little-endian IEEE754 single-precision floating-point
1048 /// (4 bytes).
1049 fn write_le_f32(&mut self, f: f32) -> IoResult<()> {
1050 unsafe {
1051 self.write_le_u32(cast::transmute(f))
1052 }
1053 }
1054
1055 /// Write a u8 (1 byte).
1056 fn write_u8(&mut self, n: u8) -> IoResult<()> {
1057 self.write([n])
1058 }
1059
1060 /// Write an i8 (1 byte).
1061 fn write_i8(&mut self, n: i8) -> IoResult<()> {
1062 self.write([n as u8])
1063 }
1064
1065 /// Creates a wrapper around a mutable reference to the writer.
1066 ///
1067 /// This is useful to allow applying wrappers while still
1068 /// retaining ownership of the original value.
1069 fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
1070 RefWriter { inner: self }
1071 }
1072 }
1073
1074 impl Writer for Box<Writer> {
1075 fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
1076 fn flush(&mut self) -> IoResult<()> { self.flush() }
1077 }
1078
1079 impl<'a> Writer for &'a mut Writer {
1080 fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
1081 fn flush(&mut self) -> IoResult<()> { self.flush() }
1082 }
1083
1084 /// A `RefWriter` is a struct implementing `Writer` which contains a reference
1085 /// to another writer. This is often useful when composing streams.
1086 ///
1087 /// # Example
1088 ///
1089 /// ```
1090 /// # fn main() {}
1091 /// # fn process_input<R: Reader>(r: R) {}
1092 /// # fn foo () {
1093 /// use std::io::util::TeeReader;
1094 /// use std::io::{stdin, MemWriter};
1095 ///
1096 /// let mut output = MemWriter::new();
1097 ///
1098 /// {
1099 /// // Don't give ownership of 'output' to the 'tee'. Instead we keep a
1100 /// // handle to it in the outer scope
1101 /// let mut tee = TeeReader::new(stdin(), output.by_ref());
1102 /// process_input(tee);
1103 /// }
1104 ///
1105 /// println!("input processed: {}", output.unwrap());
1106 /// # }
1107 /// ```
1108 pub struct RefWriter<'a, W> {
1109 /// The underlying writer which this is referencing
1110 inner: &'a mut W
1111 }
1112
1113 impl<'a, W: Writer> Writer for RefWriter<'a, W> {
1114 fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
1115 fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
1116 }
1117
1118
1119 /// A Stream is a readable and a writable object. Data written is typically
1120 /// received by the object which reads receive data from.
1121 pub trait Stream: Reader + Writer { }
1122
1123 impl<T: Reader + Writer> Stream for T {}
1124
1125 /// An iterator that reads a line on each iteration,
1126 /// until `.read_line()` encounters `EndOfFile`.
1127 ///
1128 /// # Notes about the Iteration Protocol
1129 ///
1130 /// The `Lines` may yield `None` and thus terminate
1131 /// an iteration, but continue to yield elements if iteration
1132 /// is attempted again.
1133 ///
1134 /// # Error
1135 ///
1136 /// Any error other than `EndOfFile` that is produced by the underlying Reader
1137 /// is returned by the iterator and should be handled by the caller.
1138 pub struct Lines<'r, T> {
1139 buffer: &'r mut T,
1140 }
1141
1142 impl<'r, T: Buffer> Iterator<IoResult<~str>> for Lines<'r, T> {
1143 fn next(&mut self) -> Option<IoResult<~str>> {
1144 match self.buffer.read_line() {
1145 Ok(x) => Some(Ok(x)),
1146 Err(IoError { kind: EndOfFile, ..}) => None,
1147 Err(y) => Some(Err(y))
1148 }
1149 }
1150 }
1151
1152 /// An iterator that reads a utf8-encoded character on each iteration,
1153 /// until `.read_char()` encounters `EndOfFile`.
1154 ///
1155 /// # Notes about the Iteration Protocol
1156 ///
1157 /// The `Chars` may yield `None` and thus terminate
1158 /// an iteration, but continue to yield elements if iteration
1159 /// is attempted again.
1160 ///
1161 /// # Error
1162 ///
1163 /// Any error other than `EndOfFile` that is produced by the underlying Reader
1164 /// is returned by the iterator and should be handled by the caller.
1165 pub struct Chars<'r, T> {
1166 buffer: &'r mut T
1167 }
1168
1169 impl<'r, T: Buffer> Iterator<IoResult<char>> for Chars<'r, T> {
1170 fn next(&mut self) -> Option<IoResult<char>> {
1171 match self.buffer.read_char() {
1172 Ok(x) => Some(Ok(x)),
1173 Err(IoError { kind: EndOfFile, ..}) => None,
1174 Err(y) => Some(Err(y))
1175 }
1176 }
1177 }
1178
1179 /// A Buffer is a type of reader which has some form of internal buffering to
1180 /// allow certain kinds of reading operations to be more optimized than others.
1181 /// This type extends the `Reader` trait with a few methods that are not
1182 /// possible to reasonably implement with purely a read interface.
1183 pub trait Buffer: Reader {
1184 /// Fills the internal buffer of this object, returning the buffer contents.
1185 /// Note that none of the contents will be "read" in the sense that later
1186 /// calling `read` may return the same contents.
1187 ///
1188 /// The `consume` function must be called with the number of bytes that are
1189 /// consumed from this buffer returned to ensure that the bytes are never
1190 /// returned twice.
1191 ///
1192 /// # Error
1193 ///
1194 /// This function will return an I/O error if the underlying reader was
1195 /// read, but returned an error. Note that it is not an error to return a
1196 /// 0-length buffer.
1197 fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]>;
1198
1199 /// Tells this buffer that `amt` bytes have been consumed from the buffer,
1200 /// so they should no longer be returned in calls to `fill` or `read`.
1201 fn consume(&mut self, amt: uint);
1202
1203 /// Reads the next line of input, interpreted as a sequence of UTF-8
1204 /// encoded unicode codepoints. If a newline is encountered, then the
1205 /// newline is contained in the returned string.
1206 ///
1207 /// # Example
1208 ///
1209 /// ```rust
1210 /// use std::io;
1211 ///
1212 /// let mut reader = io::stdin();
1213 /// let input = reader.read_line().ok().unwrap_or("nothing".to_owned());
1214 /// ```
1215 ///
1216 /// # Error
1217 ///
1218 /// This function has the same error semantics as `read_until`:
1219 ///
1220 /// * All non-EOF errors will be returned immediately
1221 /// * If an error is returned previously consumed bytes are lost
1222 /// * EOF is only returned if no bytes have been read
1223 /// * Reach EOF may mean that the delimiter is not present in the return
1224 /// value
1225 ///
1226 /// Additionally, this function can fail if the line of input read is not a
1227 /// valid UTF-8 sequence of bytes.
1228 fn read_line(&mut self) -> IoResult<~str> {
1229 self.read_until('\n' as u8).and_then(|line|
1230 match str::from_utf8(line.as_slice()) {
1231 Some(s) => Ok(s.to_owned()),
1232 None => Err(standard_error(InvalidInput)),
1233 }
1234 )
1235 }
1236
1237 /// Create an iterator that reads a line on each iteration until EOF.
1238 ///
1239 /// # Error
1240 ///
1241 /// Any error other than `EndOfFile` that is produced by the underlying Reader
1242 /// is returned by the iterator and should be handled by the caller.
1243 fn lines<'r>(&'r mut self) -> Lines<'r, Self> {
1244 Lines { buffer: self }
1245 }
1246
1247 /// Reads a sequence of bytes leading up to a specified delimiter. Once the
1248 /// specified byte is encountered, reading ceases and the bytes up to and
1249 /// including the delimiter are returned.
1250 ///
1251 /// # Error
1252 ///
1253 /// If any I/O error is encountered other than EOF, the error is immediately
1254 /// returned. Note that this may discard bytes which have already been read,
1255 /// and those bytes will *not* be returned. It is recommended to use other
1256 /// methods if this case is worrying.
1257 ///
1258 /// If EOF is encountered, then this function will return EOF if 0 bytes
1259 /// have been read, otherwise the pending byte buffer is returned. This
1260 /// is the reason that the byte buffer returned may not always contain the
1261 /// delimiter.
1262 fn read_until(&mut self, byte: u8) -> IoResult<Vec<u8>> {
1263 let mut res = Vec::new();
1264
1265 let mut used;
1266 loop {
1267 {
1268 let available = match self.fill_buf() {
1269 Ok(n) => n,
1270 Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
1271 used = 0;
1272 break
1273 }
1274 Err(e) => return Err(e)
1275 };
1276 match available.iter().position(|&b| b == byte) {
1277 Some(i) => {
1278 res.push_all(available.slice_to(i + 1));
1279 used = i + 1;
1280 break
1281 }
1282 None => {
1283 res.push_all(available);
1284 used = available.len();
1285 }
1286 }
1287 }
1288 self.consume(used);
1289 }
1290 self.consume(used);
1291 Ok(res)
1292 }
1293
1294 /// Reads the next utf8-encoded character from the underlying stream.
1295 ///
1296 /// # Error
1297 ///
1298 /// If an I/O error occurs, or EOF, then this function will return `Err`.
1299 /// This function will also return error if the stream does not contain a
1300 /// valid utf-8 encoded codepoint as the next few bytes in the stream.
1301 fn read_char(&mut self) -> IoResult<char> {
1302 let first_byte = try!(self.read_byte());
1303 let width = str::utf8_char_width(first_byte);
1304 if width == 1 { return Ok(first_byte as char) }
1305 if width == 0 { return Err(standard_error(InvalidInput)) } // not utf8
1306 let mut buf = [first_byte, 0, 0, 0];
1307 {
1308 let mut start = 1;
1309 while start < width {
1310 match try!(self.read(buf.mut_slice(start, width))) {
1311 n if n == width - start => break,
1312 n if n < width - start => { start += n; }
1313 _ => return Err(standard_error(InvalidInput)),
1314 }
1315 }
1316 }
1317 match str::from_utf8(buf.slice_to(width)) {
1318 Some(s) => Ok(s.char_at(0)),
1319 None => Err(standard_error(InvalidInput))
1320 }
1321 }
1322
1323 /// Create an iterator that reads a utf8-encoded character on each iteration
1324 /// until EOF.
1325 ///
1326 /// # Error
1327 ///
1328 /// Any error other than `EndOfFile` that is produced by the underlying Reader
1329 /// is returned by the iterator and should be handled by the caller.
1330 fn chars<'r>(&'r mut self) -> Chars<'r, Self> {
1331 Chars { buffer: self }
1332 }
1333 }
1334
1335 /// When seeking, the resulting cursor is offset from a base by the offset given
1336 /// to the `seek` function. The base used is specified by this enumeration.
1337 pub enum SeekStyle {
1338 /// Seek from the beginning of the stream
1339 SeekSet,
1340 /// Seek from the end of the stream
1341 SeekEnd,
1342 /// Seek from the current position
1343 SeekCur,
1344 }
1345
1346 /// An object implementing `Seek` internally has some form of cursor which can
1347 /// be moved within a stream of bytes. The stream typically has a fixed size,
1348 /// allowing seeking relative to either end.
1349 pub trait Seek {
1350 /// Return position of file cursor in the stream
1351 fn tell(&self) -> IoResult<u64>;
1352
1353 /// Seek to an offset in a stream
1354 ///
1355 /// A successful seek clears the EOF indicator. Seeking beyond EOF is
1356 /// allowed, but seeking before position 0 is not allowed.
1357 ///
1358 /// # Errors
1359 ///
1360 /// * Seeking to a negative offset is considered an error
1361 /// * Seeking past the end of the stream does not modify the underlying
1362 /// stream, but the next write may cause the previous data to be filled in
1363 /// with a bit pattern.
1364 fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>;
1365 }
1366
1367 /// A listener is a value that can consume itself to start listening for
1368 /// connections.
1369 ///
1370 /// Doing so produces some sort of Acceptor.
1371 pub trait Listener<T, A: Acceptor<T>> {
1372 /// Spin up the listener and start queuing incoming connections
1373 ///
1374 /// # Error
1375 ///
1376 /// Returns `Err` if this listener could not be bound to listen for
1377 /// connections. In all cases, this listener is consumed.
1378 fn listen(self) -> IoResult<A>;
1379 }
1380
1381 /// An acceptor is a value that presents incoming connections
1382 pub trait Acceptor<T> {
1383 /// Wait for and accept an incoming connection
1384 ///
1385 /// # Error
1386 ///
1387 /// Returns `Err` if an I/O error is encountered.
1388 fn accept(&mut self) -> IoResult<T>;
1389
1390 /// Create an iterator over incoming connection attempts.
1391 ///
1392 /// Note that I/O errors will be yielded by the iterator itself.
1393 fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
1394 IncomingConnections { inc: self }
1395 }
1396 }
1397
1398 /// An infinite iterator over incoming connection attempts.
1399 /// Calling `next` will block the task until a connection is attempted.
1400 ///
1401 /// Since connection attempts can continue forever, this iterator always returns
1402 /// `Some`. The `Some` contains the `IoResult` representing whether the
1403 /// connection attempt was successful. A successful connection will be wrapped
1404 /// in `Ok`. A failed connection is represented as an `Err`.
1405 pub struct IncomingConnections<'a, A> {
1406 inc: &'a mut A,
1407 }
1408
1409 impl<'a, T, A: Acceptor<T>> Iterator<IoResult<T>> for IncomingConnections<'a, A> {
1410 fn next(&mut self) -> Option<IoResult<T>> {
1411 Some(self.inc.accept())
1412 }
1413 }
1414
1415 /// Creates a standard error for a commonly used flavor of error. The `detail`
1416 /// field of the returned error will always be `None`.
1417 ///
1418 /// # Example
1419 ///
1420 /// ```
1421 /// use std::io;
1422 ///
1423 /// let eof = io::standard_error(io::EndOfFile);
1424 /// let einval = io::standard_error(io::InvalidInput);
1425 /// ```
1426 pub fn standard_error(kind: IoErrorKind) -> IoError {
1427 let desc = match kind {
1428 EndOfFile => "end of file",
1429 IoUnavailable => "I/O is unavailable",
1430 InvalidInput => "invalid input",
1431 OtherIoError => "unknown I/O error",
1432 FileNotFound => "file not found",
1433 PermissionDenied => "permission denied",
1434 ConnectionFailed => "connection failed",
1435 Closed => "stream is closed",
1436 ConnectionRefused => "connection refused",
1437 ConnectionReset => "connection reset",
1438 ConnectionAborted => "connection aborted",
1439 NotConnected => "not connected",
1440 BrokenPipe => "broken pipe",
1441 PathAlreadyExists => "file exists",
1442 PathDoesntExist => "no such file",
1443 MismatchedFileTypeForOperation => "mismatched file type",
1444 ResourceUnavailable => "resource unavailable",
1445 TimedOut => "operation timed out",
1446 ShortWrite(..) => "short write",
1447 };
1448 IoError {
1449 kind: kind,
1450 desc: desc,
1451 detail: None,
1452 }
1453 }
1454
1455 /// A mode specifies how a file should be opened or created. These modes are
1456 /// passed to `File::open_mode` and are used to control where the file is
1457 /// positioned when it is initially opened.
1458 pub enum FileMode {
1459 /// Opens a file positioned at the beginning.
1460 Open,
1461 /// Opens a file positioned at EOF.
1462 Append,
1463 /// Opens a file, truncating it if it already exists.
1464 Truncate,
1465 }
1466
1467 /// Access permissions with which the file should be opened. `File`s
1468 /// opened with `Read` will return an error if written to.
1469 pub enum FileAccess {
1470 /// Read-only access, requests to write will result in an error
1471 Read,
1472 /// Write-only access, requests to read will result in an error
1473 Write,
1474 /// Read-write access, no requests are denied by default
1475 ReadWrite,
1476 }
1477
1478 /// Different kinds of files which can be identified by a call to stat
1479 #[deriving(Eq, Show, Hash)]
1480 pub enum FileType {
1481 /// This is a normal file, corresponding to `S_IFREG`
1482 TypeFile,
1483
1484 /// This file is a directory, corresponding to `S_IFDIR`
1485 TypeDirectory,
1486
1487 /// This file is a named pipe, corresponding to `S_IFIFO`
1488 TypeNamedPipe,
1489
1490 /// This file is a block device, corresponding to `S_IFBLK`
1491 TypeBlockSpecial,
1492
1493 /// This file is a symbolic link to another file, corresponding to `S_IFLNK`
1494 TypeSymlink,
1495
1496 /// The type of this file is not recognized as one of the other categories
1497 TypeUnknown,
1498 }
1499
1500 /// A structure used to describe metadata information about a file. This
1501 /// structure is created through the `stat` method on a `Path`.
1502 ///
1503 /// # Example
1504 ///
1505 /// ```
1506 /// # fn main() {}
1507 /// # fn foo() {
1508 /// let info = match Path::new("foo.txt").stat() {
1509 /// Ok(stat) => stat,
1510 /// Err(e) => fail!("couldn't read foo.txt: {}", e),
1511 /// };
1512 ///
1513 /// println!("path: {}", info.path.display());
1514 /// println!("byte size: {}", info.size);
1515 /// # }
1516 /// ```
1517 #[deriving(Hash)]
1518 pub struct FileStat {
1519 /// The path that this stat structure is describing
1520 pub path: Path,
1521 /// The size of the file, in bytes
1522 pub size: u64,
1523 /// The kind of file this path points to (directory, file, pipe, etc.)
1524 pub kind: FileType,
1525 /// The file permissions currently on the file
1526 pub perm: FilePermission,
1527
1528 // FIXME(#10301): These time fields are pretty useless without an actual
1529 // time representation, what are the milliseconds relative
1530 // to?
1531
1532 /// The time that the file was created at, in platform-dependent
1533 /// milliseconds
1534 pub created: u64,
1535 /// The time that this file was last modified, in platform-dependent
1536 /// milliseconds
1537 pub modified: u64,
1538 /// The time that this file was last accessed, in platform-dependent
1539 /// milliseconds
1540 pub accessed: u64,
1541
1542 /// Information returned by stat() which is not guaranteed to be
1543 /// platform-independent. This information may be useful on some platforms,
1544 /// but it may have different meanings or no meaning at all on other
1545 /// platforms.
1546 ///
1547 /// Usage of this field is discouraged, but if access is desired then the
1548 /// fields are located here.
1549 #[unstable]
1550 pub unstable: UnstableFileStat,
1551 }
1552
1553 /// This structure represents all of the possible information which can be
1554 /// returned from a `stat` syscall which is not contained in the `FileStat`
1555 /// structure. This information is not necessarily platform independent, and may
1556 /// have different meanings or no meaning at all on some platforms.
1557 #[unstable]
1558 #[deriving(Hash)]
1559 pub struct UnstableFileStat {
1560 /// The ID of the device containing the file.
1561 pub device: u64,
1562 /// The file serial number.
1563 pub inode: u64,
1564 /// The device ID.
1565 pub rdev: u64,
1566 /// The number of hard links to this file.
1567 pub nlink: u64,
1568 /// The user ID of the file.
1569 pub uid: u64,
1570 /// The group ID of the file.
1571 pub gid: u64,
1572 /// The optimal block size for I/O.
1573 pub blksize: u64,
1574 /// The blocks allocated for this file.
1575 pub blocks: u64,
1576 /// User-defined flags for the file.
1577 pub flags: u64,
1578 /// The file generation number.
1579 pub gen: u64,
1580 }
1581
1582 bitflags!(
1583 #[doc="A set of permissions for a file or directory is represented
1584 by a set of flags which are or'd together."]
1585 #[deriving(Hash)]
1586 #[deriving(Show)]
1587 flags FilePermission: u32 {
1588 static UserRead = 0o400,
1589 static UserWrite = 0o200,
1590 static UserExecute = 0o100,
1591 static GroupRead = 0o040,
1592 static GroupWrite = 0o020,
1593 static GroupExecute = 0o010,
1594 static OtherRead = 0o004,
1595 static OtherWrite = 0o002,
1596 static OtherExecute = 0o001,
1597
1598 static UserRWX = UserRead.bits | UserWrite.bits | UserExecute.bits,
1599 static GroupRWX = GroupRead.bits | GroupWrite.bits | GroupExecute.bits,
1600 static OtherRWX = OtherRead.bits | OtherWrite.bits | OtherExecute.bits,
1601
1602 #[doc="Permissions for user owned files, equivalent to 0644 on
1603 unix-like systems."]
1604 static UserFile = UserRead.bits | UserWrite.bits | GroupRead.bits | OtherRead.bits,
1605
1606 #[doc="Permissions for user owned directories, equivalent to 0755 on
1607 unix-like systems."]
1608 static UserDir = UserRWX.bits | GroupRead.bits | GroupExecute.bits |
1609 OtherRead.bits | OtherExecute.bits,
1610
1611 #[doc="Permissions for user owned executables, equivalent to 0755
1612 on unix-like systems."]
1613 static UserExec = UserDir.bits,
1614
1615 #[doc="All possible permissions enabled."]
1616 static AllPermissions = UserRWX.bits | GroupRWX.bits | OtherRWX.bits
1617 }
1618 )
libstd/io/mod.rs:1370:45-1370:45 -trait- definition:
/// Doing so produces some sort of Acceptor.
pub trait Listener<T, A: Acceptor<T>> {
/// Spin up the listener and start queuing incoming connections
references:- 4libstd/io/result.rs:
61: impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for IoResult<L> {
62: fn listen(self) -> IoResult<A> {
libstd/io/net/tcp.rs:
306: impl Listener<TcpStream, TcpAcceptor> for TcpListener {
307: fn listen(self) -> IoResult<TcpAcceptor> {
libstd/io/net/unix.rs:
172: impl Listener<UnixStream, UnixAcceptor> for UnixListener {
173: fn listen(self) -> IoResult<UnixAcceptor> {
libstd/io/result.rs:
61: impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for IoResult<L> {
62: fn listen(self) -> IoResult<A> {
libstd/io/mod.rs:458:34-458:34 -trait- definition:
/// implement the `Reader` trait.
pub trait Reader {
// Only method which need to get implemented for this trait
references:- 43libstd/io/buffered.rs:
libstd/io/comm_adapters.rs:
libstd/io/mem.rs:
libstd/io/result.rs:
libstd/io/extensions.rs:
libstd/io/fs.rs:
libstd/io/net/tcp.rs:
libstd/io/net/udp.rs:
libstd/io/net/unix.rs:
libstd/io/pipe.rs:
libstd/io/stdio.rs:
libstd/io/util.rs:
libstd/io/mem.rs:
libstd/io/mod.rs:1558:18-1558:18 -struct- definition:
pub struct UnstableFileStat {
/// The ID of the device containing the file.
pub device: u64,
references:- 31559: pub struct UnstableFileStat {
libstd/io/mod.rs:1348:45-1348:45 -trait- definition:
/// allowing seeking relative to either end.
pub trait Seek {
/// Return position of file cursor in the stream
references:- 7libstd/io/mem.rs:
184: impl Seek for MemReader {
185: fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
--
256: impl<'a> Seek for BufWriter<'a> {
257: fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
--
316: impl<'a> Seek for BufReader<'a> {
317: fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
libstd/io/result.rs:
46: impl<S: Seek> Seek for IoResult<S> {
47: fn tell(&self) -> IoResult<u64> {
libstd/io/fs.rs:
632: impl Seek for File {
633: fn tell(&self) -> IoResult<u64> {
libstd/io/mem.rs:
114: impl Seek for MemWriter {
115: fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
libstd/io/mod.rs:285:64-285:64 -NK_AS_STR_TODO- definition:
/// A convenient typedef of the return value of any I/O action.
pub type IoResult<T> = Result<T, IoError>;
/// The type passed to I/O condition handlers to indicate error
references:- 331libstd/io/buffered.rs:
libstd/io/comm_adapters.rs:
libstd/io/mem.rs:
libstd/io/result.rs:
libstd/io/extensions.rs:
libstd/io/fs.rs:
libstd/io/net/addrinfo.rs:
libstd/io/net/tcp.rs:
libstd/io/net/udp.rs:
libstd/io/net/unix.rs:
libstd/io/pipe.rs:
libstd/io/process.rs:
libstd/io/stdio.rs:
libstd/io/timer.rs:
libstd/io/util.rs:
libstd/fmt/mod.rs:
libstd/repr.rs:
libstd/rt/rtio.rs:
libstd/rt/backtrace.rs:
libstd/rt/util.rs:
libstd/hash/sip.rs:
libstd/io/signal.rs:
libstd/io/mod.rs:1164:69-1164:69 -struct- definition:
/// is returned by the iterator and should be handled by the caller.
pub struct Chars<'r, T> {
buffer: &'r mut T
references:- 31330: fn chars<'r>(&'r mut self) -> Chars<'r, Self> {
1331: Chars { buffer: self }
1332: }
libstd/io/mod.rs:888:34-888:34 -trait- definition:
/// implement the `Writer` trait.
pub trait Writer {
/// Write the entirety of a given buffer
references:- 372libstd/io/buffered.rs:
libstd/io/comm_adapters.rs:
libstd/io/mem.rs:
libstd/io/result.rs:
libstd/io/fs.rs:
libstd/io/net/tcp.rs:
libstd/io/net/udp.rs:
libstd/io/net/ip.rs:
libstd/io/net/unix.rs:
libstd/io/pipe.rs:
libstd/io/signal.rs:
libstd/io/stdio.rs:
libstd/io/util.rs:
libstd/path/posix.rs:
libstd/path/windows.rs:
libstd/fmt/mod.rs:
libstd/repr.rs:
libstd/rt/task.rs:
libstd/rt/backtrace.rs:
libstd/rt/util.rs:
libstd/macros.rs:
libstd/str.rs:
libstd/strbuf.rs:
libstd/ascii.rs:
libstd/hash/mod.rs:
libstd/hash/sip.rs:
libstd/task.rs:
libstd/macros.rs:
libstd/io/mod.rs:859:8-859:8 -struct- definition:
/// ```
pub struct RefReader<'a, R> {
/// The underlying reader which this is referencing
references:- 4865: impl<'a, R: Reader> Reader for RefReader<'a, R> {
866: fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
--
869: impl<'a, R: Buffer> Buffer for RefReader<'a, R> {
870: fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
libstd/io/mod.rs:1336:76-1336:76 -enum- definition:
/// to the `seek` function. The base used is specified by this enumeration.
pub enum SeekStyle {
/// Seek from the beginning of the stream
references:- 91363: /// with a bit pattern.
1364: fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>;
1365: }
libstd/io/mem.rs:
257: fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
258: fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
259: let new = try!(combine(style, self.pos, self.buf.len(), pos));
--
317: fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
318: fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
319: let new = try!(combine(style, self.pos, self.buf.len(), pos));
libstd/io/result.rs:
52: }
53: fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
54: match *self {
libstd/rt/rtio.rs:
266: fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()>;
267: fn seek(&mut self, pos: i64, whence: SeekStyle) -> IoResult<u64>;
268: fn tell(&self) -> IoResult<u64>;
libstd/io/fs.rs:
637: fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
638: match self.fd.seek(pos, style) {
libstd/io/mod.rs:1457:44-1457:44 -enum- definition:
/// positioned when it is initially opened.
pub enum FileMode {
/// Opens a file positioned at the beginning.
references:- 2libstd/rt/rtio.rs:
168: -> Box<RtioFileStream:Send>;
169: fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
170: -> IoResult<Box<RtioFileStream:Send>>;
libstd/io/fs.rs:
126: pub fn open_mode(path: &Path,
127: mode: FileMode,
128: access: FileAccess) -> IoResult<File> {
libstd/io/mod.rs:1137:69-1137:69 -struct- definition:
/// is returned by the iterator and should be handled by the caller.
pub struct Lines<'r, T> {
buffer: &'r mut T,
references:- 31242: /// is returned by the iterator and should be handled by the caller.
1243: fn lines<'r>(&'r mut self) -> Lines<'r, Self> {
1244: Lines { buffer: self }
1245: }
libstd/io/mod.rs:1120:58-1120:58 -trait- definition:
/// received by the object which reads receive data from.
pub trait Stream: Reader + Writer { }
impl<T: Reader + Writer> Stream for T {}
references:- 5libstd/io/buffered.rs:
358: impl<S: Stream> Writer for BufferedStream<S> {
359: fn write(&mut self, buf: &[u8]) -> IoResult<()> {
libstd/io/mod.rs:
1123: impl<T: Reader + Writer> Stream for T {}
libstd/io/mod.rs:1425:8-1425:8 -fn- definition:
/// ```
pub fn standard_error(kind: IoErrorKind) -> IoError {
let desc = match kind {
references:- 181318: Some(s) => Ok(s.char_at(0)),
1319: None => Err(standard_error(InvalidInput))
1320: }
libstd/io/comm_adapters.rs:
80: if self.closed && num_read == 0 {
81: Err(io::standard_error(io::EndOfFile))
82: } else {
libstd/io/mem.rs:
329: } else {
330: Err(io::standard_error(io::EndOfFile))
331: }
libstd/io/fs.rs:
618: match read {
619: 0 => Err(io::standard_error(io::EndOfFile)),
620: _ => Ok(read as uint)
libstd/io/stdio.rs:
310: // end-of-file indicator so the caller knows to stop reading.
311: Ok(0) => { Err(standard_error(EndOfFile)) }
312: ret @ Ok(..) | ret @ Err(..) => ret,
libstd/io/util.rs:
46: if self.limit == 0 {
47: return Err(io::standard_error(io::EndOfFile));
48: }
--
62: if buf.len() == 0 {
63: Err(io::standard_error(io::EndOfFile))
64: } else {
--
185: }
186: Err(io::standard_error(io::EndOfFile))
187: }
libstd/rt/rtio.rs:
130: match LocalIo::borrow() {
131: None => Err(io::standard_error(io::IoUnavailable)),
132: Some(mut io) => f(io.get()),
libstd/io/util.rs:
108: fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
109: Err(io::standard_error(io::EndOfFile))
110: }
libstd/io/mod.rs:1517:18-1517:18 -struct- definition:
pub struct FileStat {
/// The path that this stat structure is describing
pub path: Path,
references:- 81516: /// ```
1518: pub struct FileStat {
libstd/io/fs.rs:
264: /// filesystem at the provided path.
265: pub fn stat(path: &Path) -> IoResult<FileStat> {
266: LocalIo::maybe_raise(|io| {
--
662: /// This call preserves identical runtime/error semantics with `file::lstat`.
663: pub fn lstat(&self) -> IoResult<FileStat> { lstat(self) }
libstd/rt/rtio.rs:
171: fn fs_unlink(&mut self, path: &CString) -> IoResult<()>;
172: fn fs_stat(&mut self, path: &CString) -> IoResult<FileStat>;
173: fn fs_mkdir(&mut self, path: &CString,
--
180: IoResult<Vec<Path>>;
181: fn fs_lstat(&mut self, path: &CString) -> IoResult<FileStat>;
182: fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
libstd/io/mod.rs:
1516: /// ```
1518: pub struct FileStat {
libstd/io/mod.rs:1107:8-1107:8 -struct- definition:
/// ```
pub struct RefWriter<'a, W> {
/// The underlying writer which this is referencing
references:- 31069: fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
1070: RefWriter { inner: self }
1071: }
--
1113: impl<'a, W: Writer> Writer for RefWriter<'a, W> {
1114: fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
libstd/io/mod.rs:399:29-399:29 -enum- definition:
pub enum IoErrorKind {
/// Any I/O error not part of this list.
OtherIoError,
references:- 9296: /// of error.
297: pub kind: IoErrorKind,
298: /// A human-readable description about the error
--
343: #[cfg(not(windows))]
344: fn get_err(errno: i32) -> (IoErrorKind, &'static str) {
345: // FIXME: this should probably be a bit more descriptive...
--
398: /// A list specifying general categories of I/O error.
400: pub enum IoErrorKind {
--
1425: /// ```
1426: pub fn standard_error(kind: IoErrorKind) -> IoError {
1427: let desc = match kind {
libstd/io/mod.rs:1404:61-1404:61 -struct- definition:
/// in `Ok`. A failed connection is represented as an `Err`.
pub struct IncomingConnections<'a, A> {
inc: &'a mut A,
references:- 31393: fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
1394: IncomingConnections { inc: self }
1395: }
--
1409: impl<'a, T, A: Acceptor<T>> Iterator<IoResult<T>> for IncomingConnections<'a, A> {
1410: fn next(&mut self) -> Option<IoResult<T>> {
libstd/io/mod.rs:1381:62-1381:62 -trait- definition:
/// An acceptor is a value that presents incoming connections
pub trait Acceptor<T> {
/// Wait for and accept an incoming connection
references:- 81370: /// Doing so produces some sort of Acceptor.
1371: pub trait Listener<T, A: Acceptor<T>> {
1372: /// Spin up the listener and start queuing incoming connections
--
1392: /// Note that I/O errors will be yielded by the iterator itself.
1393: fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
1394: IncomingConnections { inc: self }
--
1409: impl<'a, T, A: Acceptor<T>> Iterator<IoResult<T>> for IncomingConnections<'a, A> {
1410: fn next(&mut self) -> Option<IoResult<T>> {
libstd/io/result.rs:
70: impl<T, A: Acceptor<T>> Acceptor<T> for IoResult<A> {
71: fn accept(&mut self) -> IoResult<T> {
libstd/io/net/unix.rs:
203: impl Acceptor<UnixStream> for UnixAcceptor {
204: fn accept(&mut self) -> IoResult<UnixStream> {
libstd/io/net/tcp.rs:
369: impl Acceptor<TcpStream> for TcpAcceptor {
370: fn accept(&mut self) -> IoResult<TcpStream> {
libstd/io/mod.rs:1479:28-1479:28 -enum- definition:
pub enum FileType {
/// This is a normal file, corresponding to `S_IFREG`
TypeFile,
references:- 61478: /// Different kinds of files which can be identified by a call to stat
1480: pub enum FileType {
--
1523: /// The kind of file this path points to (directory, file, pipe, etc.)
1524: pub kind: FileType,
1525: /// The file permissions currently on the file
libstd/io/mod.rs:1468:59-1468:59 -enum- definition:
/// opened with `Read` will return an error if written to.
pub enum FileAccess {
/// Read-only access, requests to write will result in an error
references:- 2libstd/rt/rtio.rs:
168: -> Box<RtioFileStream:Send>;
169: fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
170: -> IoResult<Box<RtioFileStream:Send>>;
libstd/io/fs.rs:
127: mode: FileMode,
128: access: FileAccess) -> IoResult<File> {
129: LocalIo::maybe_raise(|io| {
libstd/io/mod.rs:293:23-293:23 -struct- definition:
pub struct IoError {
/// An enumeration which can be matched against for determining the flavor
/// of error.
references:- 30libstd/io/comm_adapters.rs:
libstd/io/mem.rs:
libstd/io/fs.rs:
libstd/io/stdio.rs:
libstd/io/mod.rs:
libstd/io/extensions.rs:
libstd/repr.rs:
libstd/rt/backtrace.rs:
libstd/io/mod.rs:
libstd/io/mod.rs:873:1-873:1 -fn- definition:
fn extend_sign(val: u64, nbytes: uint) -> i64 {
let shift = (8 - nbytes) * 8;
(val << shift) as i64 >> shift
references:- 2631: fn read_le_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
632: self.read_le_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
633: }
--
653: fn read_be_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
654: self.read_be_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
655: }
libstd/io/mod.rs:1182:67-1182:67 -trait- definition:
/// possible to reasonably implement with purely a read interface.
pub trait Buffer: Reader {
/// Fills the internal buffer of this object, returning the buffer contents.
references:- 141242: /// is returned by the iterator and should be handled by the caller.
1243: fn lines<'r>(&'r mut self) -> Lines<'r, Self> {
1244: Lines { buffer: self }
--
1329: /// is returned by the iterator and should be handled by the caller.
1330: fn chars<'r>(&'r mut self) -> Chars<'r, Self> {
1331: Chars { buffer: self }
libstd/io/buffered.rs:
347: impl<S: Stream> Buffer for BufferedStream<S> {
348: fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
libstd/io/mem.rs:
193: impl Buffer for MemReader {
194: fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
--
325: impl<'a> Buffer for BufReader<'a> {
326: fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
libstd/io/util.rs:
58: impl<R: Buffer> Buffer for LimitReader<R> {
59: fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
--
95: impl Buffer for ZeroReader {
96: fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
--
113: impl Buffer for NullReader {
114: fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
libstd/io/mod.rs:
1142: impl<'r, T: Buffer> Iterator<IoResult<~str>> for Lines<'r, T> {
1143: fn next(&mut self) -> Option<IoResult<~str>> {