Permalink
Browse files

Initial BDelta project taken from BDelta version 0.1.0 + code style c…

…hanges.

git-svn-id: svn://deltup.org/bdelta@1 0b3c7260-62b7-4bd3-8502-661595b7e89c
  • Loading branch information...
0 parents commit 251c9189dce4218d62713ee48c513949ad238e59 @jjwhitney committed May 13, 2008
Showing with 859 additions and 0 deletions.
  1. +2 −0 Changelog
  2. +12 −0 Format
  3. +4 −0 README
  4. +19 −0 src/Makefile
  5. +152 −0 src/bdelta.cpp
  6. +36 −0 src/bdelta.h
  7. +105 −0 src/bpatch.cpp
  8. +82 −0 src/container.h
  9. +53 −0 src/file.h
  10. +394 −0 src/libbdelta.cpp
@@ -0,0 +1,2 @@
+19 July 2003; John Whitney <jjw@linuxmail.org> :
+ Initial release of bdelta
12 Format
@@ -0,0 +1,12 @@
+(All numbers are stored in little-endian format)
+char[3] magic "BDT"
+unsigned short version;
+unsigned char intsize; (remaining ints are all unsigned and "intsize" bytes)
+unsigned file 1 size
+unsigned file 2 size
+unsigned number of matches
+for (number of matches) {
+ unsigned match relative location 1 (this value can represent a negative)
+ unsigned match relative location 2
+ unsigned match size
+}
4 README
@@ -0,0 +1,4 @@
+Author: John Whitney (jjw@deltup.org)
+License: GNU General Public License v2
+
+ BDelta is an advanced delta creator, patcher, and library. This code is still beta quality, so don't expect too much! It might not even produce correct deltas in some cases. You can find the output format in file "Format"
@@ -0,0 +1,19 @@
+DESTDIR=
+PREFIX=/usr
+BINDIR=$(PREFIX)/bin
+LIBDIR=${PREFIX}/lib
+CXXFLAGS=-O2
+
+all: bpatch libbdelta.so bdelta
+libbdelta.so: libbdelta.cpp container.h
+ ${CC} -shared -fPIC ${CXXFLAGS} $< -o $@
+bdelta: bdelta.cpp container.h file.h
+ ${CC} $< -o $@ ${CXXFLAGS} -L. -lbdelta -lstdc++
+bpatch: bpatch.cpp file.h
+% : %.cpp
+ ${CC} $< -o $@ ${CXXFLAGS} -lstdc++
+install: libbdelta.so bdelta bpatch
+ mkdir -p $(DESTDIR)$(BINDIR)
+ install -m 755 libbdelta.so $(DESTDIR)$(LIBDIR)
+ install -m 755 bdelta $(DESTDIR)$(BINDIR)
+ install -m 755 bpatch $(DESTDIR)$(BINDIR)
@@ -0,0 +1,152 @@
+/* Copyright (C) 2003-2008 John Whitney
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Author: John Whitney <jjw@deltup.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bdelta.h"
+#include "file.h"
+
+const int BUFNUM=16;
+class Buffered_File {
+ FILE *f;
+ char *buf[BUFNUM];
+ unsigned bufplace[BUFNUM];
+ int bufsize;
+public:
+ Buffered_File(char *fname, unsigned maxread) {
+ f = fopen(fname, "rb");
+ bufsize=maxread;
+ for (int i = 0; i < BUFNUM; ++i) {
+ buf[i] = new char[bufsize];
+ bufplace[i] = 0;
+ }
+ }
+ ~Buffered_File() {
+ for (int i = 0; i < BUFNUM; ++i)
+ delete buf[i];
+ fclose(f);
+ }
+ void *read(unsigned place, unsigned num) {
+ for (int i = 0; i < BUFNUM; ++i)
+ if (bufplace[i] && place>bufplace[i] && place+num<bufplace[i]+bufsize)
+ return buf[i]+place-bufplace[i];
+ char *lastbuf = buf[BUFNUM-1];
+ for (int i = BUFNUM-1; i > 0; --i) {
+ buf[i] = buf[i-1];
+ bufplace[i] = bufplace[i-1];
+ }
+ buf[0]=lastbuf;
+ bufplace[0]=place;
+ fseek(f, place, SEEK_SET);
+ fread(buf[0], 1, bufsize, f);
+ return buf[0];
+ }
+};
+
+Buffered_File *f1, *f2;
+
+void *f1_read(unsigned place, unsigned num) {
+ return f1->read(place, num);
+}
+void *f2_read(unsigned place, unsigned num) {
+ return f2->read(place, num);
+}
+
+int main(int argc, char **argv) {
+ if (argc!=4) {
+ printf("needs two files to compare + output file:\n");
+ printf("delta oldfile newfile patchfile\n");
+ exit(1);
+ }
+ if (!fileExists(argv[1]) || !fileExists(argv[2])) {
+ printf("one of the input files does not exist\n");
+ exit(1);
+ }
+ unsigned size = getLenOfFile(argv[1]);
+ unsigned size2 = getLenOfFile(argv[2]);
+ f1 = new Buffered_File(argv[1], 4096);
+ f2 = new Buffered_File(argv[2], 4096);
+
+ void *b = bdelta_init_alg(size, size2, f1_read, f2_read);
+ int nummatches;
+ for (int i = 512; i >= 16; i/=2)
+ nummatches = bdelta_pass(b, i);
+
+ unsigned copyloc1[nummatches+1];
+ unsigned copyloc2[nummatches+1];
+ unsigned copynum[nummatches+1];
+
+ FILE *fout = fopen(argv[3], "wb");
+ if (!fout) {
+ printf("couldn't open output file\n");
+ exit(1);
+ }
+
+ char *magic = "BDT";
+ fwrite(magic, 1, 3, fout);
+ unsigned short version = 1;
+ write_word(fout, version);
+ unsigned char intsize = 4;
+ fwrite(&intsize, 1, 1, fout);
+ write_dword(fout, size);
+ write_dword(fout, size2);
+ write_dword(fout, nummatches);
+
+ unsigned lastp1 = 0,
+ lastp2 = 0;
+ for (int i = 0; i < nummatches; ++i) {
+ unsigned p1, p2, num;
+ bdelta_getMatch(b, i, &p1, &p2, &num);
+ // printf("%*x, %*x, %*x, %*x\n", 10, p1, 10, p2, 10, num, 10, p2-lastp2);
+ copyloc1[i] = p1-lastp1;
+ write_dword(fout, copyloc1[i]);
+ copyloc2[i] = p2-lastp2;
+ write_dword(fout, copyloc2[i]);
+ copynum[i] = num;
+ write_dword(fout, copynum[i]);
+ lastp1=p1+num;
+ lastp2=p2+num;
+ }
+ if (size2!=lastp2) {
+ copyloc1[nummatches]=0; copynum[nummatches]=0;
+ copyloc2[nummatches]=size2-lastp2;
+ ++nummatches;
+ }
+
+// write_unsigned_list(adds, nummatches+1, fout);
+// write_unsigned_list(copynum, nummatches, fout);
+// write_signed_list(copyloc, nummatches, fout);
+ unsigned fp = 0;
+ for (int i = 0; i < nummatches; ++i) {
+ unsigned num = copyloc2[i];
+ while (num>0) {
+ unsigned towrite = num;
+ if (towrite>4096) towrite=4096;
+ void *buf = f2->read(fp, towrite);
+ fwrite(buf, 1, towrite, fout);
+ num-=towrite;
+ fp+=towrite;
+ }
+ // fp+=copyloc2[i];
+ if (i!=nummatches) fp+=copynum[i];
+ }
+
+ fclose(fout);
+
+ bdelta_done_alg(b);
+
+ delete f1;
+ delete f2;
+}
@@ -0,0 +1,36 @@
+/* Copyright (C) 2003-2008 John Whitney
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Author: John Whitney <jjw@deltup.org>
+ */
+
+// bdelta uses two callback functions to supply it with the
+// data to be compared, callback functions must keep data
+// incorrupt until two more calls for data
+typedef void *(*bdelta_readCallback)(unsigned place, unsigned num);
+
+void *bdelta_init_alg(unsigned f1_size, unsigned f2_size,
+ bdelta_readCallback f1, bdelta_readCallback f2);
+void bdelta_done_alg(void *instance);
+
+//returns the total number of matches found
+unsigned bdelta_pass(void *instance, unsigned blocksize);
+
+void bdelta_getMatch(void *instance, unsigned matchNum,
+ unsigned *p1, unsigned *p2, unsigned *num);
+
+int bdelta_getError(void *instance);
+
+const int
+ BDELTA_OK = 0,
+ BDELTA_MEM_ERROR = -1,
+ BDELTA_READ_ERROR = -2;
@@ -0,0 +1,105 @@
+/* Copyright (C) 2003-2008 John Whitney
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Author: John Whitney <jjw@deltup.org>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "file.h"
+
+bool copy_bytes_to_file(FILE *infile, FILE *outfile, unsigned numleft) {
+ size_t numread;
+ do {
+ char buf[1024];
+ numread = fread(buf, 1, numleft>1024?1024:numleft, infile);
+ if (fwrite(buf, 1, numread, outfile) != numread) {
+ printf("Could not write temporary data. Possibly out of space\n");
+ return false;
+ }
+ numleft-=numread;
+ } while (numleft && !(numread < 1024 && numleft));
+ return (numleft==0);
+}
+
+int main(int argc, char **argv) {
+ if (argc!=4) {
+ printf("needs a reference file, file to output, and patchfile:\n");
+ printf("delta oldfile newfile patchfile\n");
+ return 1;
+ }
+
+ if (!fileExists(argv[1]) || !fileExists(argv[3])) {
+ printf("one of the input files does not exist\n");
+ return 1;
+ }
+
+ FILE *patchfile = fopen(argv[3], "rb");
+ char magic[3];
+ fread(magic, 1, 3, patchfile);
+ if (strncmp(magic, "BDT", 3)) {
+ printf("Given file is not a recognized patchfile\n");
+ return 1;
+ }
+ unsigned short version = read_word(patchfile);
+ if (version!=1) {
+ printf("unsupported patch version\n");
+ return 1;
+ }
+ char intsize;
+ fread(&intsize, 1, 1, patchfile);
+ if (intsize!=4) {
+ printf("unsupported file pointer size\n");
+ return 1;
+ }
+ unsigned size1 = read_dword(patchfile),
+ size2 = read_dword(patchfile);
+
+ unsigned nummatches = read_dword(patchfile);
+
+ unsigned
+ *copyloc1 = new unsigned[nummatches+1],
+ *copyloc2 = new unsigned[nummatches+1],
+ *copynum = new unsigned[nummatches+1];
+
+ for (int i = 0; i < nummatches; ++i) {
+ copyloc1[i] = read_dword(patchfile);
+ copyloc2[i] = read_dword(patchfile);
+ copynum[i] = read_dword(patchfile);
+ size2-=copyloc2[i]+copynum[i];
+ }
+ if (size2) {
+ copyloc1[nummatches]=0; copynum[nummatches]=0;
+ copyloc2[nummatches]=size2;
+ ++nummatches;
+ }
+
+ FILE *ref = fopen(argv[1], "rb");
+ FILE *outfile = fopen(argv[2], "wb");
+
+ char *buf;
+ for (int i = 0; i < nummatches; ++i) {
+ if (!copy_bytes_to_file(patchfile, outfile, copyloc2[i])) {
+ printf("Error. patchfile is truncated\n");
+ return -1;
+ }
+
+ int copyloc = copyloc1[i];
+ fseek(ref, copyloc, SEEK_CUR);
+
+ if (!copy_bytes_to_file(ref, outfile, copynum[i])) {
+ printf("Error while copying from reference file\n");
+ return -1;
+ }
+ }
+ return 0;
+}
Oops, something went wrong.

0 comments on commit 251c918

Please sign in to comment.