[evolution-ews/gnome-3-8] Merge incremental patch support from master
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/gnome-3-8] Merge incremental patch support from master
- Date: Mon, 10 Jun 2013 12:50:00 +0000 (UTC)
commit e3aeb612bdca2541a7548225c62e77e3916f2327
Author: David Woodhouse <David Woodhouse intel com>
Date: Wed May 15 15:34:49 2013 +0100
Merge incremental patch support from master
Synchronise with commit 9583a8a6d7d9a8dc4b05cae04349f134cb37c9dc
src/addressbook/lzx/ews-oal-decompress.c | 227 ++++++++++++++++++++++++-
src/addressbook/lzx/ews-oal-decompress.h | 4 +
src/addressbook/lzx/gal-lzx-decompress-test.c | 22 ++-
3 files changed, 244 insertions(+), 9 deletions(-)
---
diff --git a/src/addressbook/lzx/ews-oal-decompress.c b/src/addressbook/lzx/ews-oal-decompress.c
index 6b204dd..96872a2 100644
--- a/src/addressbook/lzx/ews-oal-decompress.c
+++ b/src/addressbook/lzx/ews-oal-decompress.c
@@ -167,7 +167,7 @@ oal_decompress_v4_full_detail_file (const gchar *filename,
}
output = fopen (output_filename, "wb");
- if (!input) {
+ if (!output) {
g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "unable to open the output file");
ret = FALSE;
goto exit;
@@ -221,14 +221,13 @@ oal_decompress_v4_full_detail_file (const gchar *filename,
window_bits = 25;
lzs = lzxd_init (input, output, window_bits,
- 0, 16, lzx_b->ucomp_size, 1);
+ 0, 4096, lzx_b->ucomp_size, 1);
if (!lzs) {
g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "decompression
failed (lzxd_init)");
ret = FALSE;
goto exit;
}
-
- if (lzxd_decompress (lzs, lzs->length) != LZX_ERR_OK) {
+ if (lzxd_decompress (lzs, lzx_b->ucomp_size) != LZX_ERR_OK) {
g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "decompression
failed (lzxd_decompress)");
ret = FALSE;
goto exit;
@@ -261,3 +260,223 @@ exit:
return ret;
}
+
+typedef struct {
+ guint32 h_version;
+ guint32 l_version;
+ guint32 max_block_size;
+ guint32 source_size;
+ guint32 target_size;
+ guint32 source_crc;
+ guint32 target_crc;
+} LzxPatchHeader;
+
+typedef struct {
+ guint32 patch_size;
+ guint32 target_size;
+ guint32 source_size;
+ guint32 crc;
+} LzxPatchBlockHeader;
+
+
+static LzxPatchHeader *
+read_patch_headers (FILE *input,
+ GError **error)
+{
+ LzxPatchHeader *lzx_h;
+ gboolean success;
+
+ lzx_h = g_new0 (LzxPatchHeader, 1);
+
+ success = read_uint32 (input, &lzx_h->h_version);
+ if (!success)
+ goto exit;
+ success = read_uint32 (input, &lzx_h->l_version);
+ if (!success)
+ goto exit;
+
+ if (lzx_h->h_version != 0x00000003 || lzx_h->l_version != 0x00000002) {
+ g_free (lzx_h);
+ /* set the right domain later */
+ g_set_error_literal (error, g_quark_from_string ("lzx"), 1, "wrong version header");
+ return NULL;
+ }
+
+ success = read_uint32 (input, &lzx_h->max_block_size);
+ if (!success)
+ goto exit;
+ success = read_uint32 (input, &lzx_h->source_size);
+ if (!success)
+ goto exit;
+ success = read_uint32 (input, &lzx_h->target_size);
+ if (!success)
+ goto exit;
+ success = read_uint32 (input, &lzx_h->source_crc);
+ if (!success)
+ goto exit;
+ success = read_uint32 (input, &lzx_h->target_crc);
+ if (!success)
+ goto exit;
+
+exit:
+ if (!success) {
+ /* set the right domain later */
+ g_set_error_literal (error, g_quark_from_string ("lzx"), 1, "Unable to read lzx main header");
+
+ g_free (lzx_h);
+ lzx_h = NULL;
+ }
+
+ return lzx_h;
+}
+
+static LzxPatchBlockHeader *
+read_patch_block_header (FILE *input,
+ GError **error)
+{
+ LzxPatchBlockHeader *lzx_b;
+ gboolean success;
+
+ lzx_b = g_new0 (LzxPatchBlockHeader, 1);
+
+ success = read_uint32 (input, &lzx_b->patch_size);
+ if (!success)
+ goto exit;
+
+ success = read_uint32 (input, &lzx_b->target_size);
+ if (!success)
+ goto exit;
+
+ success = read_uint32 (input, &lzx_b->source_size);
+ if (!success)
+ goto exit;
+
+ success = read_uint32 (input, &lzx_b->crc);
+
+exit:
+ if (!success) {
+ /* set the right domain later */
+ g_set_error_literal (error, g_quark_from_string ("lzx"), 1, "Unable to read lzx block
header");
+
+ g_free (lzx_b);
+ lzx_b = NULL;
+ }
+
+ return lzx_b;
+}
+
+gboolean
+oal_apply_binpatch (const gchar *filename, const gchar *orig_filename,
+ const gchar *output_filename,
+ GError **error)
+{
+ LzxPatchHeader *lzx_h = NULL;
+ guint total_decomp_size = 0;
+ FILE *input = NULL, *output = NULL, *orig_input = NULL;
+ gboolean ret = TRUE;
+ GError *err = NULL;
+
+ input = fopen (filename, "rb");
+ if (!input) {
+ g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "unable to open the input file");
+ ret = FALSE;
+ goto exit;
+ }
+
+ orig_input = fopen (orig_filename, "rb");
+ if (!orig_input) {
+ g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "unable to open the reference
input file");
+ ret = FALSE;
+ goto exit;
+ }
+
+ output = fopen (output_filename, "wb");
+ if (!output) {
+ g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "unable to open the output file");
+ ret = FALSE;
+ goto exit;
+ }
+
+ lzx_h = read_patch_headers (input, &err);
+ if (!lzx_h) {
+ ret = FALSE;
+ goto exit;
+ }
+
+ /* TODO decompressing multiple lzx_blocks has not been tested yet. Will need to get a setup and test
it. */
+ do {
+ LzxPatchBlockHeader *lzx_b;
+ struct lzxd_stream *lzs;
+ goffset offset;
+ guint ref_size, window_bits;
+
+ lzx_b = read_patch_block_header (input, &err);
+ if (err) {
+ printf("err block header\n");
+ ret = FALSE;
+ goto exit;
+ }
+
+ /* note the file offset */
+ offset = ftell(input);
+
+ /* The window size should be the smallest power of two
+ between 2^17 and 2^25 that is greater than or equal
+ to the sum of the size of the reference data
+ rounded up to a multiple of 32768 and the size of
+ the subject data. */
+ ref_size = (lzx_b->source_size + 32767) & ~32767;
+ window_bits = g_bit_nth_msf(ref_size + lzx_b->target_size - 1, -1) + 1;
+
+ if (window_bits < 17)
+ window_bits = 17;
+ else if (window_bits > 25)
+ window_bits = 25;
+
+ lzs = lzxd_init (input, output, window_bits,
+ 0, 4096, lzx_b->target_size, 1);
+ if (!lzs) {
+ g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "decompression failed
(lzxd_init)");
+ ret = FALSE;
+ goto exit;
+ }
+ if (lzxd_set_reference_data(lzs, orig_input, lzx_b->source_size)) {
+ g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "decompression failed
(lzxd_set_reference_data)");
+ ret = FALSE;
+ goto exit;
+ }
+ if (lzxd_decompress (lzs, lzs->length) != LZX_ERR_OK) {
+ g_set_error_literal (&err, g_quark_from_string ("lzx"), 1, "decompression failed
(lzxd_decompress)");
+ ret = FALSE;
+ goto exit;
+ }
+
+ /* Set the fp to beggining of next block. This is a HACK, looks like decompress reads beyond
the block.
+ * Since we can identify the next block start from block header, we just reset the offset */
+ offset += lzx_b->patch_size;
+ fseek (input, offset, SEEK_SET);
+
+ total_decomp_size += lzx_b->target_size;
+ g_free (lzx_b);
+ } while (total_decomp_size < lzx_h->target_size);
+
+exit:
+ if (input)
+ fclose (input);
+
+ if (orig_input)
+ fclose (orig_input);
+
+ if (output)
+ fclose (output);
+
+ if (err) {
+ ret = FALSE;
+ g_propagate_error (error, err);
+ g_unlink (output_filename);
+ }
+
+ g_free (lzx_h);
+
+ return ret;
+}
diff --git a/src/addressbook/lzx/ews-oal-decompress.h b/src/addressbook/lzx/ews-oal-decompress.h
index cf07b58..c9b6af4 100644
--- a/src/addressbook/lzx/ews-oal-decompress.h
+++ b/src/addressbook/lzx/ews-oal-decompress.h
@@ -27,5 +27,9 @@
gboolean
oal_decompress_v4_full_detail_file (const gchar *filename, const gchar *output_filename, GError **error);
+gboolean
+oal_apply_binpatch (const gchar *filename, const gchar *orig_filename,
+ const gchar *output_filename,
+ GError **error);
#endif
diff --git a/src/addressbook/lzx/gal-lzx-decompress-test.c b/src/addressbook/lzx/gal-lzx-decompress-test.c
index 213aad3..9185ca8 100644
--- a/src/addressbook/lzx/gal-lzx-decompress-test.c
+++ b/src/addressbook/lzx/gal-lzx-decompress-test.c
@@ -1,19 +1,31 @@
#include "ews-oal-decompress.h"
+#include <glib.h>
gint
-main (gint argc,
- gchar *argv[])
+main (gint argc, gchar *argv[])
{
- if (argc != 3) {
+ GError *error = NULL;
+
+ if (argc != 3 && argc != 4) {
g_print ("Pass an lzx file and an output filename as argument \n");
return -1;
}
- if (oal_decompress_v4_full_detail_file (argv[1], argv[2], NULL))
+ if (argc == 4) {
+ g_print("Applying binary patch %s to %s to create %s\n",
+ argv[1], argv[2], argv[3]);
+ if (oal_apply_binpatch(argv[1], argv[2], argv[3], &error))
+ g_print("Successfully applied\n");
+ else
+ g_print("apply failed: %s\n", error->message);
+ } else
+
+
+ if (oal_decompress_v4_full_detail_file (argv[1], argv[2], &error))
g_print ("Successfully decompressed \n");
else
- g_print ("decompression failed \n");
+ g_print ("decompression failed: %s\n", error->message);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]