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