about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2012-07-20 21:49:20 -0700
committerGraydon Hoare <graydon@mozilla.com>2012-07-23 17:15:30 -0700
commit06ac0c2b1da2592c53462e1d3675bf1198175aed (patch)
treebbc762c42c7fa64c8dd4c413d6bae9bd7fd1727b /src/libstd
parent6d042c0f2d9fa56d7286a8f3d2fa2f5427128ea5 (diff)
Switch reader to work with preallocated vecs
This closes #2901.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/net_tcp.rs49
1 files changed, 28 insertions, 21 deletions
diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs
index c7dc2d0cdab..4826bc760c2 100644
--- a/src/libstd/net_tcp.rs
+++ b/src/libstd/net_tcp.rs
@@ -11,7 +11,7 @@ import future::extensions;
 import result::*;
 import libc::size_t;
 import str::extensions;
-import io::{reader, writer};
+import io::{reader, reader_util, writer};
 
 // tcp interfaces
 export tcp_socket;
@@ -766,34 +766,41 @@ impl tcp_socket for tcp_socket {
 
 /// Implementation of `io::reader` iface for a buffered `net::tcp::tcp_socket`
 impl tcp_socket_buf of io::reader for @tcp_socket_buf {
-    fn read_bytes(amt: uint) -> ~[u8] {
-        let has_amt_available =
-            vec::len((*(self.data)).buf) >= amt;
-        if has_amt_available {
-            // no arbitrary-length shift in vec::?
-            let mut ret_buf = ~[];
-            while vec::len(ret_buf) < amt {
-                ret_buf += ~[vec::shift((*(self.data)).buf)];
-            }
-            ret_buf
-        }
-        else {
-            let read_result = read((*(self.data)).sock, 0u);
+    fn read(buf: &[mut u8], len: uint) -> uint {
+        // Loop until our buffer has enough data in it for us to read from.
+        while self.data.buf.len() < len {
+            let read_result = read(self.data.sock, 0u);
             if read_result.is_err() {
                 let err_data = read_result.get_err();
-                log(debug, #fmt("ERROR sock_buf as io::reader.read err %? %?",
-                                 err_data.err_name, err_data.err_msg));
-                ~[]
+
+                if err_data.err_name == ~"EOF" {
+                    break;
+                } else {
+                    #debug("ERROR sock_buf as io::reader.read err %? %?",
+                           err_data.err_name, err_data.err_msg);
+
+                    ret 0;
+                }
             }
             else {
-                let new_chunk = result::unwrap(read_result);
-                (*(self.data)).buf += new_chunk;
-                self.read_bytes(amt)
+                vec::push_all(self.data.buf, result::unwrap(read_result));
             }
         }
+
+        let count = uint::min(len, self.data.buf.len());
+
+        let mut data = ~[];
+        self.data.buf <-> data;
+
+        vec::u8::memcpy(buf, vec::view(data, 0, data.len()), count);
+
+        vec::push_all(self.data.buf, vec::view(data, count, data.len()));
+
+        count
     }
     fn read_byte() -> int {
-        self.read_bytes(1u)[0] as int
+        let bytes = ~[0];
+        if self.read(bytes, 1u) == 0 { fail } else { bytes[0] as int }
     }
     fn unread_byte(amt: int) {
         vec::unshift((*(self.data)).buf, amt as u8);