@@ -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