5 * bdelta - Generate and apply binary deltas
7 * This library takes two strings containing binary data, and produces a
8 * "patch" that can be applied to the first one to produce the second one.
9 * It can be used to save bandwidth and disk space when many texts differing
10 * by a small number of bytes need to be transmitted or stored.
12 * Patches produced by this version of the library can be applied using future
13 * versions, but not past versions.
15 * bdelta implements the algorithm described in
16 * An O(ND) Difference Algorithm and Its Variations by Eugene W. Myers.
17 * Because its memory usage and expected running time are O(N + D^2),
18 * it works well only when the strings differ by a small number of bytes.
19 * This implementation stops trying when the strings differ by more than
20 * 1000 bytes, and falls back to producing a patch that simply emits the new
23 * Thus, bdelta does not save any space when given two strings that differ by
24 * more than 1000 bytes. This may be improved in a future version of the
28 * #include <ccan/bdelta/bdelta.h>
33 * static void gulp(const char *filename, void **data_out, size_t *size_out);
35 * static int usage(const char *prog)
39 * "Usage: %s diff <old> <new> > <patch>\n"
40 * " %s patch <old> <patch> > <new>\n",
46 * int main(int argc, char *argv[])
48 * void *old, *new_, *patch;
49 * size_t old_size, new_size, patch_size;
53 * return usage(argv[0]);
55 * if (strcmp(argv[1], "diff") == 0) {
56 * gulp(argv[2], &old, &old_size);
57 * gulp(argv[3], &new_, &new_size);
59 * rc = bdelta_diff(old, old_size, new_, new_size, &patch, &patch_size);
60 * if (rc != BDELTA_OK) {
61 * bdelta_perror("bdelta_diff", rc);
65 * if (fwrite(patch, 1, patch_size, stdout) != patch_size) {
69 * } else if (strcmp(argv[1], "patch") == 0) {
70 * gulp(argv[2], &old, &old_size);
71 * gulp(argv[3], &patch, &patch_size);
73 * rc = bdelta_patch(old, old_size, patch, patch_size, &new_, &new_size);
74 * if (rc != BDELTA_OK) {
75 * bdelta_perror("bdelta_patch", rc);
79 * if (fwrite(new_, 1, new_size, stdout) != new_size) {
84 * return usage(argv[0]);
93 * static void gulp(const char *filename, void **data_out, size_t *size_out)
95 * FILE *f = fopen(filename, "rb");
98 * char *data = malloc(alloc);
100 * if (f == NULL || data == NULL)
104 * size += fread(data + size, 1, alloc - size, f);
105 * if (size < alloc) {
110 * data = realloc(data, alloc *= 2);
115 * if (fclose(f) != 0)
124 * exit(EXIT_FAILURE);
127 * Author: Joey Adams <joeyadams3.14159@gmail.com>
131 int main(int argc, char *argv[])
133 /* Expect exactly one argument */
137 if (strcmp(argv[1], "depends") == 0) {