@@ -416,6 +416,116 @@ 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. seek( SeekFrom :: Start ( 5 ) ) ?, 4 ) ;
442+
443+ assert_eq ! ( take. seek( SeekFrom :: End ( 1 ) ) ?, 4 ) ;
444+ assert_eq ! ( take. seek( SeekFrom :: End ( 0 ) ) ?, 4 ) ;
445+ assert_eq ! ( take. seek( SeekFrom :: End ( -1 ) ) ?, 3 ) ;
446+ take. read_exact ( & mut buf1) ?;
447+ assert_eq ! ( buf1, [ b'5' ] ) ;
448+ assert_eq ! ( take. seek( SeekFrom :: End ( -2 ) ) ?, 2 ) ;
449+ take. read_exact ( & mut buf2) ?;
450+ assert_eq ! ( buf2, [ b'4' , b'5' ] ) ;
451+ assert_eq ! ( take. seek( SeekFrom :: End ( -3 ) ) ?, 1 ) ;
452+ take. read_exact ( & mut buf2) ?;
453+ assert_eq ! ( buf2, [ b'3' , b'4' ] ) ;
454+ assert_eq ! ( take. seek( SeekFrom :: End ( -4 ) ) ?, 0 ) ;
455+ take. read_exact ( & mut buf2) ?;
456+ assert_eq ! ( buf2, [ b'2' , b'3' ] ) ;
457+
458+ assert_eq ! ( take. seek( SeekFrom :: Current ( 0 ) ) ?, 2 ) ;
459+ take. read_exact ( & mut buf2) ?;
460+ assert_eq ! ( buf2, [ b'4' , b'5' ] ) ;
461+
462+ assert_eq ! ( take. seek( SeekFrom :: Current ( -3 ) ) ?, 1 ) ;
463+ take. read_exact ( & mut buf2) ?;
464+ assert_eq ! ( buf2, [ b'3' , b'4' ] ) ;
465+
466+ assert_eq ! ( take. seek( SeekFrom :: Current ( -1 ) ) ?, 2 ) ;
467+ take. read_exact ( & mut buf2) ?;
468+ assert_eq ! ( buf2, [ b'4' , b'5' ] ) ;
469+
470+ assert_eq ! ( take. seek( SeekFrom :: Current ( -4 ) ) ?, 0 ) ;
471+ take. read_exact ( & mut buf2) ?;
472+ assert_eq ! ( buf2, [ b'2' , b'3' ] ) ;
473+
474+ assert_eq ! ( take. seek( SeekFrom :: Current ( 2 ) ) ?, 4 ) ;
475+ assert_eq ! ( take. seek( SeekFrom :: Current ( 10 ) ) ?, 4 ) ;
476+
477+ Ok ( ( ) )
478+ }
479+
480+ struct ExampleHugeRangeOfZeroes {
481+ position : u64 ,
482+ }
483+
484+ impl Read for ExampleHugeRangeOfZeroes {
485+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
486+ let max = buf. len ( ) . min ( usize:: MAX ) ;
487+ for i in 0 ..max {
488+ if self . position == u64:: MAX {
489+ return Ok ( i) ;
490+ }
491+ self . position += 1 ;
492+ buf[ i] = 0 ;
493+ }
494+ Ok ( max)
495+ }
496+ }
497+
498+ impl Seek for ExampleHugeRangeOfZeroes {
499+ fn seek ( & mut self , pos : io:: SeekFrom ) -> io:: Result < u64 > {
500+ match pos {
501+ io:: SeekFrom :: Start ( i) => self . position = i,
502+ io:: SeekFrom :: End ( i) if i >= 0 => self . position = u64:: MAX ,
503+ io:: SeekFrom :: End ( i) => self . position = self . position - i. unsigned_abs ( ) ,
504+ io:: SeekFrom :: Current ( i) => {
505+ self . position = if i >= 0 {
506+ self . position . saturating_add ( i. unsigned_abs ( ) )
507+ } else {
508+ self . position . saturating_sub ( i. unsigned_abs ( ) )
509+ } ;
510+ }
511+ }
512+ Ok ( self . position )
513+ }
514+ }
515+
516+ #[ test]
517+ fn take_seek_big_offsets ( ) -> io:: Result < ( ) > {
518+ let inner = ExampleHugeRangeOfZeroes { position : 1 } ;
519+ let mut take = inner. take ( u64:: MAX - 2 ) ;
520+ assert_eq ! ( take. seek( io:: SeekFrom :: Start ( u64 :: MAX ) ) ?, u64 :: MAX - 2 ) ;
521+ assert_eq ! ( take. inner. position, u64 :: MAX - 1 ) ;
522+ assert_eq ! ( take. seek( io:: SeekFrom :: Start ( 0 ) ) ?, 0 ) ;
523+ assert_eq ! ( take. inner. position, 1 ) ;
524+ assert_eq ! ( take. seek( io:: SeekFrom :: End ( -1 ) ) ?, u64 :: MAX - 3 ) ;
525+ assert_eq ! ( take. inner. position, u64 :: MAX - 2 ) ;
526+ Ok ( ( ) )
527+ }
528+
419529// A simple example reader which uses the default implementation of
420530// read_to_end.
421531struct ExampleSliceReader < ' a > {
0 commit comments