[PATCH 6 of 7 V3] util: add a file handle wrapper class that does hash digest validation
Mike Hommey
mh at glandium.org
Thu Oct 16 08:22:31 UTC 2014
# HG changeset patch
# User Mike Hommey <mh at glandium.org>
# Date 1413446601 -32400
# Thu Oct 16 17:03:21 2014 +0900
# Node ID dad191f49c35873419268b31cef19dbc251ad812
# Parent f6cbabdb852b211b67797d9775989f614ff56528
util: add a file handle wrapper class that does hash digest validation
It is going to be used for the remote-changegroup feature in bundle2.
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -179,16 +179,47 @@ class digester(object):
def preferred(supported):
"""returns the strongest digest type in both supported and DIGESTS."""
for k in DIGESTS_BY_STRENGTH:
if k in supported:
return k
return None
+class digestchecker(object):
+ """file handle wrapper that additionally checks content against a given
+ size and digests.
+
+ d = digestchecker(fh, size, {'md5': '...'})
+
+ When multiple digests are given, all of them are validated.
+ """
+
+ def __init__(self, fh, size, digests):
+ self._fh = fh
+ self._size = size
+ self._got = 0
+ self._digests = dict(digests)
+ self._digester = digester(self._digests.keys())
+
+ def read(self, length=-1):
+ content = self._fh.read(length)
+ self._digester.update(content)
+ self._got += len(content)
+ return content
+
+ def validate(self):
+ if self._size != self._got:
+ raise Abort(_('size mismatch: expected %d, got %d') %
+ (self._size, self._got))
+ for k, v in self._digests.items():
+ if v != self._digester[k]:
+ raise Abort(_('%s mismatch: expected %s, got %s') %
+ (k, v, self._digester[k]))
+
try:
buffer = buffer
except NameError:
if sys.version_info[0] < 3:
def buffer(sliceable, offset=0):
return sliceable[offset:]
else:
def buffer(sliceable, offset=0):
More information about the Mercurial-devel
mailing list