@@ -3075,47 +3075,27 @@ impl<T> SizeHint for Take<T> {
30753075#[ stable( feature = "seek_io_take" , since = "CURRENT_RUSTC_VERSION" ) ]
30763076impl < T : Seek > Seek for Take < T > {
30773077 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) ,
30963082 } ;
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 ;
31043091 }
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 ) ?;
31143096 }
3115- self . inner . seek ( SeekFrom :: Current ( -( offset_from_current as i64 ) ) ) ?;
3116- self . limit += offset_from_current;
3117- Ok ( self . position ( ) )
31183097 }
3098+ Ok ( new_position)
31193099 }
31203100
31213101 fn stream_len ( & mut self ) -> Result < u64 > {
@@ -3125,6 +3105,15 @@ impl<T: Seek> Seek for Take<T> {
31253105 fn stream_position ( & mut self ) -> Result < u64 > {
31263106 Ok ( self . position ( ) )
31273107 }
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+ }
31283117}
31293118
31303119/// An iterator over `u8` values of a reader.
0 commit comments