@@ -123,9 +123,12 @@ def read(self, size=-1):
123
123
# If the read request demands more bytes than are buffered, fetch more.
124
124
remaining_size = size - len (result )
125
125
if remaining_size > 0 or size < 0 :
126
+ self ._pos += self ._buffer .tell ()
127
+ read_size = len (result )
128
+
126
129
self ._buffer .seek (0 )
127
130
self ._buffer .truncate (0 ) # Clear the buffer to make way for new data.
128
- fetch_start = self ._pos + len ( result )
131
+ fetch_start = self ._pos
129
132
if size > 0 :
130
133
# Fetch the larger of self._chunk_size or the remaining_size.
131
134
fetch_end = fetch_start + max (remaining_size , self ._chunk_size )
@@ -154,9 +157,8 @@ def read(self, size=-1):
154
157
self ._buffer .write (result [size :])
155
158
self ._buffer .seek (0 )
156
159
result = result [:size ]
157
-
158
- self ._pos += len (result )
159
-
160
+ # Increment relative offset by true amount read.
161
+ self ._pos += len (result ) - read_size
160
162
return result
161
163
162
164
def read1 (self , size = - 1 ):
@@ -174,29 +176,33 @@ def seek(self, pos, whence=0):
174
176
if self ._blob .size is None :
175
177
self ._blob .reload (** self ._download_kwargs )
176
178
177
- initial_pos = self ._pos
179
+ initial_offset = self ._pos + self . _buffer . tell ()
178
180
179
181
if whence == 0 :
180
- self . _pos = pos
182
+ target_pos = pos
181
183
elif whence == 1 :
182
- self . _pos += pos
184
+ target_pos = initial_offset + pos
183
185
elif whence == 2 :
184
- self . _pos = self ._blob .size + pos
186
+ target_pos = self ._blob .size + pos
185
187
if whence not in {0 , 1 , 2 }:
186
188
raise ValueError ("invalid whence value" )
187
189
188
- if self . _pos > self ._blob .size :
189
- self . _pos = self ._blob .size
190
+ if target_pos > self ._blob .size :
191
+ target_pos = self ._blob .size
190
192
191
193
# Seek or invalidate buffer as needed.
192
- difference = self ._pos - initial_pos
193
- new_buffer_pos = self ._buffer .seek (difference , 1 )
194
- if new_buffer_pos != difference : # Buffer does not contain new pos.
195
- # Invalidate buffer.
194
+ if target_pos < self ._pos :
195
+ # Target position < relative offset <= true offset.
196
+ # As data is not in buffer, invalidate buffer.
196
197
self ._buffer .seek (0 )
197
198
self ._buffer .truncate (0 )
198
-
199
- return self ._pos
199
+ new_pos = target_pos
200
+ self ._pos = target_pos
201
+ else :
202
+ # relative offset <= target position <= size of file.
203
+ difference = target_pos - initial_offset
204
+ new_pos = self ._pos + self ._buffer .seek (difference , 1 )
205
+ return new_pos
200
206
201
207
def close (self ):
202
208
self ._buffer .close ()
0 commit comments