@@ -315,6 +315,72 @@ pub trait Read {
315
315
append_to_string ( buf, |b| read_to_end ( self , b) )
316
316
}
317
317
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
+
318
384
/// Creates a "by reference" adaptor for this instance of `Read`.
319
385
///
320
386
/// The returned adaptor also implements `Read` and will simply borrow this
@@ -1556,6 +1622,47 @@ mod tests {
1556
1622
assert ! ( c. read_to_string( & mut v) . is_err( ) ) ;
1557
1623
}
1558
1624
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
+
1559
1666
#[ test]
1560
1667
fn take_eof ( ) {
1561
1668
struct R ;
0 commit comments