352 cleanup: |
352 cleanup: |
353 lfree(patch); |
353 lfree(patch); |
354 return result; |
354 return result; |
355 } |
355 } |
356 |
356 |
|
357 /* calculate size of a patched file directly */ |
|
358 static PyObject * |
|
359 patchedsize(PyObject *self, PyObject *args) |
|
360 { |
|
361 long orig, start, end, len, outlen = 0, last = 0; |
|
362 int patchlen; |
|
363 char *bin, *binend; |
|
364 char decode[12]; /* for dealing with alignment issues */ |
|
365 |
|
366 if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen)) |
|
367 return NULL; |
|
368 |
|
369 binend = bin + patchlen; |
|
370 |
|
371 while (bin < binend) { |
|
372 memcpy(decode, bin, 12); |
|
373 start = ntohl(*(uint32_t *)decode); |
|
374 end = ntohl(*(uint32_t *)(decode + 4)); |
|
375 len = ntohl(*(uint32_t *)(decode + 8)); |
|
376 bin += 12 + len; |
|
377 outlen += start - last; |
|
378 last = end; |
|
379 outlen += len; |
|
380 } |
|
381 |
|
382 if (bin != binend) { |
|
383 if (!PyErr_Occurred()) |
|
384 PyErr_SetString(mpatch_Error, "patch cannot be decoded"); |
|
385 return NULL; |
|
386 } |
|
387 |
|
388 outlen += orig - last; |
|
389 return Py_BuildValue("l", outlen); |
|
390 } |
|
391 |
357 static PyMethodDef methods[] = { |
392 static PyMethodDef methods[] = { |
358 {"patches", patches, METH_VARARGS, "apply a series of patches\n"}, |
393 {"patches", patches, METH_VARARGS, "apply a series of patches\n"}, |
|
394 {"patchedsize", patchedsize, METH_VARARGS, "calculed patched size\n"}, |
359 {NULL, NULL} |
395 {NULL, NULL} |
360 }; |
396 }; |
361 |
397 |
362 PyMODINIT_FUNC |
398 PyMODINIT_FUNC |
363 initmpatch(void) |
399 initmpatch(void) |