@@ -669,13 +669,33 @@ impl<T> Take<T> {
669
669
670
670
impl < T : Read > Read for Take < T > {
671
671
fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize > {
672
+ // Don't call into inner reader at all at EOF because it may still block
673
+ if self . limit == 0 {
674
+ return Ok ( 0 ) ;
675
+ }
676
+
672
677
let max = cmp:: min ( buf. len ( ) as u64 , self . limit ) as usize ;
673
678
let n = try!( self . inner . read ( & mut buf[ ..max] ) ) ;
674
679
self . limit -= n as u64 ;
675
680
Ok ( n)
676
681
}
677
682
}
678
683
684
+ impl < T : BufRead > BufRead for Take < T > {
685
+ fn fill_buf ( & mut self ) -> Result < & [ u8 ] > {
686
+ let buf = try!( self . inner . fill_buf ( ) ) ;
687
+ let cap = cmp:: min ( buf. len ( ) as u64 , self . limit ) as usize ;
688
+ Ok ( & buf[ ..cap] )
689
+ }
690
+
691
+ fn consume ( & mut self , amt : usize ) {
692
+ // Don't let callers reset the limit by passing an overlarge value
693
+ let amt = cmp:: min ( amt as u64 , self . limit ) as usize ;
694
+ self . limit -= amt as u64 ;
695
+ self . inner . consume ( amt) ;
696
+ }
697
+ }
698
+
679
699
/// An adaptor which will emit all read data to a specified writer as well.
680
700
///
681
701
/// For more information see `ReadExt::tee`
@@ -846,6 +866,7 @@ impl<B: BufRead> Iterator for Lines<B> {
846
866
mod tests {
847
867
use prelude:: v1:: * ;
848
868
use io:: prelude:: * ;
869
+ use io;
849
870
use super :: Cursor ;
850
871
851
872
#[ test]
@@ -943,4 +964,18 @@ mod tests {
943
964
let mut v = String :: new ( ) ;
944
965
assert ! ( c. read_to_string( & mut v) . is_err( ) ) ;
945
966
}
967
+
968
+ #[ test]
969
+ fn take_eof ( ) {
970
+ struct R ;
971
+
972
+ impl Read for R {
973
+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
974
+ Err ( io:: Error :: new ( io:: ErrorKind :: Other , "" , None ) )
975
+ }
976
+ }
977
+
978
+ let mut buf = [ 0 ; 1 ] ;
979
+ assert_eq ! ( Ok ( 0 ) , R . take( 0 ) . read( & mut buf) ) ;
980
+ }
946
981
}
0 commit comments