55
55
should happen with monotonically increasing offsets.
58
# in _checked_read() below, we may have to discard several MB in the worst
59
# case. To avoid buffering that much, we read and discard by chunks
60
# instead. The underlying file is either a socket or a StringIO, so reading
61
# 8k chunks should be fine.
62
_discarded_buf_size = 8192
58
64
def __init__(self, path, infile):
145
151
self.set_range(start, size)
147
153
def _checked_read(self, size):
148
"""Read the file checking for short reads"""
154
"""Read the file checking for short reads.
156
The data read is discarded along the way.
150
data = self._file.read(size)
152
if size > 0 and data_len != size:
153
raise errors.ShortReadvError(self._path, pos, size, data_len)
154
self._pos += data_len
161
data = self._file.read(min(remaining, self._discarded_buf_size))
162
remaining -= len(data)
164
raise errors.ShortReadvError(self._path, pos, size,
157
168
def _seek_to_next_range(self):
158
169
# We will cross range boundaries
159
170
if self._boundary is None:
160
171
# If we don't have a boundary, we can't find another range
161
raise errors.InvalidRange(
162
self._path, self._pos,
163
"Range (%s, %s) exhausted"
164
% (self._start, self._size))
172
raise errors.InvalidRange(self._path, self._pos,
173
"Range (%s, %s) exhausted"
174
% (self._start, self._size))
165
175
self.read_boundary()
166
176
self.read_range_definition()