about summary refs log tree commit diff
path: root/src/libstd/io/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/io/mod.rs')
-rw-r--r--src/libstd/io/mod.rs42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 1c1df691a52..54c0d98c798 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -277,7 +277,7 @@ use str::{StrSlice, OwnedStr};
 use str;
 use to_str::ToStr;
 use uint;
-use unstable::finally::Finally;
+use unstable::finally::try_finally;
 use vec::{OwnedVector, MutableVector, ImmutableVector, OwnedCloneableVector};
 use vec;
 
@@ -473,25 +473,33 @@ pub trait Reader {
     /// pushed on to the vector, otherwise the amount `len` bytes couldn't be
     /// read (an error was encountered), and the error is returned.
     fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> IoResult<()> {
+        struct State<'a> {
+            buf: &'a mut ~[u8],
+            total_read: uint
+        }
+
         let start_len = buf.len();
-        let mut total_read = 0;
-
-        buf.reserve_additional(len);
-        unsafe { buf.set_len(start_len + len); }
-
-        (|| {
-            while total_read < len {
-                let len = buf.len();
-                let slice = buf.mut_slice(start_len + total_read, len);
-                match self.read(slice) {
-                    Ok(nread) => {
-                        total_read += nread;
+        let mut s = State { buf: buf, total_read: 0 };
+
+        s.buf.reserve_additional(len);
+        unsafe { s.buf.set_len(start_len + len); }
+
+        try_finally(
+            &mut s, (),
+            |s, _| {
+                while s.total_read < len {
+                    let len = s.buf.len();
+                    let slice = s.buf.mut_slice(start_len + s.total_read, len);
+                    match self.read(slice) {
+                        Ok(nread) => {
+                            s.total_read += nread;
+                        }
+                        Err(e) => return Err(e)
                     }
-                    Err(e) => return Err(e)
                 }
-            }
-            Ok(())
-        }).finally(|| unsafe { buf.set_len(start_len + total_read) })
+                Ok(())
+            },
+            |s| unsafe { s.buf.set_len(start_len + s.total_read) })
     }
 
     /// Reads `len` bytes and gives you back a new vector of length `len`