@@ -544,6 +544,72 @@ pub trait Read {
544
544
append_to_string ( buf, |b| read_to_end ( self , b) )
545
545
}
546
546
547
+ /// Read the exact number of bytes required to fill `buf`.
548
+ ///
549
+ /// This function reads as many bytes as necessary to completely fill the
550
+ /// specified buffer `buf`.
551
+ ///
552
+ /// No guarantees are provided about the contents of `buf` when this
553
+ /// function is called, implementations cannot rely on any property of the
554
+ /// contents of `buf` being true. It is recommended that implementations
555
+ /// only write data to `buf` instead of reading its contents.
556
+ ///
557
+ /// # Errors
558
+ ///
559
+ /// If this function encounters an error of the kind
560
+ /// `ErrorKind::Interrupted` then the error is ignored and the operation
561
+ /// will continue.
562
+ ///
563
+ /// If this function encounters an "end of file" before completely filling
564
+ /// the buffer, it returns an error of the kind `ErrorKind::UnexpectedEOF`.
565
+ /// The contents of `buf` are unspecified in this case.
566
+ ///
567
+ /// If any other read error is encountered then this function immediately
568
+ /// returns. The contents of `buf` are unspecified in this case.
569
+ ///
570
+ /// If this function returns an error, it is unspecified how many bytes it
571
+ /// has read, but it will never read more than would be necessary to
572
+ /// completely fill the buffer.
573
+ ///
574
+ /// # Examples
575
+ ///
576
+ /// [`File`][file]s implement `Read`:
577
+ ///
578
+ /// [file]: ../std/fs/struct.File.html
579
+ ///
580
+ /// ```
581
+ /// #![feature(read_exact)]
582
+ /// use std::io;
583
+ /// use std::io::prelude::*;
584
+ /// use std::fs::File;
585
+ ///
586
+ /// # fn foo() -> io::Result<()> {
587
+ /// let mut f = try!(File::open("foo.txt"));
588
+ /// let mut buffer = [0; 10];
589
+ ///
590
+ /// // read exactly 10 bytes
591
+ /// try!(f.read_exact(&mut buffer));
592
+ /// # Ok(())
593
+ /// # }
594
+ /// ```
595
+ #[ unstable( feature = "read_exact" , reason = "recently added" , issue = "27585" ) ]
596
+ fn read_exact ( & mut self , mut buf : & mut [ u8 ] ) -> Result < ( ) > {
597
+ while !buf. is_empty ( ) {
598
+ match self . read ( buf) {
599
+ Ok ( 0 ) => break ,
600
+ Ok ( n) => { let tmp = buf; buf = & mut tmp[ n..] ; }
601
+ Err ( ref e) if e. kind ( ) == ErrorKind :: Interrupted => { }
602
+ Err ( e) => return Err ( e) ,
603
+ }
604
+ }
605
+ if !buf. is_empty ( ) {
606
+ Err ( Error :: new ( ErrorKind :: UnexpectedEOF ,
607
+ "failed to fill whole buffer" ) )
608
+ } else {
609
+ Ok ( ( ) )
610
+ }
611
+ }
612
+
547
613
/// Creates a "by reference" adaptor for this instance of `Read`.
548
614
///
549
615
/// The returned adaptor also implements `Read` and will simply borrow this
@@ -1818,6 +1884,47 @@ mod tests {
1818
1884
assert ! ( c. read_to_string( & mut v) . is_err( ) ) ;
1819
1885
}
1820
1886
1887
+ #[ test]
1888
+ fn read_exact ( ) {
1889
+ let mut buf = [ 0 ; 4 ] ;
1890
+
1891
+ let mut c = Cursor :: new ( & b"" [ ..] ) ;
1892
+ assert_eq ! ( c. read_exact( & mut buf) . unwrap_err( ) . kind( ) ,
1893
+ io:: ErrorKind :: UnexpectedEOF ) ;
1894
+
1895
+ let mut c = Cursor :: new ( & b"123" [ ..] ) . chain ( Cursor :: new ( & b"456789" [ ..] ) ) ;
1896
+ c. read_exact ( & mut buf) . unwrap ( ) ;
1897
+ assert_eq ! ( & buf, b"1234" ) ;
1898
+ c. read_exact ( & mut buf) . unwrap ( ) ;
1899
+ assert_eq ! ( & buf, b"5678" ) ;
1900
+ assert_eq ! ( c. read_exact( & mut buf) . unwrap_err( ) . kind( ) ,
1901
+ io:: ErrorKind :: UnexpectedEOF ) ;
1902
+ }
1903
+
1904
+ #[ test]
1905
+ fn read_exact_slice ( ) {
1906
+ let mut buf = [ 0 ; 4 ] ;
1907
+
1908
+ let mut c = & b"" [ ..] ;
1909
+ assert_eq ! ( c. read_exact( & mut buf) . unwrap_err( ) . kind( ) ,
1910
+ io:: ErrorKind :: UnexpectedEOF ) ;
1911
+
1912
+ let mut c = & b"123" [ ..] ;
1913
+ assert_eq ! ( c. read_exact( & mut buf) . unwrap_err( ) . kind( ) ,
1914
+ io:: ErrorKind :: UnexpectedEOF ) ;
1915
+ // make sure the optimized (early returning) method is being used
1916
+ assert_eq ! ( & buf, & [ 0 ; 4 ] ) ;
1917
+
1918
+ let mut c = & b"1234" [ ..] ;
1919
+ c. read_exact ( & mut buf) . unwrap ( ) ;
1920
+ assert_eq ! ( & buf, b"1234" ) ;
1921
+
1922
+ let mut c = & b"56789" [ ..] ;
1923
+ c. read_exact ( & mut buf) . unwrap ( ) ;
1924
+ assert_eq ! ( & buf, b"5678" ) ;
1925
+ assert_eq ! ( c, b"9" ) ;
1926
+ }
1927
+
1821
1928
#[ test]
1822
1929
fn take_eof ( ) {
1823
1930
struct R ;
0 commit comments