mercurial/cffi/mpatch.py
changeset 32545 0e8b0b9a7acc
parent 32539 2dcb3d52ef41
child 32546 25b37900d6e0
equal deleted inserted replaced
32544:2e431fb98c6b 32545:0e8b0b9a7acc
       
     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 
       
     8 from __future__ import absolute_import
       
     9 
       
    10 from ..pure.mpatch import *
       
    11 from ..pure.mpatch import mpatchError  # silence pyflakes
       
    12 from . import _mpatch
       
    13 
       
    14 ffi = _mpatch.ffi
       
    15 lib = _mpatch.lib
       
    16 
       
    17 if True:
       
    18     if True:
       
    19         @ffi.def_extern()
       
    20         def cffi_get_next_item(arg, pos):
       
    21             all, bins = ffi.from_handle(arg)
       
    22             container = ffi.new("struct mpatch_flist*[1]")
       
    23             to_pass = ffi.new("char[]", str(bins[pos]))
       
    24             all.append(to_pass)
       
    25             r = lib.mpatch_decode(to_pass, len(to_pass) - 1, container)
       
    26             if r < 0:
       
    27                 return ffi.NULL
       
    28             return container[0]
       
    29 
       
    30         def patches(text, bins):
       
    31             lgt = len(bins)
       
    32             all = []
       
    33             if not lgt:
       
    34                 return text
       
    35             arg = (all, bins)
       
    36             patch = lib.mpatch_fold(ffi.new_handle(arg),
       
    37                                     lib.cffi_get_next_item, 0, lgt)
       
    38             if not patch:
       
    39                 raise mpatchError("cannot decode chunk")
       
    40             outlen = lib.mpatch_calcsize(len(text), patch)
       
    41             if outlen < 0:
       
    42                 lib.mpatch_lfree(patch)
       
    43                 raise mpatchError("inconsistency detected")
       
    44             buf = ffi.new("char[]", outlen)
       
    45             if lib.mpatch_apply(buf, text, len(text), patch) < 0:
       
    46                 lib.mpatch_lfree(patch)
       
    47                 raise mpatchError("error applying patches")
       
    48             res = ffi.buffer(buf, outlen)[:]
       
    49             lib.mpatch_lfree(patch)
       
    50             return res