Mercurial > public > mercurial-scm > hg
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'), |