mercurial/cffi/mpatch.py
changeset 32512 0e8b0b9a7acc
parent 32506 2dcb3d52ef41
child 32513 25b37900d6e0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cffi/mpatch.py	Tue May 02 21:15:31 2017 +0900
@@ -0,0 +1,50 @@
+# mpatch.py - CFFI implementation of mpatch.c
+#
+# Copyright 2016 Maciej Fijalkowski <fijall@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+from ..pure.mpatch import *
+from ..pure.mpatch import mpatchError  # silence pyflakes
+from . import _mpatch
+
+ffi = _mpatch.ffi
+lib = _mpatch.lib
+
+if True:
+    if True:
+        @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