mpatch.py
48 lines
| 1.4 KiB
| text/x-python
|
PythonLexer
Yuya Nishihara
|
r32512 | # 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 ..pure.mpatch import * | ||||
from ..pure.mpatch import mpatchError # silence pyflakes | ||||
Matt Harbison
|
r47543 | from . import _mpatch # pytype: disable=import-error | ||
Yuya Nishihara
|
r32512 | |||
ffi = _mpatch.ffi | ||||
lib = _mpatch.lib | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32513 | @ffi.def_extern() | ||
def cffi_get_next_item(arg, pos): | ||||
all, bins = ffi.from_handle(arg) | ||||
Augie Fackler
|
r43347 | container = ffi.new(b"struct mpatch_flist*[1]") | ||
to_pass = ffi.new(b"char[]", str(bins[pos])) | ||||
Yuya Nishihara
|
r32513 | all.append(to_pass) | ||
r = lib.mpatch_decode(to_pass, len(to_pass) - 1, container) | ||||
if r < 0: | ||||
return ffi.NULL | ||||
return container[0] | ||||
Yuya Nishihara
|
r32512 | |||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32513 | def patches(text, bins): | ||
lgt = len(bins) | ||||
all = [] | ||||
if not lgt: | ||||
return text | ||||
arg = (all, bins) | ||||
Augie Fackler
|
r43346 | patch = lib.mpatch_fold(ffi.new_handle(arg), lib.cffi_get_next_item, 0, lgt) | ||
Yuya Nishihara
|
r32513 | if not patch: | ||
Augie Fackler
|
r43347 | raise mpatchError(b"cannot decode chunk") | ||
Yuya Nishihara
|
r32513 | outlen = lib.mpatch_calcsize(len(text), patch) | ||
if outlen < 0: | ||||
lib.mpatch_lfree(patch) | ||||
Augie Fackler
|
r43347 | raise mpatchError(b"inconsistency detected") | ||
buf = ffi.new(b"char[]", outlen) | ||||
Yuya Nishihara
|
r32513 | if lib.mpatch_apply(buf, text, len(text), patch) < 0: | ||
lib.mpatch_lfree(patch) | ||||
Augie Fackler
|
r43347 | raise mpatchError(b"error applying patches") | ||
Yuya Nishihara
|
r32513 | res = ffi.buffer(buf, outlen)[:] | ||
lib.mpatch_lfree(patch) | ||||
return res | ||||