annotate mercurial/pure/mpatch.py @ 29925:1619efcde9a4

manifest: make one use of _mancache avoid manifestctxs In a future patch we will change manifestctx and treemanifestctx to no longer derive from manifestdict and treemanifest, respectively. This means that consumers of the _mancache will now need to be aware of the different between the two, until we get rid of the manifest entirely and the _mancache becomes only filled with ctxs. This fixes one case of it that can be fixed by using the other cache. Future patches will address the others uses using the upcoming manifestctx.read() function.
author Durham Goode <durham@fb.com>
date Mon, 12 Sep 2016 14:29:09 -0700
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