# HG changeset patch # User Eric Sumner # Date 1421280859 28800 # Node ID f0b498cfc5c839b07ca8832d57ef8f3a473db56a # Parent c7601086338a12fd915d544d1af3e75750576d2e bundle2.unbundlepart: implement seek() This implements a seek() method for unbundlepart. This allows on-disk bundle2 parts to behave enough like files for bundlerepo to handle them. A future patch will add support for bundlerepo to read the bundle2 files that are written when the experimental.strip-bundle2-version config option is used. diff -r c7601086338a -r f0b498cfc5c8 mercurial/bundle2.py --- a/mercurial/bundle2.py Wed Jan 14 15:57:57 2015 -0800 +++ b/mercurial/bundle2.py Wed Jan 14 16:14:19 2015 -0800 @@ -886,6 +886,15 @@ payloadsize = self._unpack(_fpayloadsize)[0] self.ui.debug('payload chunk size: %i\n' % payloadsize) + def _findchunk(self, pos): + '''for a given payload position, return a chunk number and offset''' + for chunk, (ppos, fpos) in enumerate(self._chunkindex): + if ppos == pos: + return chunk, 0 + elif ppos > pos: + return chunk - 1, pos - self._chunkindex[chunk - 1][0] + raise ValueError('Unknown chunk') + def _readheader(self): """read the header and setup the object""" typesize = self._unpackheader(_fparttypesize)[0] @@ -937,6 +946,31 @@ def tell(self): return self._pos + def seek(self, offset, whence=0): + if whence == 0: + newpos = offset + elif whence == 1: + newpos = self._pos + offset + elif whence == 2: + if not self.consumed: + self.read() + newpos = self._chunkindex[-1][0] - offset + else: + raise ValueError('Unknown whence value: %r' % (whence,)) + + if newpos > self._chunkindex[-1][0] and not self.consumed: + self.read() + if not 0 <= newpos <= self._chunkindex[-1][0]: + raise ValueError('Offset out of range') + + if self._pos != newpos: + chunk, internaloffset = self._findchunk(newpos) + self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk)) + adjust = self.read(internaloffset) + if len(adjust) != internaloffset: + raise util.Abort(_('Seek failed\n')) + self._pos = newpos + capabilities = {'HG2Y': (), 'b2x:listkeys': (), 'b2x:pushkey': (),