@@ -416,6 +416,152 @@ 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
+
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
+
419
565
// A simple example reader which uses the default implementation of
420
566
// read_to_end.
421
567
struct ExampleSliceReader < ' a > {
0 commit comments