|
1 # bdiff.py - CFFI implementation of bdiff.c |
|
2 # |
|
3 # Copyright 2016 Maciej Fijalkowski <fijall@gmail.com> |
|
4 # |
|
5 # This software may be used and distributed according to the terms of the |
|
6 # GNU General Public License version 2 or any later version. |
|
7 |
|
8 from __future__ import absolute_import |
|
9 |
|
10 import struct |
|
11 |
|
12 from ..pure.bdiff import * |
|
13 from . import _bdiff |
|
14 |
|
15 ffi = _bdiff.ffi |
|
16 lib = _bdiff.lib |
|
17 |
|
18 if True: |
|
19 if True: |
|
20 def blocks(sa, sb): |
|
21 a = ffi.new("struct bdiff_line**") |
|
22 b = ffi.new("struct bdiff_line**") |
|
23 ac = ffi.new("char[]", str(sa)) |
|
24 bc = ffi.new("char[]", str(sb)) |
|
25 l = ffi.new("struct bdiff_hunk*") |
|
26 try: |
|
27 an = lib.bdiff_splitlines(ac, len(sa), a) |
|
28 bn = lib.bdiff_splitlines(bc, len(sb), b) |
|
29 if not a[0] or not b[0]: |
|
30 raise MemoryError |
|
31 count = lib.bdiff_diff(a[0], an, b[0], bn, l) |
|
32 if count < 0: |
|
33 raise MemoryError |
|
34 rl = [None] * count |
|
35 h = l.next |
|
36 i = 0 |
|
37 while h: |
|
38 rl[i] = (h.a1, h.a2, h.b1, h.b2) |
|
39 h = h.next |
|
40 i += 1 |
|
41 finally: |
|
42 lib.free(a[0]) |
|
43 lib.free(b[0]) |
|
44 lib.bdiff_freehunks(l.next) |
|
45 return rl |
|
46 |
|
47 def bdiff(sa, sb): |
|
48 a = ffi.new("struct bdiff_line**") |
|
49 b = ffi.new("struct bdiff_line**") |
|
50 ac = ffi.new("char[]", str(sa)) |
|
51 bc = ffi.new("char[]", str(sb)) |
|
52 l = ffi.new("struct bdiff_hunk*") |
|
53 try: |
|
54 an = lib.bdiff_splitlines(ac, len(sa), a) |
|
55 bn = lib.bdiff_splitlines(bc, len(sb), b) |
|
56 if not a[0] or not b[0]: |
|
57 raise MemoryError |
|
58 count = lib.bdiff_diff(a[0], an, b[0], bn, l) |
|
59 if count < 0: |
|
60 raise MemoryError |
|
61 rl = [] |
|
62 h = l.next |
|
63 la = lb = 0 |
|
64 while h: |
|
65 if h.a1 != la or h.b1 != lb: |
|
66 lgt = (b[0] + h.b1).l - (b[0] + lb).l |
|
67 rl.append(struct.pack(">lll", (a[0] + la).l - a[0].l, |
|
68 (a[0] + h.a1).l - a[0].l, lgt)) |
|
69 rl.append(str(ffi.buffer((b[0] + lb).l, lgt))) |
|
70 la = h.a2 |
|
71 lb = h.b2 |
|
72 h = h.next |
|
73 |
|
74 finally: |
|
75 lib.free(a[0]) |
|
76 lib.free(b[0]) |
|
77 lib.bdiff_freehunks(l.next) |
|
78 return "".join(rl) |