提交 28a13ec8 编写于 作者: B Brian Anderson

core::rt: Make push_bytes raise read_error on EOF

上级 1c1f11e6
......@@ -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 @@ fn read_byte(&mut self) -> Option<u8> {
}
}
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 @@ fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> bool {
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 @@ fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> bool {
}).finally {
vec::raw::set_len(buf, start_len + total_read);
}
return !eof;
}
}
......@@ -407,11 +409,20 @@ fn read_bytes_partial() {
assert!(bytes == ~[10, 11, 12, 13]);
}
#[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 @@ fn push_bytes_partial() {
}
};
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 @@ fn push_bytes_partial() {
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 @@ fn push_bytes_error() {
};
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]
......
......@@ -260,8 +260,11 @@
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 net {
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!()
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册