@@ -490,6 +490,85 @@ fn file_test_io_read_write_at() {
490490 check ! ( fs:: remove_file( & filename) ) ;
491491}
492492
493+ #[ test]
494+ #[ cfg( unix) ]
495+ fn test_read_buf_at ( ) {
496+ use crate :: os:: unix:: fs:: FileExt ;
497+
498+ let tmpdir = tmpdir ( ) ;
499+ let filename = tmpdir. join ( "file_rt_io_file_test_read_buf_at.txt" ) ;
500+ {
501+ let oo = OpenOptions :: new ( ) . create_new ( true ) . write ( true ) . read ( true ) . clone ( ) ;
502+ let mut file = check ! ( oo. open( & filename) ) ;
503+ check ! ( file. write_all( b"0123456789" ) ) ;
504+ }
505+ {
506+ let mut file = check ! ( File :: open( & filename) ) ;
507+ let mut buf: [ MaybeUninit < u8 > ; 5 ] = [ MaybeUninit :: uninit ( ) ; 5 ] ;
508+ let mut buf = BorrowedBuf :: from ( buf. as_mut_slice ( ) ) ;
509+
510+ // Fill entire buffer with potentially short reads
511+ while buf. unfilled ( ) . capacity ( ) > 0 {
512+ let len = buf. len ( ) ;
513+ check ! ( file. read_buf_at( buf. unfilled( ) , 2 + len as u64 ) ) ;
514+ assert ! ( !buf. filled( ) . is_empty( ) ) ;
515+ assert ! ( b"23456" . starts_with( buf. filled( ) ) ) ;
516+ assert_eq ! ( check!( file. stream_position( ) ) , 0 ) ;
517+ }
518+ assert_eq ! ( buf. filled( ) , b"23456" ) ;
519+
520+ // Already full
521+ check ! ( file. read_buf_at( buf. unfilled( ) , 3 ) ) ;
522+ check ! ( file. read_buf_at( buf. unfilled( ) , 10 ) ) ;
523+ assert_eq ! ( buf. filled( ) , b"23456" ) ;
524+ assert_eq ! ( check!( file. stream_position( ) ) , 0 ) ;
525+
526+ // Read past eof is noop
527+ check ! ( file. read_buf_at( buf. clear( ) . unfilled( ) , 10 ) ) ;
528+ assert_eq ! ( buf. filled( ) , b"" ) ;
529+ check ! ( file. read_buf_at( buf. clear( ) . unfilled( ) , 11 ) ) ;
530+ assert_eq ! ( buf. filled( ) , b"" ) ;
531+ assert_eq ! ( check!( file. stream_position( ) ) , 0 ) ;
532+ }
533+ check ! ( fs:: remove_file( & filename) ) ;
534+ }
535+
536+ #[ test]
537+ #[ cfg( unix) ]
538+ fn test_read_buf_exact_at ( ) {
539+ use crate :: os:: unix:: fs:: FileExt ;
540+
541+ let tmpdir = tmpdir ( ) ;
542+ let filename = tmpdir. join ( "file_rt_io_file_test_read_buf_exact_at.txt" ) ;
543+ {
544+ let oo = OpenOptions :: new ( ) . create_new ( true ) . write ( true ) . read ( true ) . clone ( ) ;
545+ let mut file = check ! ( oo. open( & filename) ) ;
546+ check ! ( file. write_all( b"0123456789" ) ) ;
547+ }
548+ {
549+ let mut file = check ! ( File :: open( & filename) ) ;
550+ let mut buf: [ MaybeUninit < u8 > ; 5 ] = [ MaybeUninit :: uninit ( ) ; 5 ] ;
551+ let mut buf = BorrowedBuf :: from ( buf. as_mut_slice ( ) ) ;
552+
553+ // Exact read
554+ check ! ( file. read_buf_exact_at( buf. unfilled( ) , 2 ) ) ;
555+ assert_eq ! ( buf. filled( ) , b"23456" ) ;
556+ assert_eq ! ( check!( file. stream_position( ) ) , 0 ) ;
557+
558+ // Already full
559+ check ! ( file. read_buf_exact_at( buf. unfilled( ) , 3 ) ) ;
560+ check ! ( file. read_buf_exact_at( buf. unfilled( ) , 10 ) ) ;
561+ assert_eq ! ( buf. filled( ) , b"23456" ) ;
562+ assert_eq ! ( check!( file. stream_position( ) ) , 0 ) ;
563+
564+ // Non-empty exact read past eof fails
565+ let err = file. read_buf_exact_at ( buf. clear ( ) . unfilled ( ) , 6 ) . unwrap_err ( ) ;
566+ assert_eq ! ( err. kind( ) , ErrorKind :: UnexpectedEof ) ;
567+ assert_eq ! ( check!( file. stream_position( ) ) , 0 ) ;
568+ }
569+ check ! ( fs:: remove_file( & filename) ) ;
570+ }
571+
493572#[ test]
494573#[ cfg( unix) ]
495574fn set_get_unix_permissions ( ) {
@@ -566,6 +645,39 @@ fn file_test_io_seek_read_write() {
566645 check ! ( fs:: remove_file( & filename) ) ;
567646}
568647
648+ #[ test]
649+ #[ cfg( windows) ]
650+ fn test_seek_read_buf ( ) {
651+ use crate :: os:: windows:: fs:: FileExt ;
652+
653+ let tmpdir = tmpdir ( ) ;
654+ let filename = tmpdir. join ( "file_rt_io_file_test_seek_read_buf.txt" ) ;
655+ {
656+ let oo = OpenOptions :: new ( ) . create_new ( true ) . write ( true ) . read ( true ) . clone ( ) ;
657+ let mut file = check ! ( oo. open( & filename) ) ;
658+ check ! ( file. write_all( b"0123456789" ) ) ;
659+ }
660+ {
661+ let mut file = check ! ( File :: open( & filename) ) ;
662+ let mut buf: [ MaybeUninit < u8 > ; 1 ] = [ MaybeUninit :: uninit ( ) ] ;
663+ let mut buf = BorrowedBuf :: from ( buf. as_mut_slice ( ) ) ;
664+
665+ // Seek read
666+ check ! ( file. seek_read_buf( buf. unfilled( ) , 8 ) ) ;
667+ assert_eq ! ( buf. filled( ) , b"8" ) ;
668+ assert_eq ! ( check!( file. stream_position( ) ) , 9 ) ;
669+
670+ // Empty seek read
671+ check ! ( file. seek_read_buf( buf. unfilled( ) , 0 ) ) ;
672+ assert_eq ! ( buf. filled( ) , b"8" ) ;
673+
674+ // Seek read past eof
675+ check ! ( file. seek_read_buf( buf. clear( ) . unfilled( ) , 10 ) ) ;
676+ assert_eq ! ( buf. filled( ) , b"" ) ;
677+ }
678+ check ! ( fs:: remove_file( & filename) ) ;
679+ }
680+
569681#[ test]
570682fn file_test_read_buf ( ) {
571683 let tmpdir = tmpdir ( ) ;
0 commit comments