@@ -416,6 +416,126 @@ fn seek_position() -> io::Result<()> {
416416 Ok ( ( ) )
417417}
418418
419+ #[ test]
420+ fn take_seek ( ) -> io:: Result < ( ) > {
421+ let mut buf = Cursor :: new ( b"0123456789" ) ;
422+ buf. set_position ( 2 ) ;
423+ let mut take = buf. by_ref ( ) . take ( 4 ) ;
424+ let mut buf1 = [ 0u8 ; 1 ] ;
425+ let mut buf2 = [ 0u8 ; 2 ] ;
426+ assert_eq ! ( take. position( ) , 0 ) ;
427+
428+ assert_eq ! ( take. seek( SeekFrom :: Start ( 0 ) ) ?, 0 ) ;
429+ take. read_exact ( & mut buf2) ?;
430+ assert_eq ! ( buf2, [ b'2' , b'3' ] ) ;
431+ assert_eq ! ( take. seek( SeekFrom :: Start ( 1 ) ) ?, 1 ) ;
432+ take. read_exact ( & mut buf2) ?;
433+ assert_eq ! ( buf2, [ b'3' , b'4' ] ) ;
434+ assert_eq ! ( take. seek( SeekFrom :: Start ( 2 ) ) ?, 2 ) ;
435+ take. read_exact ( & mut buf2) ?;
436+ assert_eq ! ( buf2, [ b'4' , b'5' ] ) ;
437+ assert_eq ! ( take. seek( SeekFrom :: Start ( 3 ) ) ?, 3 ) ;
438+ take. read_exact ( & mut buf1) ?;
439+ assert_eq ! ( buf1, [ b'5' ] ) ;
440+ assert_eq ! ( take. seek( SeekFrom :: Start ( 4 ) ) ?, 4 ) ;
441+ assert_eq ! ( take. read( & mut buf1) ?, 0 ) ;
442+
443+ assert_eq ! ( take. seek( SeekFrom :: End ( 0 ) ) ?, 4 ) ;
444+ assert_eq ! ( take. seek( SeekFrom :: End ( -1 ) ) ?, 3 ) ;
445+ take. read_exact ( & mut buf1) ?;
446+ assert_eq ! ( buf1, [ b'5' ] ) ;
447+ assert_eq ! ( take. seek( SeekFrom :: End ( -2 ) ) ?, 2 ) ;
448+ take. read_exact ( & mut buf2) ?;
449+ assert_eq ! ( buf2, [ b'4' , b'5' ] ) ;
450+ assert_eq ! ( take. seek( SeekFrom :: End ( -3 ) ) ?, 1 ) ;
451+ take. read_exact ( & mut buf2) ?;
452+ assert_eq ! ( buf2, [ b'3' , b'4' ] ) ;
453+ assert_eq ! ( take. seek( SeekFrom :: End ( -4 ) ) ?, 0 ) ;
454+ take. read_exact ( & mut buf2) ?;
455+ assert_eq ! ( buf2, [ b'2' , b'3' ] ) ;
456+
457+ assert_eq ! ( take. seek( SeekFrom :: Current ( 0 ) ) ?, 2 ) ;
458+ take. read_exact ( & mut buf2) ?;
459+ assert_eq ! ( buf2, [ b'4' , b'5' ] ) ;
460+
461+ assert_eq ! ( take. seek( SeekFrom :: Current ( -3 ) ) ?, 1 ) ;
462+ take. read_exact ( & mut buf2) ?;
463+ assert_eq ! ( buf2, [ b'3' , b'4' ] ) ;
464+
465+ assert_eq ! ( take. seek( SeekFrom :: Current ( -1 ) ) ?, 2 ) ;
466+ take. read_exact ( & mut buf2) ?;
467+ assert_eq ! ( buf2, [ b'4' , b'5' ] ) ;
468+
469+ assert_eq ! ( take. seek( SeekFrom :: Current ( -4 ) ) ?, 0 ) ;
470+ take. read_exact ( & mut buf2) ?;
471+ assert_eq ! ( buf2, [ b'2' , b'3' ] ) ;
472+
473+ assert_eq ! ( take. seek( SeekFrom :: Current ( 2 ) ) ?, 4 ) ;
474+ assert_eq ! ( take. read( & mut buf1) ?, 0 ) ;
475+
476+ Ok ( ( ) )
477+ }
478+
479+ #[ test]
480+ fn take_seek_error ( ) {
481+ let buf = Cursor :: new ( b"0123456789" ) ;
482+ let mut take = buf. take ( 2 ) ;
483+ assert ! ( take. seek( SeekFrom :: Start ( 3 ) ) . is_err( ) ) ;
484+ assert ! ( take. seek( SeekFrom :: End ( 1 ) ) . is_err( ) ) ;
485+ assert ! ( take. seek( SeekFrom :: End ( -3 ) ) . is_err( ) ) ;
486+ assert ! ( take. seek( SeekFrom :: Current ( -1 ) ) . is_err( ) ) ;
487+ assert ! ( take. seek( SeekFrom :: Current ( 3 ) ) . is_err( ) ) ;
488+ }
489+
490+ struct ExampleHugeRangeOfZeroes {
491+ position : u64 ,
492+ }
493+
494+ impl Read for ExampleHugeRangeOfZeroes {
495+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
496+ let max = buf. len ( ) . min ( usize:: MAX ) ;
497+ for i in 0 ..max {
498+ if self . position == u64:: MAX {
499+ return Ok ( i) ;
500+ }
501+ self . position += 1 ;
502+ buf[ i] = 0 ;
503+ }
504+ Ok ( max)
505+ }
506+ }
507+
508+ impl Seek for ExampleHugeRangeOfZeroes {
509+ fn seek ( & mut self , pos : io:: SeekFrom ) -> io:: Result < u64 > {
510+ match pos {
511+ io:: SeekFrom :: Start ( i) => self . position = i,
512+ io:: SeekFrom :: End ( i) if i >= 0 => self . position = u64:: MAX ,
513+ io:: SeekFrom :: End ( i) => self . position = self . position - i. unsigned_abs ( ) ,
514+ io:: SeekFrom :: Current ( i) => {
515+ self . position = if i >= 0 {
516+ self . position . saturating_add ( i. unsigned_abs ( ) )
517+ } else {
518+ self . position . saturating_sub ( i. unsigned_abs ( ) )
519+ } ;
520+ }
521+ }
522+ Ok ( self . position )
523+ }
524+ }
525+
526+ #[ test]
527+ fn take_seek_big_offsets ( ) -> io:: Result < ( ) > {
528+ let inner = ExampleHugeRangeOfZeroes { position : 1 } ;
529+ let mut take = inner. take ( u64:: MAX - 2 ) ;
530+ assert_eq ! ( take. seek( io:: SeekFrom :: Start ( u64 :: MAX - 2 ) ) ?, u64 :: MAX - 2 ) ;
531+ assert_eq ! ( take. inner. position, u64 :: MAX - 1 ) ;
532+ assert_eq ! ( take. seek( io:: SeekFrom :: Start ( 0 ) ) ?, 0 ) ;
533+ assert_eq ! ( take. inner. position, 1 ) ;
534+ assert_eq ! ( take. seek( io:: SeekFrom :: End ( -1 ) ) ?, u64 :: MAX - 3 ) ;
535+ assert_eq ! ( take. inner. position, u64 :: MAX - 2 ) ;
536+ Ok ( ( ) )
537+ }
538+
419539// A simple example reader which uses the default implementation of
420540// read_to_end.
421541struct ExampleSliceReader < ' a > {
0 commit comments