annotate mercurial/pure/mpatch.py @ 30343:952e1916ae56

manifest: add copy to mfctx classes This adds copy functionality to the manifestctx classes. This will be used in an upcoming diff to copy a manifestctx during commit so we can modify the manifest before committing.
author Durham Goode <durham@fb.com>
date Tue, 08 Nov 2016 08:03:43 -0800
parents f2846d546645
children 151cc3b3d799
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
1 # mpatch.py - Python implementation of mpatch.c
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
2 #
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7775
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 8225
diff changeset
6 # GNU General Public License version 2 or any later version.
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
7
27337
9a17576103a4 mpatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 16683
diff changeset
8 from __future__ import absolute_import
9a17576103a4 mpatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 16683
diff changeset
9
7775
5280c39778b6 pure/mpatch: use StringIO instead of mmap (issue1493)
Martin Geisler <mg@daimi.au.dk>
parents: 7699
diff changeset
10 import struct
27337
9a17576103a4 mpatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 16683
diff changeset
11
29695
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
12 from . import policy, pycompat
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28782
diff changeset
13 stringio = pycompat.stringio
29695
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
14 modulepolicy = policy.policy
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
15 policynocffi = policy.policynocffi
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
16
28782
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
17 class mpatchError(Exception):
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
18 """error raised when a delta cannot be decoded
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
19 """
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
20
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
21 # This attempts to apply a series of patches in time proportional to
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
22 # the total size of the patches, rather than patches * len(text). This
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
23 # means rather than shuffling strings around, we shuffle around
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
24 # pointers to fragments with fragment lists.
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
25 #
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
26 # When the fragment lists get too long, we collapse them. To do this
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
27 # efficiently, we do all our operations inside a buffer created by
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
28 # mmap and simply use memmove. This avoids creating a bunch of large
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
29 # temporary string buffers.
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
30
28587
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
31 def _pull(dst, src, l): # pull l bytes from src
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
32 while l:
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
33 f = src.pop()
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
34 if f[0] > l: # do we need to split?
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
35 src.append((f[0] - l, f[1] + l))
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
36 dst.append((l, f[1]))
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
37 return
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
38 dst.append(f)
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
39 l -= f[0]
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
40
28588
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
41 def _move(m, dest, src, count):
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
42 """move count bytes from src to dest
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
43
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
44 The file pointer is left at the end of dest.
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
45 """
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
46 m.seek(src)
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
47 buf = m.read(count)
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
48 m.seek(dest)
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
49 m.write(buf)
6546afde350e mpatch: un-nest the move() method
Augie Fackler <augie@google.com>
parents: 28587
diff changeset
50
28589
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
51 def _collect(m, buf, list):
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
52 start = buf
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
53 for l, p in reversed(list):
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
54 _move(m, buf, p, l)
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
55 buf += l
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
56 return (buf - start, start)
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
57
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
58 def patches(a, bins):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
59 if not bins:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
60 return a
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
61
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
62 plens = [len(x) for x in bins]
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
63 pl = sum(plens)
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
64 bl = len(a) + pl
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
65 tl = bl + bl + pl # enough for the patches and two working texts
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
66 b1, b2 = 0, bl
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
67
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
68 if not tl:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
69 return a
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
70
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28782
diff changeset
71 m = stringio()
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
72
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
73 # load our original text
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
74 m.write(a)
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
75 frags = [(len(a), b1)]
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
76
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
77 # copy all the patches into our segment so we can memmove from them
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
78 pos = b2 + bl
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
79 m.seek(pos)
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
80 for p in bins: m.write(p)
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
81
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
82 for plen in plens:
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
83 # if our list gets too long, execute it
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
84 if len(frags) > 128:
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
85 b2, b1 = b1, b2
28589
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
86 frags = [_collect(m, b1, frags)]
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
87
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
88 new = []
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
89 end = pos + plen
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
90 last = 0
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
91 while pos < end:
7775
5280c39778b6 pure/mpatch: use StringIO instead of mmap (issue1493)
Martin Geisler <mg@daimi.au.dk>
parents: 7699
diff changeset
92 m.seek(pos)
28782
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
93 try:
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
94 p1, p2, l = struct.unpack(">lll", m.read(12))
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
95 except struct.error:
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
96 raise mpatchError("patch cannot be decoded")
28587
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
97 _pull(new, frags, p1 - last) # what didn't change
76d7cab13f04 mpatch: move pull() method to top level
Augie Fackler <augie@google.com>
parents: 27337
diff changeset
98 _pull([], frags, p2 - p1) # what got deleted
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 14065
diff changeset
99 new.append((l, pos + 12)) # what got added
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
100 pos += l + 12
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
101 last = p2
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 14065
diff changeset
102 frags.extend(reversed(new)) # what was left at the end
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
103
28589
c4c7be9f0554 mpatch: move collect() to module level
Augie Fackler <augie@google.com>
parents: 28588
diff changeset
104 t = _collect(m, b2, frags)
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
105
7775
5280c39778b6 pure/mpatch: use StringIO instead of mmap (issue1493)
Martin Geisler <mg@daimi.au.dk>
parents: 7699
diff changeset
106 m.seek(t[1])
5280c39778b6 pure/mpatch: use StringIO instead of mmap (issue1493)
Martin Geisler <mg@daimi.au.dk>
parents: 7699
diff changeset
107 return m.read(t[0])
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
108
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
109 def patchedsize(orig, delta):
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
110 outlen, last, bin = 0, 0, 0
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
111 binend = len(delta)
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
112 data = 12
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
113
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
114 while data <= binend:
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
115 decode = delta[bin:bin + 12]
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
116 start, end, length = struct.unpack(">lll", decode)
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
117 if start > end:
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
118 break
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
119 bin = data + length
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
120 data = bin + 12
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
121 outlen += start - last
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
122 last = end
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
123 outlen += length
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
124
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
125 if bin != binend:
28782
f736f98e16ca mpatch: unify mpatchError (issue5182)
timeless <timeless@mozdev.org>
parents: 28589
diff changeset
126 raise mpatchError("patch cannot be decoded")
7699
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
127
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
128 outlen += orig - last
fac054f84600 pure Python implementation of mpatch.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
129 return outlen
29695
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
130
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
131 if modulepolicy not in policynocffi:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
132 try:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
133 from _mpatch_cffi import ffi, lib
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
134 except ImportError:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
135 if modulepolicy == 'cffi': # strict cffi import
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
136 raise
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
137 else:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
138 @ffi.def_extern()
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
139 def cffi_get_next_item(arg, pos):
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
140 all, bins = ffi.from_handle(arg)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
141 container = ffi.new("struct mpatch_flist*[1]")
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
142 to_pass = ffi.new("char[]", str(bins[pos]))
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
143 all.append(to_pass)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
144 r = lib.mpatch_decode(to_pass, len(to_pass) - 1, container)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
145 if r < 0:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
146 return ffi.NULL
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
147 return container[0]
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
148
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
149 def patches(text, bins):
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
150 lgt = len(bins)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
151 all = []
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
152 if not lgt:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
153 return text
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
154 arg = (all, bins)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
155 patch = lib.mpatch_fold(ffi.new_handle(arg),
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
156 lib.cffi_get_next_item, 0, lgt)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
157 if not patch:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
158 raise mpatchError("cannot decode chunk")
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
159 outlen = lib.mpatch_calcsize(len(text), patch)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
160 if outlen < 0:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
161 lib.mpatch_lfree(patch)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
162 raise mpatchError("inconsistency detected")
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
163 buf = ffi.new("char[]", outlen)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
164 if lib.mpatch_apply(buf, text, len(text), patch) < 0:
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
165 lib.mpatch_lfree(patch)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
166 raise mpatchError("error applying patches")
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
167 res = ffi.buffer(buf, outlen)[:]
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
168 lib.mpatch_lfree(patch)
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
169 return res
f2846d546645 mpatch: write a cffi version of mpatch.patches
Maciej Fijalkowski <fijall@gmail.com>
parents: 28861
diff changeset
170