changeset 12334:50946802593d

bundle: refactor progress callback This lets us eliminate the chunk iterator so we can have the bundle class parse headers.
author Matt Mackall <mpm@selenic.com>
date Sun, 19 Sep 2010 12:38:44 -0500
parents 44c7dfc2f6a3
children e21fe9c5fb25
files mercurial/changegroup.py mercurial/localrepo.py
diffstat 2 files changed, 32 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/changegroup.py	Sat Sep 18 18:20:34 2010 -0500
+++ b/mercurial/changegroup.py	Sun Sep 19 12:38:44 2010 -0500
@@ -142,6 +142,7 @@
     def __init__(self, fh, alg):
         self._stream = decompressor(fh, alg)
         self._type = alg
+        self.callback = None
     def compressed(self):
         return self._type != 'UN'
     def read(self, l):
@@ -150,10 +151,32 @@
         return self._stream.seek(pos)
     def tell(self):
         return self._stream.tell()
-    def chunks(self, progress=None):
-        return chunkiter(self, progress)
+
+    def chunklength(self):
+        d = self.read(4)
+        if not d:
+            return 0
+        l = max(0, struct.unpack(">l", d)[0] - 4)
+        if l and self.callback:
+            self.callback()
+        return l
+
     def chunk(self):
-        return getchunk(self)
+        """return the next chunk from changegroup 'source' as a string"""
+        l = self.chunklength()
+        d = self.read(l)
+        if len(d) < l:
+            raise util.Abort(_("premature EOF reading chunk"
+                               " (got %d bytes, expected %d)")
+                             % (len(d), l))
+        return d
+
+    def chunks(self):
+        while 1:
+            c = self.chunk()
+            if not c:
+                break
+            yield c
 
 class headerlessfixup(object):
     def __init__(self, fh, h):
--- a/mercurial/localrepo.py	Sat Sep 18 18:20:34 2010 -0500
+++ b/mercurial/localrepo.py	Sun Sep 19 12:38:44 2010 -0500
@@ -1674,7 +1674,9 @@
                                      total=self.total)
                     self.count += 1
             pr = prog()
-            if (cl.addgroup(source.chunks(pr), csmap, trp) is None
+            source.callback = pr
+
+            if (cl.addgroup(source.chunks(), csmap, trp) is None
                 and not emptyok):
                 raise util.Abort(_("received changelog group is empty"))
             clend = len(cl)
@@ -1693,7 +1695,7 @@
             # if the result of the merge of 1 and 2 is the same in 3 and 4,
             # no new manifest will be created and the manifest group will
             # be empty during the pull
-            self.manifest.addgroup(source.chunks(pr), revmap, trp)
+            self.manifest.addgroup(source.chunks(), revmap, trp)
             self.ui.progress(_('manifests'), None)
 
             needfiles = {}
@@ -1711,6 +1713,8 @@
             pr.step = 'files'
             pr.count = 1
             pr.total = efiles
+            source.callback = None
+
             while 1:
                 f = source.chunk()
                 if not f: