@@ -416,6 +416,116 @@ fn seek_position() -> io::Result<()> {
416
416
Ok ( ( ) )
417
417
}
418
418
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
+
419
529
// A simple example reader which uses the default implementation of
420
530
// read_to_end.
421
531
struct ExampleSliceReader < ' a > {
0 commit comments