about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorStepan Koltsov <stepan.koltsov@gmail.com>2013-07-28 16:53:00 +0400
committerUser <stepancheg@yandex-team.ru>2013-07-28 16:53:00 +0400
commitb92d1ea723034c3f9adc10a6da11b124a20c57b1 (patch)
treec5a135627c5f691280a1e67987b838a31761c93c /src/libstd
parent5842ab36b81f0a3e8d6dd48a200bc405ad19ca96 (diff)
downloadrust-b92d1ea723034c3f9adc10a6da11b124a20c57b1.tar.gz
rust-b92d1ea723034c3f9adc10a6da11b124a20c57b1.zip
ReaderUtil::each_byte shouldn't include EOF byte -- Issue #5056
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io.rs42
1 files changed, 38 insertions, 4 deletions
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 761d07da805..1865dc5dece 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -148,6 +148,9 @@ pub trait Reader {
     /**
     * Returns a boolean value: are we currently at EOF?
     *
+    * Note that stream position may be already at the end-of-file point,
+    * but `eof` returns false until an attempt to read at that position.
+    *
     * `eof` is conceptually similar to C's `feof` function.
     *
     * # Examples
@@ -724,15 +727,21 @@ impl<T:Reader> ReaderUtil for T {
     }
 
     fn each_byte(&self, it: &fn(int) -> bool) -> bool {
-        while !self.eof() {
-            if !it(self.read_byte()) { return false; }
+        loop {
+            match self.read_byte() {
+                -1 => break,
+                ch => if !it(ch) { return false; }
+            }
         }
         return true;
     }
 
     fn each_char(&self, it: &fn(char) -> bool) -> bool {
-        while !self.eof() {
-            if !it(self.read_char()) { return false; }
+        loop {
+            match self.read_char() {
+                eof if eof == (-1 as char) => break,
+                ch => if !it(ch) { return false; }
+            }
         }
         return true;
     }
@@ -1859,6 +1868,31 @@ mod tests {
     }
 
     #[test]
+    fn test_each_byte_each_char_file() {
+        // Issue #5056 -- shouldn't include trailing EOF.
+        let path = Path("tmp/lib-io-test-each-byte-each-char-file.tmp");
+
+        {
+            // create empty, enough to reproduce a problem
+            io::file_writer(&path, [io::Create]).unwrap();
+        }
+
+        {
+            let file = io::file_reader(&path).unwrap();
+            for file.each_byte() |_| {
+                fail!("must be empty");
+            }
+        }
+
+        {
+            let file = io::file_reader(&path).unwrap();
+            for file.each_char() |_| {
+                fail!("must be empty");
+            }
+        }
+    }
+
+    #[test]
     fn test_readchars_empty() {
         do io::with_str_reader("") |inp| {
             let res : ~[char] = inp.read_chars(128);