comparison mercurial/cffi/mpatch.py @ 33572:857876ebaed4 stable 4.3-rc

merge default into stable for code freeze
author Kevin Bullock <kbullock+mercurial@ringworld.org>
date Wed, 19 Jul 2017 07:51:41 -0500
parents 9cc438bf7d9a 25b37900d6e0
children 2372284d9457
comparison
equal deleted inserted replaced
33202:c1994c986d77 33572:857876ebaed4
1 # mpatch.py - CFFI implementation of mpatch.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
1 from __future__ import absolute_import 8 from __future__ import absolute_import
2 9
3 import cffi 10 from ..pure.mpatch import *
4 import os 11 from ..pure.mpatch import mpatchError # silence pyflakes
12 from . import _mpatch
5 13
6 ffi = cffi.FFI() 14 ffi = _mpatch.ffi
7 mpatch_c = os.path.join(os.path.join(os.path.dirname(__file__), '..', 15 lib = _mpatch.lib
8 'mpatch.c'))
9 ffi.set_source("_mpatch_cffi", open(mpatch_c).read(),
10 include_dirs=["mercurial"])
11 ffi.cdef("""
12 16
13 struct mpatch_frag { 17 @ffi.def_extern()
14 int start, end, len; 18 def cffi_get_next_item(arg, pos):
15 const char *data; 19 all, bins = ffi.from_handle(arg)
16 }; 20 container = ffi.new("struct mpatch_flist*[1]")
21 to_pass = ffi.new("char[]", str(bins[pos]))
22 all.append(to_pass)
23 r = lib.mpatch_decode(to_pass, len(to_pass) - 1, container)
24 if r < 0:
25 return ffi.NULL
26 return container[0]
17 27
18 struct mpatch_flist { 28 def patches(text, bins):
19 struct mpatch_frag *base, *head, *tail; 29 lgt = len(bins)
20 }; 30 all = []
21 31 if not lgt:
22 extern "Python" struct mpatch_flist* cffi_get_next_item(void*, ssize_t); 32 return text
23 33 arg = (all, bins)
24 int mpatch_decode(const char *bin, ssize_t len, struct mpatch_flist** res); 34 patch = lib.mpatch_fold(ffi.new_handle(arg),
25 ssize_t mpatch_calcsize(size_t len, struct mpatch_flist *l); 35 lib.cffi_get_next_item, 0, lgt)
26 void mpatch_lfree(struct mpatch_flist *a); 36 if not patch:
27 static int mpatch_apply(char *buf, const char *orig, size_t len, 37 raise mpatchError("cannot decode chunk")
28 struct mpatch_flist *l); 38 outlen = lib.mpatch_calcsize(len(text), patch)
29 struct mpatch_flist *mpatch_fold(void *bins, 39 if outlen < 0:
30 struct mpatch_flist* (*get_next_item)(void*, ssize_t), 40 lib.mpatch_lfree(patch)
31 ssize_t start, ssize_t end); 41 raise mpatchError("inconsistency detected")
32 """) 42 buf = ffi.new("char[]", outlen)
33 43 if lib.mpatch_apply(buf, text, len(text), patch) < 0:
34 if __name__ == '__main__': 44 lib.mpatch_lfree(patch)
35 ffi.compile() 45 raise mpatchError("error applying patches")
46 res = ffi.buffer(buf, outlen)[:]
47 lib.mpatch_lfree(patch)
48 return res