view mercurial/cffi/mpatch.py @ 32736:173f1bdc322d

bookmarks: rely on exception for malformed lines Since we already have an exception context open, for other thing, we can simplify the code a bit and rely on exception handling for invalid lines. Speed is not the main motivation for this changes. However as I'm in the middle of benchmarking things we can see a small positive impact. Before: ! wall 0.009358 comb 0.000000 user 0.000000 sys 0.000000 (best of 303) After: ! wall 0.009173 comb 0.010000 user 0.010000 sys 0.000000 (best of 310)
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 07 Jun 2017 19:22:39 +0100
parents 25b37900d6e0
children 857876ebaed4
line wrap: on
line source

# 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 __future__ import absolute_import

from ..pure.mpatch import *
from ..pure.mpatch import mpatchError  # silence pyflakes
from . import _mpatch

ffi = _mpatch.ffi
lib = _mpatch.lib

@ffi.def_extern()
def cffi_get_next_item(arg, pos):
    all, bins = ffi.from_handle(arg)
    container = ffi.new("struct mpatch_flist*[1]")
    to_pass = ffi.new("char[]", str(bins[pos]))
    all.append(to_pass)
    r = lib.mpatch_decode(to_pass, len(to_pass) - 1, container)
    if r < 0:
        return ffi.NULL
    return container[0]

def patches(text, bins):
    lgt = len(bins)
    all = []
    if not lgt:
        return text
    arg = (all, bins)
    patch = lib.mpatch_fold(ffi.new_handle(arg),
                            lib.cffi_get_next_item, 0, lgt)
    if not patch:
        raise mpatchError("cannot decode chunk")
    outlen = lib.mpatch_calcsize(len(text), patch)
    if outlen < 0:
        lib.mpatch_lfree(patch)
        raise mpatchError("inconsistency detected")
    buf = ffi.new("char[]", outlen)
    if lib.mpatch_apply(buf, text, len(text), patch) < 0:
        lib.mpatch_lfree(patch)
        raise mpatchError("error applying patches")
    res = ffi.buffer(buf, outlen)[:]
    lib.mpatch_lfree(patch)
    return res