##// END OF EJS Templates
bundle2: move 'seek' and 'tell' methods off the unpackermixin class...
Pierre-Yves David -
r31889:a02e7730 default
parent child Browse files
Show More
@@ -617,8 +617,6 b' class unpackermixin(object):'
617
617
618 def __init__(self, fp):
618 def __init__(self, fp):
619 self._fp = fp
619 self._fp = fp
620 self._seekable = (util.safehasattr(fp, 'seek') and
621 util.safehasattr(fp, 'tell'))
622
620
623 def _unpack(self, format):
621 def _unpack(self, format):
624 """unpack this struct format from the stream
622 """unpack this struct format from the stream
@@ -641,25 +639,6 b' class unpackermixin(object):'
641 Do not use it to implement higher-level logic or methods."""
639 Do not use it to implement higher-level logic or methods."""
642 return changegroup.readexactly(self._fp, size)
640 return changegroup.readexactly(self._fp, size)
643
641
644 def seek(self, offset, whence=0):
645 """move the underlying file pointer"""
646 if self._seekable:
647 return self._fp.seek(offset, whence)
648 else:
649 raise NotImplementedError(_('File pointer is not seekable'))
650
651 def tell(self):
652 """return the file offset, or None if file is not seekable"""
653 if self._seekable:
654 try:
655 return self._fp.tell()
656 except IOError as e:
657 if e.errno == errno.ESPIPE:
658 self._seekable = False
659 else:
660 raise
661 return None
662
663 def getunbundler(ui, fp, magicstring=None):
642 def getunbundler(ui, fp, magicstring=None):
664 """return a valid unbundler object for a given magicstring"""
643 """return a valid unbundler object for a given magicstring"""
665 if magicstring is None:
644 if magicstring is None:
@@ -1111,6 +1090,8 b' class unbundlepart(unpackermixin):'
1111
1090
1112 def __init__(self, ui, header, fp):
1091 def __init__(self, ui, header, fp):
1113 super(unbundlepart, self).__init__(fp)
1092 super(unbundlepart, self).__init__(fp)
1093 self._seekable = (util.safehasattr(fp, 'seek') and
1094 util.safehasattr(fp, 'tell'))
1114 self.ui = ui
1095 self.ui = ui
1115 # unbundle state attr
1096 # unbundle state attr
1116 self._headerdata = header
1097 self._headerdata = header
@@ -1158,11 +1139,11 b' class unbundlepart(unpackermixin):'
1158 '''seek to specified chunk and start yielding data'''
1139 '''seek to specified chunk and start yielding data'''
1159 if len(self._chunkindex) == 0:
1140 if len(self._chunkindex) == 0:
1160 assert chunknum == 0, 'Must start with chunk 0'
1141 assert chunknum == 0, 'Must start with chunk 0'
1161 self._chunkindex.append((0, super(unbundlepart, self).tell()))
1142 self._chunkindex.append((0, self._tellfp()))
1162 else:
1143 else:
1163 assert chunknum < len(self._chunkindex), \
1144 assert chunknum < len(self._chunkindex), \
1164 'Unknown chunk %d' % chunknum
1145 'Unknown chunk %d' % chunknum
1165 super(unbundlepart, self).seek(self._chunkindex[chunknum][1])
1146 self._seekfp(self._chunkindex[chunknum][1])
1166
1147
1167 pos = self._chunkindex[chunknum][0]
1148 pos = self._chunkindex[chunknum][0]
1168 payloadsize = self._unpack(_fpayloadsize)[0]
1149 payloadsize = self._unpack(_fpayloadsize)[0]
@@ -1180,8 +1161,7 b' class unbundlepart(unpackermixin):'
1180 chunknum += 1
1161 chunknum += 1
1181 pos += payloadsize
1162 pos += payloadsize
1182 if chunknum == len(self._chunkindex):
1163 if chunknum == len(self._chunkindex):
1183 self._chunkindex.append((pos,
1164 self._chunkindex.append((pos, self._tellfp()))
1184 super(unbundlepart, self).tell()))
1185 yield result
1165 yield result
1186 payloadsize = self._unpack(_fpayloadsize)[0]
1166 payloadsize = self._unpack(_fpayloadsize)[0]
1187 indebug(self.ui, 'payload chunk size: %i' % payloadsize)
1167 indebug(self.ui, 'payload chunk size: %i' % payloadsize)
@@ -1274,6 +1254,37 b' class unbundlepart(unpackermixin):'
1274 raise error.Abort(_('Seek failed\n'))
1254 raise error.Abort(_('Seek failed\n'))
1275 self._pos = newpos
1255 self._pos = newpos
1276
1256
1257 def _seekfp(self, offset, whence=0):
1258 """move the underlying file pointer
1259
1260 This method is meant for internal usage by the bundle2 protocol only.
1261 They directly manipulate the low level stream including bundle2 level
1262 instruction.
1263
1264 Do not use it to implement higher-level logic or methods."""
1265 if self._seekable:
1266 return self._fp.seek(offset, whence)
1267 else:
1268 raise NotImplementedError(_('File pointer is not seekable'))
1269
1270 def _tellfp(self):
1271 """return the file offset, or None if file is not seekable
1272
1273 This method is meant for internal usage by the bundle2 protocol only.
1274 They directly manipulate the low level stream including bundle2 level
1275 instruction.
1276
1277 Do not use it to implement higher-level logic or methods."""
1278 if self._seekable:
1279 try:
1280 return self._fp.tell()
1281 except IOError as e:
1282 if e.errno == errno.ESPIPE:
1283 self._seekable = False
1284 else:
1285 raise
1286 return None
1287
1277 # These are only the static capabilities.
1288 # These are only the static capabilities.
1278 # Check the 'getrepocaps' function for the rest.
1289 # Check the 'getrepocaps' function for the rest.
1279 capabilities = {'HG20': (),
1290 capabilities = {'HG20': (),
General Comments 0
You need to be logged in to leave comments. Login now