112
113
return current_offset, self.current_offset - current_offset
116
class ReadVFile(object):
117
"""Adapt a readv result iterator to a file like protocol."""
119
def __init__(self, readv_result):
120
self.readv_result = readv_result
121
# the most recent readv result block
125
if (self._string is None or
126
self._string.tell() == self._string_length):
127
length, data = self.readv_result.next()
128
self._string_length = len(data)
129
self._string = StringIO(data)
131
def read(self, length):
133
result = self._string.read(length)
134
if len(result) < length:
135
raise errors.BzrError('request for too much data from a readv hunk.')
139
"""Note that readline will not cross readv segments."""
141
result = self._string.readline()
142
if self._string.tell() == self._string_length and result[-1] != '\n':
143
raise errors.BzrError('short readline in the readvfile hunk.')
147
def make_readv_reader(transport, filename, requested_records):
148
"""Create a ContainerReader that will read selected records only.
150
:param transport: The transport the pack file is located on.
151
:param filename: The filename of the pack file.
152
:param requested_records: The record offset, length tuples as returned
153
by add_bytes_record for the desired records.
155
readv_blocks = [(0, len(FORMAT_ONE)+1)]
156
readv_blocks.extend(requested_records)
157
result = ContainerReader(ReadVFile(
158
transport.readv(filename, readv_blocks)))
115
162
class BaseReader(object):
117
164
def __init__(self, source_file):