6 * bdelta - Generate and apply binary deltas
8 * This library takes two strings containing binary data, and produces a
9 * "patch" that can be applied to the first one to produce the second one.
10 * It can be used to save bandwidth and disk space when many texts differing
11 * by a small number of bytes need to be transmitted or stored.
13 * Patches produced by this version of the library can be applied using future
14 * versions, but not past versions.
16 * bdelta implements the algorithm described in
17 * An O(ND) Difference Algorithm and Its Variations by Eugene W. Myers.
18 * Because its memory usage and expected running time are O(N + D^2),
19 * it works well only when the strings differ by a small number of bytes.
20 * This implementation stops trying when the strings differ by more than
21 * 1000 bytes, and falls back to producing a patch that simply emits the new
24 * Thus, bdelta does not save any space when given two strings that differ by
25 * more than 1000 bytes. This may be improved in a future version of the
29 * #include <ccan/bdelta/bdelta.h>
34 * static void gulp(const char *filename, void **data_out, size_t *size_out);
36 * static int usage(const char *prog)
40 * "Usage: %s diff <old> <new> > <patch>\n"
41 * " %s patch <old> <patch> > <new>\n",
47 * int main(int argc, char *argv[])
49 * void *old, *new_, *patch;
50 * size_t old_size, new_size, patch_size;
54 * return usage(argv[0]);
56 * if (strcmp(argv[1], "diff") == 0) {
57 * gulp(argv[2], &old, &old_size);
58 * gulp(argv[3], &new_, &new_size);
60 * rc = bdelta_diff(old, old_size, new_, new_size, &patch, &patch_size);
61 * if (rc != BDELTA_OK) {
62 * bdelta_perror("bdelta_diff", rc);
66 * if (fwrite(patch, 1, patch_size, stdout) != patch_size) {
70 * } else if (strcmp(argv[1], "patch") == 0) {
71 * gulp(argv[2], &old, &old_size);
72 * gulp(argv[3], &patch, &patch_size);
74 * rc = bdelta_patch(old, old_size, patch, patch_size, &new_, &new_size);
75 * if (rc != BDELTA_OK) {
76 * bdelta_perror("bdelta_patch", rc);
80 * if (fwrite(new_, 1, new_size, stdout) != new_size) {
85 * return usage(argv[0]);
94 * static void gulp(const char *filename, void **data_out, size_t *size_out)
96 * FILE *f = fopen(filename, "rb");
99 * char *data = malloc(alloc);
101 * if (f == NULL || data == NULL)
105 * size += fread(data + size, 1, alloc - size, f);
106 * if (size < alloc) {
111 * data = realloc(data, alloc *= 2);
116 * if (fclose(f) != 0)
125 * exit(EXIT_FAILURE);
128 * Author: Joey Adams <joeyadams3.14159@gmail.com>
132 int main(int argc, char *argv[])
134 /* Expect exactly one argument */
138 if (strcmp(argv[1], "depends") == 0) {