# HG changeset patch # User Mike Hommey # Date 2014-10-16 08:03:21 # Node ID 56e04741bbf1a9fb565a4454fb708ab3fca30417 # Parent 4d58f4083148eac60477c8de24d444c54cbb6cba 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 @@ -183,6 +183,37 @@ class digester(object): 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: