@@ -72,7 +72,7 @@ pub fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket {
72
72
*/
73
73
pub struct TcpSocketBuf {
74
74
data : @TcpBufferedSocketData ,
75
- mut end_of_stream : bool ,
75
+ mut end_of_stream : bool
76
76
}
77
77
78
78
pub fn TcpSocketBuf ( data : @TcpBufferedSocketData ) -> TcpSocketBuf {
@@ -809,7 +809,7 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint,
809
809
* A buffered wrapper that you can cast as an `io::reader` or `io::writer`
810
810
*/
811
811
pub fn socket_buf ( sock : TcpSocket ) -> TcpSocketBuf {
812
- TcpSocketBuf ( @TcpBufferedSocketData { sock : sock, buf : ~[ ] } )
812
+ TcpSocketBuf ( @TcpBufferedSocketData { sock : move sock, mut buf : ~[ ] , buf_off : 0 } )
813
813
}
814
814
815
815
/// Convenience methods extending `net::tcp::tcp_socket`
@@ -859,48 +859,89 @@ impl TcpSocket {
859
859
/// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket`
860
860
impl TcpSocketBuf : io:: Reader {
861
861
fn read ( & self , buf : & [ mut u8] , len : uint ) -> uint {
862
- // Loop until our buffer has enough data in it for us to read from.
863
- while self . data . buf . len ( ) < len {
864
- let read_result = read ( & self . data . sock , 0 u) ;
865
- if read_result. is_err ( ) {
866
- let err_data = read_result. get_err ( ) ;
862
+ if len == 0 { return 0 }
863
+ let mut count: uint = 0 ;
867
864
868
- if err_data. err_name == ~"EOF " {
869
- self . end_of_stream = true ;
870
- break ;
871
- } else {
872
- debug ! ( "ERROR sock_buf as io::reader.read err %? %?" ,
873
- err_data. err_name, err_data. err_msg) ;
865
+ loop {
866
+ assert count < len;
874
867
875
- return 0 ;
868
+ // If possible, copy up to `len` bytes from the internal
869
+ // `data.buf` into `buf`
870
+ let nbuffered = self . data . buf . len ( ) - self . data . buf_off ;
871
+ let needed = len - count;
872
+ if nbuffered > 0 {
873
+ unsafe {
874
+ let ncopy = uint:: min ( nbuffered, needed) ;
875
+ let dst = ptr:: mut_offset (
876
+ vec:: raw:: to_mut_ptr ( buf) , count) ;
877
+ let src = ptr:: const_offset (
878
+ vec:: raw:: to_const_ptr ( self . data . buf ) ,
879
+ self . data . buf_off ) ;
880
+ ptr:: copy_memory ( dst, src, ncopy) ;
881
+ self . data . buf_off += ncopy;
882
+ count += ncopy;
876
883
}
877
- }
878
- else {
879
- self . data . buf . push_all ( result:: unwrap ( read_result) ) ;
880
- }
881
- }
882
-
883
- let count = uint:: min ( len, self . data . buf . len ( ) ) ;
884
-
885
- let mut data = ~[ ] ;
886
- self . data . buf <-> data;
884
+ }
887
885
888
- vec:: bytes:: copy_memory ( buf, vec:: view ( data, 0 , data. len ( ) ) , count) ;
886
+ assert count <= len;
887
+ if count == len {
888
+ break ;
889
+ }
889
890
890
- self . data . buf . push_all ( vec:: view ( data, count, data. len ( ) ) ) ;
891
+ // We copied all the bytes we had in the internal buffer into
892
+ // the result buffer, but the caller wants more bytes, so we
893
+ // need to read in data from the socket. Note that the internal
894
+ // buffer is of no use anymore as we read all bytes from it,
895
+ // so we can throw it away.
896
+ let read_result = read ( & self . data . sock , 0 u) ;
897
+ if read_result. is_err ( ) {
898
+ let err_data = read_result. get_err ( ) ;
899
+
900
+ if err_data. err_name == ~"EOF " {
901
+ self . end_of_stream = true ;
902
+ break ;
903
+ } else {
904
+ debug ! ( "ERROR sock_buf as io::reader.read err %? %?" ,
905
+ err_data. err_name, err_data. err_msg) ;
906
+ // As we have already copied data into result buffer,
907
+ // we cannot simply return 0 here. Instead the error
908
+ // should show up in a later call to read().
909
+ break ;
910
+ }
911
+ }
912
+ else {
913
+ self . data . buf = result:: unwrap ( read_result) ;
914
+ self . data . buf_off = 0 ;
915
+ }
916
+ }
891
917
892
918
count
893
919
}
894
920
fn read_byte ( & self ) -> int {
895
- let mut bytes = ~[ 0 ] ;
896
- if self . read ( bytes, 1 u) == 0 {
897
- if self . end_of_stream {
898
- -1
899
- } else {
900
- fail
901
- }
902
- } else {
903
- bytes[ 0 ] as int
921
+ loop {
922
+ if self . data . buf . len ( ) > self . data . buf_off {
923
+ let c = self . data . buf [ self . data . buf_off ] ;
924
+ self . data . buf_off += 1 ;
925
+ return c as int
926
+ }
927
+
928
+ let read_result = read ( & self . data . sock , 0 u) ;
929
+ if read_result. is_err ( ) {
930
+ let err_data = read_result. get_err ( ) ;
931
+
932
+ if err_data. err_name == ~"EOF " {
933
+ self . end_of_stream = true ;
934
+ return -1
935
+ } else {
936
+ debug ! ( "ERROR sock_buf as io::reader.read err %? %?" ,
937
+ err_data. err_name, err_data. err_msg) ;
938
+ fail
939
+ }
940
+ }
941
+ else {
942
+ self . data . buf = result:: unwrap ( read_result) ;
943
+ self . data . buf_off = 0 ;
944
+ }
904
945
}
905
946
}
906
947
fn eof ( & self ) -> bool {
@@ -1375,6 +1416,7 @@ struct TcpSocketData {
1375
1416
struct TcpBufferedSocketData {
1376
1417
sock : TcpSocket ,
1377
1418
mut buf : ~[ u8 ] ,
1419
+ mut buf_off : uint
1378
1420
}
1379
1421
1380
1422
//#[cfg(test)]
0 commit comments