@@ -315,6 +315,72 @@ pub trait Read {
315315 append_to_string ( buf, |b| read_to_end ( self , b) )
316316 }
317317
318+ /// Read the exact number of bytes required to fill `buf`.
319+ ///
320+ /// This function reads as many bytes as necessary to completely fill the
321+ /// specified buffer `buf`.
322+ ///
323+ /// No guarantees are provided about the contents of `buf` when this
324+ /// function is called, implementations cannot rely on any property of the
325+ /// contents of `buf` being true. It is recommended that implementations
326+ /// only write data to `buf` instead of reading its contents.
327+ ///
328+ /// # Errors
329+ ///
330+ /// If this function encounters an error of the kind
331+ /// `ErrorKind::Interrupted` then the error is ignored and the operation
332+ /// will continue.
333+ ///
334+ /// If this function encounters an "end of file" before completely filling
335+ /// the buffer, it returns an error of the kind `ErrorKind::UnexpectedEOF`.
336+ /// The contents of `buf` are unspecified in this case.
337+ ///
338+ /// If any other read error is encountered then this function immediately
339+ /// returns. The contents of `buf` are unspecified in this case.
340+ ///
341+ /// If this function returns an error, it is unspecified how many bytes it
342+ /// has read, but it will never read more than would be necessary to
343+ /// completely fill the buffer.
344+ ///
345+ /// # Examples
346+ ///
347+ /// [`File`][file]s implement `Read`:
348+ ///
349+ /// [file]: ../std/fs/struct.File.html
350+ ///
351+ /// ```
352+ /// #![feature(read_exact)]
353+ /// use std::io;
354+ /// use std::io::prelude::*;
355+ /// use std::fs::File;
356+ ///
357+ /// # fn foo() -> io::Result<()> {
358+ /// let mut f = try!(File::open("foo.txt"));
359+ /// let mut buffer = [0; 10];
360+ ///
361+ /// // read exactly 10 bytes
362+ /// try!(f.read_exact(&mut buffer));
363+ /// # Ok(())
364+ /// # }
365+ /// ```
366+ #[ unstable( feature = "read_exact" , reason = "recently added" ) ]
367+ fn read_exact ( & mut self , mut buf : & mut [ u8 ] ) -> Result < ( ) > {
368+ while !buf. is_empty ( ) {
369+ match self . read ( buf) {
370+ Ok ( 0 ) => break ,
371+ Ok ( n) => { let tmp = buf; buf = & mut tmp[ n..] ; }
372+ Err ( ref e) if e. kind ( ) == ErrorKind :: Interrupted => { }
373+ Err ( e) => return Err ( e) ,
374+ }
375+ }
376+ if !buf. is_empty ( ) {
377+ Err ( Error :: new ( ErrorKind :: UnexpectedEOF ,
378+ "failed to fill whole buffer" ) )
379+ } else {
380+ Ok ( ( ) )
381+ }
382+ }
383+
318384 /// Creates a "by reference" adaptor for this instance of `Read`.
319385 ///
320386 /// The returned adaptor also implements `Read` and will simply borrow this
@@ -1556,6 +1622,47 @@ mod tests {
15561622 assert ! ( c. read_to_string( & mut v) . is_err( ) ) ;
15571623 }
15581624
1625+ #[ test]
1626+ fn read_exact ( ) {
1627+ let mut buf = [ 0 ; 4 ] ;
1628+
1629+ let mut c = Cursor :: new ( & b"" [ ..] ) ;
1630+ assert_eq ! ( c. read_exact( & mut buf) . unwrap_err( ) . kind( ) ,
1631+ io:: ErrorKind :: UnexpectedEOF ) ;
1632+
1633+ let mut c = Cursor :: new ( & b"123" [ ..] ) . chain ( Cursor :: new ( & b"456789" [ ..] ) ) ;
1634+ c. read_exact ( & mut buf) . unwrap ( ) ;
1635+ assert_eq ! ( & buf, b"1234" ) ;
1636+ c. read_exact ( & mut buf) . unwrap ( ) ;
1637+ assert_eq ! ( & buf, b"5678" ) ;
1638+ assert_eq ! ( c. read_exact( & mut buf) . unwrap_err( ) . kind( ) ,
1639+ io:: ErrorKind :: UnexpectedEOF ) ;
1640+ }
1641+
1642+ #[ test]
1643+ fn read_exact_slice ( ) {
1644+ let mut buf = [ 0 ; 4 ] ;
1645+
1646+ let mut c = & b"" [ ..] ;
1647+ assert_eq ! ( c. read_exact( & mut buf) . unwrap_err( ) . kind( ) ,
1648+ io:: ErrorKind :: UnexpectedEOF ) ;
1649+
1650+ let mut c = & b"123" [ ..] ;
1651+ assert_eq ! ( c. read_exact( & mut buf) . unwrap_err( ) . kind( ) ,
1652+ io:: ErrorKind :: UnexpectedEOF ) ;
1653+ // make sure the optimized (early returning) method is being used
1654+ assert_eq ! ( & buf, & [ 0 ; 4 ] ) ;
1655+
1656+ let mut c = & b"1234" [ ..] ;
1657+ c. read_exact ( & mut buf) . unwrap ( ) ;
1658+ assert_eq ! ( & buf, b"1234" ) ;
1659+
1660+ let mut c = & b"56789" [ ..] ;
1661+ c. read_exact ( & mut buf) . unwrap ( ) ;
1662+ assert_eq ! ( & buf, b"5678" ) ;
1663+ assert_eq ! ( c, b"9" ) ;
1664+ }
1665+
15591666 #[ test]
15601667 fn take_eof ( ) {
15611668 struct R ;
0 commit comments