Skip to content

Commit 28a13ec

Browse files
committed
core::rt: Make push_bytes raise read_error on EOF
1 parent 1c1f11e commit 28a13ec

File tree

2 files changed

+45
-19
lines changed

2 files changed

+45
-19
lines changed

src/libcore/rt/io/extensions.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// XXX: Iteration should probably be considered separately
1515

1616
use vec;
17-
use rt::io::Reader;
17+
use rt::io::{Reader, read_error, standard_error, EndOfFile};
1818
use option::{Option, Some, None};
1919
use unstable::finally::Finally;
2020
use util;
@@ -36,16 +36,19 @@ pub trait ReaderUtil {
3636
///
3737
/// # Failure
3838
///
39-
/// Raises the same conditions as `read`. Returns `false` if
40-
/// the condition is handled.
41-
fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> bool;
39+
/// Raises the same conditions as `read`. Additionally raises `read_error`
40+
/// on EOF. If `read_error` is handled then `push_bytes` returns without
41+
/// pushing any bytes onto `buf` - that is, `buf` has the same length
42+
/// upon exit as it did on entry.
43+
fn push_bytes(&mut self, buf: &mut ~[u8], len: uint);
4244

43-
/// Reads `len` bytes and gives you back a new vector
45+
/// Reads `len` bytes and gives you back a new vector of length `len`
4446
///
4547
/// # Failure
4648
///
47-
/// Raises the same conditions as the `read` method. May return
48-
/// less than the requested number of bytes on error or EOF.
49+
/// Raises the same conditions as `read`. Additionally raises `read_error`
50+
/// on EOF. If `read_error` is handled then the returned vector has
51+
/// length 0.
4952
fn read_bytes(&mut self, len: uint) -> ~[u8];
5053

5154
/// Reads all remaining bytes from the stream.
@@ -71,11 +74,10 @@ impl<T: Reader> ReaderUtil for T {
7174
}
7275
}
7376

74-
fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> bool {
77+
fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) {
7578
unsafe {
7679
let start_len = buf.len();
7780
let mut total_read = 0;
78-
let mut eof = false;
7981

8082
vec::reserve_at_least(buf, start_len + len);
8183
vec::raw::set_len(buf, start_len + len);
@@ -88,16 +90,16 @@ impl<T: Reader> ReaderUtil for T {
8890
total_read += nread;
8991
}
9092
None => {
91-
eof = true;
93+
read_error::cond.raise(standard_error(EndOfFile));
94+
// Reset the vector length as though we didn't read anything
95+
total_read = 0;
9296
break;
9397
}
9498
}
9599
}
96100
}).finally {
97101
vec::raw::set_len(buf, start_len + total_read);
98102
}
99-
100-
return !eof;
101103
}
102104
}
103105

@@ -407,11 +409,20 @@ mod test {
407409
assert!(bytes == ~[10, 11, 12, 13]);
408410
}
409411

412+
#[test]
413+
fn read_bytes_eof() {
414+
let mut reader = MemReader::new(~[10, 11]);
415+
do read_error::cond.trap(|_| {
416+
}).in {
417+
assert!(reader.read_bytes(4) == ~[]);
418+
}
419+
}
420+
410421
#[test]
411422
fn push_bytes() {
412423
let mut reader = MemReader::new(~[10, 11, 12, 13]);
413424
let mut buf = ~[8, 9];
414-
assert!(reader.push_bytes(&mut buf, 4));
425+
reader.push_bytes(&mut buf, 4);
415426
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
416427
}
417428

@@ -434,16 +445,19 @@ mod test {
434445
}
435446
};
436447
let mut buf = ~[8, 9];
437-
assert!(reader.push_bytes(&mut buf, 4));
448+
reader.push_bytes(&mut buf, 4);
438449
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
439450
}
440451

441452
#[test]
442453
fn push_bytes_eof() {
443454
let mut reader = MemReader::new(~[10, 11]);
444455
let mut buf = ~[8, 9];
445-
assert!(!reader.push_bytes(&mut buf, 4));
446-
assert!(buf == ~[8, 9, 10, 11]);
456+
do read_error::cond.trap(|_| {
457+
}).in {
458+
reader.push_bytes(&mut buf, 4);
459+
assert!(buf == ~[8, 9]);
460+
}
447461
}
448462

449463
#[test]
@@ -464,9 +478,9 @@ mod test {
464478
};
465479
let mut buf = ~[8, 9];
466480
do read_error::cond.trap(|_| { } ).in {
467-
assert!(!reader.push_bytes(&mut buf, 4));
481+
reader.push_bytes(&mut buf, 4);
468482
}
469-
assert!(buf == ~[8, 9, 10]);
483+
assert!(buf == ~[8, 9]);
470484
}
471485

472486
#[test]

src/libcore/rt/io/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,11 @@ pub use self::net::tcp::TcpStream;
260260
pub use self::net::udp::UdpStream;
261261

262262
// Some extension traits that all Readers and Writers get.
263+
#[cfg(not(stage0))] // Requires condition! fixes
263264
pub use self::extensions::ReaderUtil;
265+
#[cfg(not(stage0))] // Requires condition! fixes
264266
pub use self::extensions::ReaderByteConversions;
267+
#[cfg(not(stage0))] // Requires condition! fixes
265268
pub use self::extensions::WriterByteConversions;
266269

267270
/// Synchronous, non-blocking file I/O.
@@ -295,6 +298,7 @@ pub mod flate;
295298
pub mod comm_adapters;
296299

297300
/// Extension traits
301+
#[cfg(not(stage0))] // Requires condition! fixes
298302
mod extensions;
299303

300304
/// Non-I/O things needed by the I/O module
@@ -373,7 +377,8 @@ pub trait Reader {
373377
///
374378
/// * Should raise error on eof
375379
/// * If the condition is handled it should still return the bytes read,
376-
/// in which case there's no need to return Option
380+
/// in which case there's no need to return Option - but then you *have*
381+
/// to install a handler to detect eof.
377382
///
378383
/// This doesn't take a `len` argument like the old `read`.
379384
/// Will people often need to slice their vectors to call this
@@ -482,6 +487,13 @@ pub fn standard_error(kind: IoErrorKind) -> IoError {
482487
detail: None
483488
}
484489
}
490+
EndOfFile => {
491+
IoError {
492+
kind: EndOfFile,
493+
desc: "End of file",
494+
detail: None
495+
}
496+
}
485497
_ => fail!()
486498
}
487499
}

0 commit comments

Comments
 (0)