comparison mercurial/bundle2.py @ 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 731fa8e3e580
comparison
equal deleted inserted replaced
24036:c7601086338a 24037:f0b498cfc5c8
884 super(unbundlepart, self).tell())) 884 super(unbundlepart, self).tell()))
885 yield result 885 yield result
886 payloadsize = self._unpack(_fpayloadsize)[0] 886 payloadsize = self._unpack(_fpayloadsize)[0]
887 self.ui.debug('payload chunk size: %i\n' % payloadsize) 887 self.ui.debug('payload chunk size: %i\n' % payloadsize)
888 888
889 def _findchunk(self, pos):
890 '''for a given payload position, return a chunk number and offset'''
891 for chunk, (ppos, fpos) in enumerate(self._chunkindex):
892 if ppos == pos:
893 return chunk, 0
894 elif ppos > pos:
895 return chunk - 1, pos - self._chunkindex[chunk - 1][0]
896 raise ValueError('Unknown chunk')
897
889 def _readheader(self): 898 def _readheader(self):
890 """read the header and setup the object""" 899 """read the header and setup the object"""
891 typesize = self._unpackheader(_fparttypesize)[0] 900 typesize = self._unpackheader(_fparttypesize)[0]
892 self.type = self._fromheader(typesize) 901 self.type = self._fromheader(typesize)
893 self.ui.debug('part type: "%s"\n' % self.type) 902 self.ui.debug('part type: "%s"\n' % self.type)
935 return data 944 return data
936 945
937 def tell(self): 946 def tell(self):
938 return self._pos 947 return self._pos
939 948
949 def seek(self, offset, whence=0):
950 if whence == 0:
951 newpos = offset
952 elif whence == 1:
953 newpos = self._pos + offset
954 elif whence == 2:
955 if not self.consumed:
956 self.read()
957 newpos = self._chunkindex[-1][0] - offset
958 else:
959 raise ValueError('Unknown whence value: %r' % (whence,))
960
961 if newpos > self._chunkindex[-1][0] and not self.consumed:
962 self.read()
963 if not 0 <= newpos <= self._chunkindex[-1][0]:
964 raise ValueError('Offset out of range')
965
966 if self._pos != newpos:
967 chunk, internaloffset = self._findchunk(newpos)
968 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk))
969 adjust = self.read(internaloffset)
970 if len(adjust) != internaloffset:
971 raise util.Abort(_('Seek failed\n'))
972 self._pos = newpos
973
940 capabilities = {'HG2Y': (), 974 capabilities = {'HG2Y': (),
941 'b2x:listkeys': (), 975 'b2x:listkeys': (),
942 'b2x:pushkey': (), 976 'b2x:pushkey': (),
943 'digests': tuple(sorted(util.DIGESTS.keys())), 977 'digests': tuple(sorted(util.DIGESTS.keys())),
944 'b2x:remote-changegroup': ('http', 'https'), 978 'b2x:remote-changegroup': ('http', 'https'),