@@ -3075,47 +3075,27 @@ impl<T> SizeHint for Take<T> {
3075
3075
#[ stable( feature = "seek_io_take" , since = "CURRENT_RUSTC_VERSION" ) ]
3076
3076
impl < T : Seek > Seek for Take < T > {
3077
3077
fn seek ( & mut self , pos : SeekFrom ) -> Result < u64 > {
3078
- let offset_from_start = match pos {
3079
- SeekFrom :: Start ( offset) => offset,
3080
- SeekFrom :: End ( offset) => {
3081
- if offset > 0 {
3082
- return Ok ( self . position ( ) ) ;
3083
- }
3084
- if offset. unsigned_abs ( ) > self . len {
3085
- return Err ( Error :: from ( ErrorKind :: InvalidInput ) ) ;
3086
- }
3087
- self . len - offset. unsigned_abs ( )
3088
- }
3089
- SeekFrom :: Current ( offset) => {
3090
- if offset >= 0 {
3091
- self . position ( ) + offset. unsigned_abs ( )
3092
- } else {
3093
- self . position ( ) - offset. unsigned_abs ( )
3094
- }
3095
- }
3078
+ let new_position = match pos {
3079
+ SeekFrom :: Start ( v) => Some ( v) ,
3080
+ SeekFrom :: Current ( v) => self . position ( ) . checked_add_signed ( v) ,
3081
+ SeekFrom :: End ( v) => self . len . checked_add_signed ( v) ,
3096
3082
} ;
3097
- let offset_from_start = offset_from_start. min ( self . len ) ;
3098
- if offset_from_start > self . position ( ) {
3099
- let mut offset_from_current = offset_from_start - self . position ( ) ;
3100
- while offset_from_current > i64:: MAX as u64 {
3101
- self . inner . seek ( SeekFrom :: Current ( i64:: MAX ) ) ?;
3102
- self . limit -= i64:: MAX as u64 ;
3103
- offset_from_current -= i64:: MAX as u64 ;
3083
+ let new_position = match new_position {
3084
+ Some ( v) if v <= self . len => v,
3085
+ _ => return Err ( ErrorKind :: InvalidInput . into ( ) ) ,
3086
+ } ;
3087
+ while new_position != self . position ( ) {
3088
+ if let Some ( offset) = new_position. checked_signed_diff ( self . position ( ) ) {
3089
+ self . seek_relative ( offset) ?;
3090
+ break ;
3104
3091
}
3105
- self . inner . seek ( SeekFrom :: Current ( offset_from_current as i64 ) ) ?;
3106
- self . limit -= offset_from_current;
3107
- Ok ( self . position ( ) )
3108
- } else {
3109
- let mut offset_from_current = self . position ( ) - offset_from_start;
3110
- while offset_from_current > i64:: MIN . unsigned_abs ( ) {
3111
- self . inner . seek ( SeekFrom :: Current ( i64:: MIN ) ) ?;
3112
- self . limit += i64:: MIN . unsigned_abs ( ) ;
3113
- offset_from_current -= i64:: MIN . unsigned_abs ( ) ;
3092
+ if new_position > self . position ( ) {
3093
+ self . seek_relative ( i64:: MAX ) ?;
3094
+ } else {
3095
+ self . seek_relative ( i64:: MIN ) ?;
3114
3096
}
3115
- self . inner . seek ( SeekFrom :: Current ( -( offset_from_current as i64 ) ) ) ?;
3116
- self . limit += offset_from_current;
3117
- Ok ( self . position ( ) )
3118
3097
}
3098
+ Ok ( new_position)
3119
3099
}
3120
3100
3121
3101
fn stream_len ( & mut self ) -> Result < u64 > {
@@ -3125,6 +3105,15 @@ impl<T: Seek> Seek for Take<T> {
3125
3105
fn stream_position ( & mut self ) -> Result < u64 > {
3126
3106
Ok ( self . position ( ) )
3127
3107
}
3108
+
3109
+ fn seek_relative ( & mut self , offset : i64 ) -> Result < ( ) > {
3110
+ if !self . position ( ) . checked_add_signed ( offset) . is_some_and ( |p| p <= self . len ) {
3111
+ return Err ( ErrorKind :: InvalidInput . into ( ) ) ;
3112
+ }
3113
+ self . inner . seek_relative ( offset) ?;
3114
+ self . limit = self . limit . wrapping_sub ( offset as u64 ) ;
3115
+ Ok ( ( ) )
3116
+ }
3128
3117
}
3129
3118
3130
3119
/// An iterator over `u8` values of a reader.
0 commit comments