Mercurial > hg
changeset 24037:f0b498cfc5c8
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.
author | Eric Sumner <ericsumner@fb.com> |
---|---|
date | Wed, 14 Jan 2015 16:14:19 -0800 |
parents | c7601086338a |
children | 10d02cd18604 |
files | mercurial/bundle2.py |
diffstat | 1 files changed, 34 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- 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': (),