diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-05-13 15:23:52 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-05-15 12:19:16 -0700 |
| commit | 28a13ec8d76ba9a4f9645991e1260882a3b7dc68 (patch) | |
| tree | 56f71c53cd8f478c2be4f6b663645b8b834c8a8f | |
| parent | 1c1f11e649c52135435f6ea747426568edac56a2 (diff) | |
core::rt: Make push_bytes raise read_error on EOF
| -rw-r--r-- | src/libcore/rt/io/extensions.rs | 50 | ||||
| -rw-r--r-- | src/libcore/rt/io/mod.rs | 14 |
2 files changed, 45 insertions, 19 deletions
diff --git a/src/libcore/rt/io/extensions.rs b/src/libcore/rt/io/extensions.rs index 97841f0db46..addafcf1d99 100644 --- a/src/libcore/rt/io/extensions.rs +++ b/src/libcore/rt/io/extensions.rs @@ -14,7 +14,7 @@ // XXX: Iteration should probably be considered separately use vec; -use rt::io::Reader; +use rt::io::{Reader, read_error, standard_error, EndOfFile}; use option::{Option, Some, None}; use unstable::finally::Finally; use util; @@ -36,16 +36,19 @@ pub trait ReaderUtil { /// /// # Failure /// - /// Raises the same conditions as `read`. Returns `false` if - /// the condition is handled. - fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> bool; + /// Raises the same conditions as `read`. Additionally raises `read_error` + /// on EOF. If `read_error` is handled then `push_bytes` returns without + /// pushing any bytes onto `buf` - that is, `buf` has the same length + /// upon exit as it did on entry. + fn push_bytes(&mut self, buf: &mut ~[u8], len: uint); - /// Reads `len` bytes and gives you back a new vector + /// Reads `len` bytes and gives you back a new vector of length `len` /// /// # Failure /// - /// Raises the same conditions as the `read` method. May return - /// less than the requested number of bytes on error or EOF. + /// Raises the same conditions as `read`. Additionally raises `read_error` + /// on EOF. If `read_error` is handled then the returned vector has + /// length 0. fn read_bytes(&mut self, len: uint) -> ~[u8]; /// Reads all remaining bytes from the stream. @@ -71,11 +74,10 @@ impl<T: Reader> ReaderUtil for T { } } - fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> bool { + fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) { unsafe { let start_len = buf.len(); let mut total_read = 0; - let mut eof = false; vec::reserve_at_least(buf, start_len + len); vec::raw::set_len(buf, start_len + len); @@ -88,7 +90,9 @@ impl<T: Reader> ReaderUtil for T { total_read += nread; } None => { - eof = true; + read_error::cond.raise(standard_error(EndOfFile)); + // Reset the vector length as though we didn't read anything + total_read = 0; break; } } @@ -96,8 +100,6 @@ impl<T: Reader> ReaderUtil for T { }).finally { vec::raw::set_len(buf, start_len + total_read); } - - return !eof; } } @@ -408,10 +410,19 @@ mod test { } #[test] + fn read_bytes_eof() { + let mut reader = MemReader::new(~[10, 11]); + do read_error::cond.trap(|_| { + }).in { + assert!(reader.read_bytes(4) == ~[]); + } + } + + #[test] fn push_bytes() { let mut reader = MemReader::new(~[10, 11, 12, 13]); let mut buf = ~[8, 9]; - assert!(reader.push_bytes(&mut buf, 4)); + reader.push_bytes(&mut buf, 4); assert!(buf == ~[8, 9, 10, 11, 12, 13]); } @@ -434,7 +445,7 @@ mod test { } }; let mut buf = ~[8, 9]; - assert!(reader.push_bytes(&mut buf, 4)); + reader.push_bytes(&mut buf, 4); assert!(buf == ~[8, 9, 10, 11, 12, 13]); } @@ -442,8 +453,11 @@ mod test { fn push_bytes_eof() { let mut reader = MemReader::new(~[10, 11]); let mut buf = ~[8, 9]; - assert!(!reader.push_bytes(&mut buf, 4)); - assert!(buf == ~[8, 9, 10, 11]); + do read_error::cond.trap(|_| { + }).in { + reader.push_bytes(&mut buf, 4); + assert!(buf == ~[8, 9]); + } } #[test] @@ -464,9 +478,9 @@ mod test { }; let mut buf = ~[8, 9]; do read_error::cond.trap(|_| { } ).in { - assert!(!reader.push_bytes(&mut buf, 4)); + reader.push_bytes(&mut buf, 4); } - assert!(buf == ~[8, 9, 10]); + assert!(buf == ~[8, 9]); } #[test] diff --git a/src/libcore/rt/io/mod.rs b/src/libcore/rt/io/mod.rs index 4ec5e83c382..7e611a0b8bc 100644 --- a/src/libcore/rt/io/mod.rs +++ b/src/libcore/rt/io/mod.rs @@ -260,8 +260,11 @@ pub use self::net::tcp::TcpStream; pub use self::net::udp::UdpStream; // Some extension traits that all Readers and Writers get. +#[cfg(not(stage0))] // Requires condition! fixes pub use self::extensions::ReaderUtil; +#[cfg(not(stage0))] // Requires condition! fixes pub use self::extensions::ReaderByteConversions; +#[cfg(not(stage0))] // Requires condition! fixes pub use self::extensions::WriterByteConversions; /// Synchronous, non-blocking file I/O. @@ -295,6 +298,7 @@ pub mod flate; pub mod comm_adapters; /// Extension traits +#[cfg(not(stage0))] // Requires condition! fixes mod extensions; /// Non-I/O things needed by the I/O module @@ -373,7 +377,8 @@ pub trait Reader { /// /// * Should raise error on eof /// * If the condition is handled it should still return the bytes read, - /// in which case there's no need to return Option + /// in which case there's no need to return Option - but then you *have* + /// to install a handler to detect eof. /// /// This doesn't take a `len` argument like the old `read`. /// Will people often need to slice their vectors to call this @@ -482,6 +487,13 @@ pub fn standard_error(kind: IoErrorKind) -> IoError { detail: None } } + EndOfFile => { + IoError { + kind: EndOfFile, + desc: "End of file", + detail: None + } + } _ => fail!() } } |
