mercurial/cffi/bdiff.py
changeset 32512 0e8b0b9a7acc
parent 32506 2dcb3d52ef41
child 32513 25b37900d6e0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/cffi/bdiff.py	Tue May 02 21:15:31 2017 +0900
@@ -0,0 +1,78 @@
+# bdiff.py - CFFI implementation of bdiff.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
+
+import struct
+
+from ..pure.bdiff import *
+from . import _bdiff
+
+ffi = _bdiff.ffi
+lib = _bdiff.lib
+
+if True:
+    if True:
+        def blocks(sa, sb):
+            a = ffi.new("struct bdiff_line**")
+            b = ffi.new("struct bdiff_line**")
+            ac = ffi.new("char[]", str(sa))
+            bc = ffi.new("char[]", str(sb))
+            l = ffi.new("struct bdiff_hunk*")
+            try:
+                an = lib.bdiff_splitlines(ac, len(sa), a)
+                bn = lib.bdiff_splitlines(bc, len(sb), b)
+                if not a[0] or not b[0]:
+                    raise MemoryError
+                count = lib.bdiff_diff(a[0], an, b[0], bn, l)
+                if count < 0:
+                    raise MemoryError
+                rl = [None] * count
+                h = l.next
+                i = 0
+                while h:
+                    rl[i] = (h.a1, h.a2, h.b1, h.b2)
+                    h = h.next
+                    i += 1
+            finally:
+                lib.free(a[0])
+                lib.free(b[0])
+                lib.bdiff_freehunks(l.next)
+            return rl
+
+        def bdiff(sa, sb):
+            a = ffi.new("struct bdiff_line**")
+            b = ffi.new("struct bdiff_line**")
+            ac = ffi.new("char[]", str(sa))
+            bc = ffi.new("char[]", str(sb))
+            l = ffi.new("struct bdiff_hunk*")
+            try:
+                an = lib.bdiff_splitlines(ac, len(sa), a)
+                bn = lib.bdiff_splitlines(bc, len(sb), b)
+                if not a[0] or not b[0]:
+                    raise MemoryError
+                count = lib.bdiff_diff(a[0], an, b[0], bn, l)
+                if count < 0:
+                    raise MemoryError
+                rl = []
+                h = l.next
+                la = lb = 0
+                while h:
+                    if h.a1 != la or h.b1 != lb:
+                        lgt = (b[0] + h.b1).l - (b[0] + lb).l
+                        rl.append(struct.pack(">lll", (a[0] + la).l - a[0].l,
+                            (a[0] + h.a1).l - a[0].l, lgt))
+                        rl.append(str(ffi.buffer((b[0] + lb).l, lgt)))
+                    la = h.a2
+                    lb = h.b2
+                    h = h.next
+
+            finally:
+                lib.free(a[0])
+                lib.free(b[0])
+                lib.bdiff_freehunks(l.next)
+            return "".join(rl)