##// END OF EJS Templates
mpatch: provide things that will be exported later with a prefixed name...
Maciej Fijalkowski -
r29692:6b3a8d03 default
parent child Browse files
Show More
@@ -32,25 +32,25 b''
32 static char mpatch_doc[] = "Efficient binary patching.";
32 static char mpatch_doc[] = "Efficient binary patching.";
33 static PyObject *mpatch_Error;
33 static PyObject *mpatch_Error;
34
34
35 struct frag {
35 struct mpatch_frag {
36 int start, end, len;
36 int start, end, len;
37 const char *data;
37 const char *data;
38 };
38 };
39
39
40 struct flist {
40 struct mpatch_flist {
41 struct frag *base, *head, *tail;
41 struct mpatch_frag *base, *head, *tail;
42 };
42 };
43
43
44 static struct flist *lalloc(ssize_t size)
44 static struct mpatch_flist *lalloc(ssize_t size)
45 {
45 {
46 struct flist *a = NULL;
46 struct mpatch_flist *a = NULL;
47
47
48 if (size < 1)
48 if (size < 1)
49 size = 1;
49 size = 1;
50
50
51 a = (struct flist *)malloc(sizeof(struct flist));
51 a = (struct mpatch_flist *)malloc(sizeof(struct mpatch_flist));
52 if (a) {
52 if (a) {
53 a->base = (struct frag *)malloc(sizeof(struct frag) * size);
53 a->base = (struct mpatch_frag *)malloc(sizeof(struct mpatch_frag) * size);
54 if (a->base) {
54 if (a->base) {
55 a->head = a->tail = a->base;
55 a->head = a->tail = a->base;
56 return a;
56 return a;
@@ -63,7 +63,7 b' static struct flist *lalloc(ssize_t size'
63 return NULL;
63 return NULL;
64 }
64 }
65
65
66 static void lfree(struct flist *a)
66 static void mpatch_lfree(struct mpatch_flist *a)
67 {
67 {
68 if (a) {
68 if (a) {
69 free(a->base);
69 free(a->base);
@@ -71,7 +71,7 b' static void lfree(struct flist *a)'
71 }
71 }
72 }
72 }
73
73
74 static ssize_t lsize(struct flist *a)
74 static ssize_t lsize(struct mpatch_flist *a)
75 {
75 {
76 return a->tail - a->head;
76 return a->tail - a->head;
77 }
77 }
@@ -79,9 +79,10 b' static ssize_t lsize(struct flist *a)'
79 /* move hunks in source that are less cut to dest, compensating
79 /* move hunks in source that are less cut to dest, compensating
80 for changes in offset. the last hunk may be split if necessary.
80 for changes in offset. the last hunk may be split if necessary.
81 */
81 */
82 static int gather(struct flist *dest, struct flist *src, int cut, int offset)
82 static int gather(struct mpatch_flist *dest, struct mpatch_flist *src, int cut,
83 int offset)
83 {
84 {
84 struct frag *d = dest->tail, *s = src->head;
85 struct mpatch_frag *d = dest->tail, *s = src->head;
85 int postend, c, l;
86 int postend, c, l;
86
87
87 while (s != src->tail) {
88 while (s != src->tail) {
@@ -124,9 +125,9 b' static int gather(struct flist *dest, st'
124 }
125 }
125
126
126 /* like gather, but with no output list */
127 /* like gather, but with no output list */
127 static int discard(struct flist *src, int cut, int offset)
128 static int discard(struct mpatch_flist *src, int cut, int offset)
128 {
129 {
129 struct frag *s = src->head;
130 struct mpatch_frag *s = src->head;
130 int postend, c, l;
131 int postend, c, l;
131
132
132 while (s != src->tail) {
133 while (s != src->tail) {
@@ -161,10 +162,11 b' static int discard(struct flist *src, in'
161
162
162 /* combine hunk lists a and b, while adjusting b for offset changes in a/
163 /* combine hunk lists a and b, while adjusting b for offset changes in a/
163 this deletes a and b and returns the resultant list. */
164 this deletes a and b and returns the resultant list. */
164 static struct flist *combine(struct flist *a, struct flist *b)
165 static struct mpatch_flist *combine(struct mpatch_flist *a,
166 struct mpatch_flist *b)
165 {
167 {
166 struct flist *c = NULL;
168 struct mpatch_flist *c = NULL;
167 struct frag *bh, *ct;
169 struct mpatch_frag *bh, *ct;
168 int offset = 0, post;
170 int offset = 0, post;
169
171
170 if (a && b)
172 if (a && b)
@@ -190,20 +192,20 b' static struct flist *combine(struct flis'
190 }
192 }
191
193
192 /* hold on to tail from a */
194 /* hold on to tail from a */
193 memcpy(c->tail, a->head, sizeof(struct frag) * lsize(a));
195 memcpy(c->tail, a->head, sizeof(struct mpatch_frag) * lsize(a));
194 c->tail += lsize(a);
196 c->tail += lsize(a);
195 }
197 }
196
198
197 lfree(a);
199 mpatch_lfree(a);
198 lfree(b);
200 mpatch_lfree(b);
199 return c;
201 return c;
200 }
202 }
201
203
202 /* decode a binary patch into a hunk list */
204 /* decode a binary patch into a hunk list */
203 static struct flist *decode(const char *bin, ssize_t len)
205 static struct mpatch_flist *mpatch_decode(const char *bin, ssize_t len)
204 {
206 {
205 struct flist *l;
207 struct mpatch_flist *l;
206 struct frag *lt;
208 struct mpatch_frag *lt;
207 int pos = 0;
209 int pos = 0;
208
210
209 /* assume worst case size, we won't have many of these lists */
211 /* assume worst case size, we won't have many of these lists */
@@ -227,7 +229,7 b' static struct flist *decode(const char *'
227 if (pos != len) {
229 if (pos != len) {
228 if (!PyErr_Occurred())
230 if (!PyErr_Occurred())
229 PyErr_SetString(mpatch_Error, "patch cannot be decoded");
231 PyErr_SetString(mpatch_Error, "patch cannot be decoded");
230 lfree(l);
232 mpatch_lfree(l);
231 return NULL;
233 return NULL;
232 }
234 }
233
235
@@ -236,10 +238,10 b' static struct flist *decode(const char *'
236 }
238 }
237
239
238 /* calculate the size of resultant text */
240 /* calculate the size of resultant text */
239 static ssize_t calcsize(ssize_t len, struct flist *l)
241 static ssize_t mpatch_calcsize(ssize_t len, struct mpatch_flist *l)
240 {
242 {
241 ssize_t outlen = 0, last = 0;
243 ssize_t outlen = 0, last = 0;
242 struct frag *f = l->head;
244 struct mpatch_frag *f = l->head;
243
245
244 while (f != l->tail) {
246 while (f != l->tail) {
245 if (f->start < last || f->end > len) {
247 if (f->start < last || f->end > len) {
@@ -258,9 +260,10 b' static ssize_t calcsize(ssize_t len, str'
258 return outlen;
260 return outlen;
259 }
261 }
260
262
261 static int apply(char *buf, const char *orig, ssize_t len, struct flist *l)
263 static int mpatch_apply(char *buf, const char *orig, ssize_t len,
264 struct mpatch_flist *l)
262 {
265 {
263 struct frag *f = l->head;
266 struct mpatch_frag *f = l->head;
264 int last = 0;
267 int last = 0;
265 char *p = buf;
268 char *p = buf;
266
269
@@ -283,7 +286,8 b' static int apply(char *buf, const char *'
283 }
286 }
284
287
285 /* recursively generate a patch of all bins between start and end */
288 /* recursively generate a patch of all bins between start and end */
286 static struct flist *fold(PyObject *bins, ssize_t start, ssize_t end)
289 static struct mpatch_flist *mpatch_fold(PyObject *bins, ssize_t start,
290 ssize_t end)
287 {
291 {
288 ssize_t len, blen;
292 ssize_t len, blen;
289 const char *buffer;
293 const char *buffer;
@@ -295,20 +299,20 b' static struct flist *fold(PyObject *bins'
295 return NULL;
299 return NULL;
296 if (PyObject_AsCharBuffer(tmp, &buffer, &blen))
300 if (PyObject_AsCharBuffer(tmp, &buffer, &blen))
297 return NULL;
301 return NULL;
298 return decode(buffer, blen);
302 return mpatch_decode(buffer, blen);
299 }
303 }
300
304
301 /* divide and conquer, memory management is elsewhere */
305 /* divide and conquer, memory management is elsewhere */
302 len = (end - start) / 2;
306 len = (end - start) / 2;
303 return combine(fold(bins, start, start + len),
307 return combine(mpatch_fold(bins, start, start + len),
304 fold(bins, start + len, end));
308 mpatch_fold(bins, start + len, end));
305 }
309 }
306
310
307 static PyObject *
311 static PyObject *
308 patches(PyObject *self, PyObject *args)
312 patches(PyObject *self, PyObject *args)
309 {
313 {
310 PyObject *text, *bins, *result;
314 PyObject *text, *bins, *result;
311 struct flist *patch;
315 struct mpatch_flist *patch;
312 const char *in;
316 const char *in;
313 char *out;
317 char *out;
314 Py_ssize_t len, outlen, inlen;
318 Py_ssize_t len, outlen, inlen;
@@ -326,11 +330,11 b' patches(PyObject *self, PyObject *args)'
326 if (PyObject_AsCharBuffer(text, &in, &inlen))
330 if (PyObject_AsCharBuffer(text, &in, &inlen))
327 return NULL;
331 return NULL;
328
332
329 patch = fold(bins, 0, len);
333 patch = mpatch_fold(bins, 0, len);
330 if (!patch)
334 if (!patch)
331 return NULL;
335 return NULL;
332
336
333 outlen = calcsize(inlen, patch);
337 outlen = mpatch_calcsize(inlen, patch);
334 if (outlen < 0) {
338 if (outlen < 0) {
335 result = NULL;
339 result = NULL;
336 goto cleanup;
340 goto cleanup;
@@ -341,12 +345,12 b' patches(PyObject *self, PyObject *args)'
341 goto cleanup;
345 goto cleanup;
342 }
346 }
343 out = PyBytes_AsString(result);
347 out = PyBytes_AsString(result);
344 if (!apply(out, in, inlen, patch)) {
348 if (!mpatch_apply(out, in, inlen, patch)) {
345 Py_DECREF(result);
349 Py_DECREF(result);
346 result = NULL;
350 result = NULL;
347 }
351 }
348 cleanup:
352 cleanup:
349 lfree(patch);
353 mpatch_lfree(patch);
350 return result;
354 return result;
351 }
355 }
352
356
General Comments 0
You need to be logged in to leave comments. Login now