@@ -544,6 +544,72 @@ pub trait Read {
544544 append_to_string ( buf, |b| read_to_end ( self , b) )
545545 }
546546
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+
547613 /// Creates a "by reference" adaptor for this instance of `Read`.
548614 ///
549615 /// The returned adaptor also implements `Read` and will simply borrow this
@@ -1818,6 +1884,47 @@ mod tests {
18181884 assert ! ( c. read_to_string( & mut v) . is_err( ) ) ;
18191885 }
18201886
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+
18211928 #[ test]
18221929 fn take_eof ( ) {
18231930 struct R ;
0 commit comments