[PATCH 4 of 4] bundle2.unbundlepart: implement seek()
Eric Sumner
ericsumner at fb.com
Wed Feb 4 13:29:38 CST 2015
# HG changeset patch
# User Eric Sumner <ericsumner at fb.com>
# Date 1421280859 28800
# Wed Jan 14 16:14:19 2015 -0800
# Node ID f0bc1ba2a91c628e1f0d4abe7b037e35668a26a1
# Parent 34be4c79b05ea59a75e2e60f25839971c120126f
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 --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -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': (),
More information about the Mercurial-devel
mailing list