Mercurial > hg
diff mercurial/pure/mpatch.py @ 29695:f2846d546645
mpatch: write a cffi version of mpatch.patches
author | Maciej Fijalkowski <fijall@gmail.com> |
---|---|
date | Mon, 25 Jul 2016 15:10:52 +0200 |
parents | 86db5cb55d46 |
children | 151cc3b3d799 |
line wrap: on
line diff
--- a/mercurial/pure/mpatch.py Fri Jul 22 17:28:05 2016 +0200 +++ b/mercurial/pure/mpatch.py Mon Jul 25 15:10:52 2016 +0200 @@ -9,8 +9,10 @@ import struct -from . import pycompat +from . import policy, pycompat stringio = pycompat.stringio +modulepolicy = policy.policy +policynocffi = policy.policynocffi class mpatchError(Exception): """error raised when a delta cannot be decoded @@ -125,3 +127,44 @@ outlen += orig - last return outlen + +if modulepolicy not in policynocffi: + try: + from _mpatch_cffi import ffi, lib + except ImportError: + if modulepolicy == 'cffi': # strict cffi import + raise + else: + @ffi.def_extern() + def cffi_get_next_item(arg, pos): + all, bins = ffi.from_handle(arg) + container = ffi.new("struct mpatch_flist*[1]") + to_pass = ffi.new("char[]", str(bins[pos])) + all.append(to_pass) + r = lib.mpatch_decode(to_pass, len(to_pass) - 1, container) + if r < 0: + return ffi.NULL + return container[0] + + def patches(text, bins): + lgt = len(bins) + all = [] + if not lgt: + return text + arg = (all, bins) + patch = lib.mpatch_fold(ffi.new_handle(arg), + lib.cffi_get_next_item, 0, lgt) + if not patch: + raise mpatchError("cannot decode chunk") + outlen = lib.mpatch_calcsize(len(text), patch) + if outlen < 0: + lib.mpatch_lfree(patch) + raise mpatchError("inconsistency detected") + buf = ffi.new("char[]", outlen) + if lib.mpatch_apply(buf, text, len(text), patch) < 0: + lib.mpatch_lfree(patch) + raise mpatchError("error applying patches") + res = ffi.buffer(buf, outlen)[:] + lib.mpatch_lfree(patch) + return res +