@@ -416,6 +416,152 @@ 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+ #[ should_panic]
478+ fn take_seek_out_of_bounds_start ( ) {
479+ let buf = Cursor :: new ( b"0123456789" ) ;
480+ let mut take = buf. take ( 2 ) ;
481+ take. seek ( SeekFrom :: Start ( 3 ) ) . unwrap ( ) ;
482+ }
483+
484+ #[ test]
485+ #[ should_panic]
486+ fn take_seek_out_of_bounds_end_forward ( ) {
487+ let buf = Cursor :: new ( b"0123456789" ) ;
488+ let mut take = buf. take ( 2 ) ;
489+ take. seek ( SeekFrom :: End ( 1 ) ) . unwrap ( ) ;
490+ }
491+
492+ #[ test]
493+ #[ should_panic]
494+ fn take_seek_out_of_bounds_end_before_start ( ) {
495+ let buf = Cursor :: new ( b"0123456789" ) ;
496+ let mut take = buf. take ( 2 ) ;
497+ take. seek ( SeekFrom :: End ( -3 ) ) . unwrap ( ) ;
498+ }
499+
500+ #[ test]
501+ #[ should_panic]
502+ fn take_seek_out_of_bounds_current_before_start ( ) {
503+ let buf = Cursor :: new ( b"0123456789" ) ;
504+ let mut take = buf. take ( 2 ) ;
505+ take. seek ( SeekFrom :: Current ( -1 ) ) . unwrap ( ) ;
506+ }
507+
508+ #[ test]
509+ #[ should_panic]
510+ fn take_seek_out_of_bounds_current_after_end ( ) {
511+ let buf = Cursor :: new ( b"0123456789" ) ;
512+ let mut take = buf. take ( 2 ) ;
513+ take. seek ( SeekFrom :: Current ( 3 ) ) . unwrap ( ) ;
514+ }
515+
516+ struct ExampleHugeRangeOfZeroes {
517+ position : u64 ,
518+ }
519+
520+ impl Read for ExampleHugeRangeOfZeroes {
521+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
522+ let max = buf. len ( ) . min ( usize:: MAX ) ;
523+ for i in 0 ..max {
524+ if self . position == u64:: MAX {
525+ return Ok ( i) ;
526+ }
527+ self . position += 1 ;
528+ buf[ i] = 0 ;
529+ }
530+ Ok ( max)
531+ }
532+ }
533+
534+ impl Seek for ExampleHugeRangeOfZeroes {
535+ fn seek ( & mut self , pos : io:: SeekFrom ) -> io:: Result < u64 > {
536+ match pos {
537+ io:: SeekFrom :: Start ( i) => self . position = i,
538+ io:: SeekFrom :: End ( i) if i >= 0 => self . position = u64:: MAX ,
539+ io:: SeekFrom :: End ( i) => self . position = self . position - i. unsigned_abs ( ) ,
540+ io:: SeekFrom :: Current ( i) => {
541+ self . position = if i >= 0 {
542+ self . position . saturating_add ( i. unsigned_abs ( ) )
543+ } else {
544+ self . position . saturating_sub ( i. unsigned_abs ( ) )
545+ } ;
546+ }
547+ }
548+ Ok ( self . position )
549+ }
550+ }
551+
552+ #[ test]
553+ fn take_seek_big_offsets ( ) -> io:: Result < ( ) > {
554+ let inner = ExampleHugeRangeOfZeroes { position : 1 } ;
555+ let mut take = inner. take ( u64:: MAX - 2 ) ;
556+ assert_eq ! ( take. seek( io:: SeekFrom :: Start ( u64 :: MAX - 2 ) ) ?, u64 :: MAX - 2 ) ;
557+ assert_eq ! ( take. inner. position, u64 :: MAX - 1 ) ;
558+ assert_eq ! ( take. seek( io:: SeekFrom :: Start ( 0 ) ) ?, 0 ) ;
559+ assert_eq ! ( take. inner. position, 1 ) ;
560+ assert_eq ! ( take. seek( io:: SeekFrom :: End ( -1 ) ) ?, u64 :: MAX - 3 ) ;
561+ assert_eq ! ( take. inner. position, u64 :: MAX - 2 ) ;
562+ Ok ( ( ) )
563+ }
564+
419565// A simple example reader which uses the default implementation of
420566// read_to_end.
421567struct ExampleSliceReader < ' a > {
0 commit comments