Mercurial > hg
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 |