summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Endsley <mendsley@gmail.com>2012-05-13 23:11:32 -0700
committerMatthew Endsley <mendsley@gmail.com>2012-05-14 01:04:25 -0700
commit9e42fa58dbb3847ae71cfbba0800184b755f0c9e (patch)
treea4dc8f81d8b23e7a9e6edb317f9373bae604c99a
parent025c1b0195d4b63503385d0ef7a0c9118a96c922 (diff)
downloadbsdiff-9e42fa58dbb3847ae71cfbba0800184b755f0c9e.tar.gz
interleaving control, diff and extra data
-rw-r--r--bsdiff.c87
-rw-r--r--bspatch.c80
2 files changed, 37 insertions, 130 deletions
diff --git a/bsdiff.c b/bsdiff.c
index 88936aa..c4da099 100644
--- a/bsdiff.c
+++ b/bsdiff.c
@@ -249,13 +249,11 @@ static int bsdiff_internal(const struct bsdiff_request req)
{
int64_t *I,*V;
int64_t scan,pos,len;
- int64_t compresslen, filelen;
int64_t lastscan,lastpos,lastoffset;
int64_t oldscore,scsc;
int64_t s,Sf,lenf,Sb,lenb;
int64_t overlap,Ss,lens;
int64_t i;
- int64_t dblen,eblen;
uint8_t *db,*eb;
uint8_t buf[8 * 3];
@@ -267,22 +265,6 @@ static int bsdiff_internal(const struct bsdiff_request req)
db = req.db;
eb = req.eb;
- dblen=0;
- eblen=0;
- filelen=0;
-
- /* Header is
- 0 8 "BSDIFF40"
- 8 8 length of bzip2ed ctrl block
- 16 8 length of bzip2ed diff block
- 24 8 length of new file */
- /* File is
- 0 32 Header
- 32 ?? Bzip2ed ctrl block
- ?? ?? Bzip2ed diff block
- ?? ?? Bzip2ed extra block */
- memcpy(req.header->signature,"BSDIFF40",sizeof(req.header->signature));
- req.header->new_file_length = req.newsize;
/* Compute the differences, writing ctrl as we go */
scan=0;len=0;
@@ -340,56 +322,31 @@ static int bsdiff_internal(const struct bsdiff_request req)
};
for(i=0;i<lenf;i++)
- db[dblen+i]=req.new[lastscan+i]-req.old[lastpos+i];
+ db[i]=req.new[lastscan+i]-req.old[lastpos+i];
for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
- eb[eblen+i]=req.new[lastscan+lenf+i];
-
- dblen+=lenf;
- eblen+=(scan-lenb)-(lastscan+lenf);
+ eb[i]=req.new[lastscan+lenf+i];
offtout(lenf,buf);
offtout((scan-lenb)-(lastscan+lenf),buf+8);
offtout((pos-lenb)-(lastpos+lenf),buf+16);
- compresslen = writedata(req.stream, buf, sizeof(buf));
- if (compresslen == -1)
+ /* Write control data */
+ if (writedata(req.stream, buf, sizeof(buf)))
+ return -1;
+
+ /* Write diff data */
+ if (writedata(req.stream, db, lenf))
+ return -1;
+
+ /* Write extra data */
+ if (writedata(req.stream, eb, (scan-lenb)-(lastscan+lenf)))
return -1;
- filelen += compresslen;
lastscan=scan-lenb;
lastpos=pos-lenb;
lastoffset=pos-scan;
};
};
- compresslen = req.stream->finish(req.stream);
- if (compresslen == -1)
- return -1;
- filelen += compresslen;
-
- /* Compute size of compressed ctrl data */
- req.header->ctrl_block_length = filelen;
-
- /* Write compressed diff data */
- filelen = 0;
- compresslen = writedata(req.stream, db, dblen);
- if (compresslen == -1)
- return -1;
- filelen += compresslen;
- compresslen = req.stream->finish(req.stream);
- if (compresslen == -1)
- return -1;
- filelen += compresslen;
-
- /* Compute size of compressed diff data */
- req.header->diff_block_length = filelen;
-
- /* Write compressed extra data */
- compresslen = writedata(req.stream, eb, eblen);
- if (compresslen == -1)
- return -1;
- compresslen = req.stream->finish(req.stream);
- if (compresslen == -1)
- return -1;
return 0;
}
@@ -447,7 +404,6 @@ static int bz2_write(struct bsdiff_stream* stream, const void* buffer, int size)
bz_stream* bz2;
FILE* pf;
int err;
- int totalwritten;
char compress_buffer[4096];
bz2 = (bz_stream*)stream->opaque;
@@ -462,7 +418,6 @@ static int bz2_write(struct bsdiff_stream* stream, const void* buffer, int size)
bz2->next_in = (char*)buffer;
bz2->avail_in = size;
- totalwritten = 0;
for (;;)
{
bz2->next_out = compress_buffer;
@@ -475,19 +430,16 @@ static int bz2_write(struct bsdiff_stream* stream, const void* buffer, int size)
const size_t written = sizeof(compress_buffer) - bz2->avail_out;
if (written != fwrite(compress_buffer, 1, written, pf))
return -1;
-
- totalwritten += written;
}
if (bz2->avail_in == 0)
- return totalwritten;
+ return 0;
}
}
static int bz2_finish(struct bsdiff_stream* stream)
{
int err;
- int totalwritten;
bz_stream* bz2;
FILE* pf;
char compress_buffer[4096];
@@ -495,7 +447,6 @@ static int bz2_finish(struct bsdiff_stream* stream)
bz2 = (bz_stream*)stream->opaque;
pf = (FILE*)bz2->opaque;
- totalwritten = 0;
for (;;)
{
bz2->next_out = compress_buffer;
@@ -510,8 +461,6 @@ static int bz2_finish(struct bsdiff_stream* stream)
const size_t written = sizeof(compress_buffer) - bz2->avail_out;
if (written != fwrite(compress_buffer, 1, written, pf))
return -1;
-
- totalwritten += written;
}
if (BZ_STREAM_END == err)
@@ -519,7 +468,7 @@ static int bz2_finish(struct bsdiff_stream* stream)
}
BZ2_bzCompressEnd(bz2);
- return totalwritten;
+ return 0;
}
int main(int argc,char *argv[])
@@ -573,6 +522,14 @@ int main(int argc,char *argv[])
if (bsdiff(old, oldsize, new, newsize, &stream, &header))
err(1, "bsdiff");
+ if (stream.finish(&stream))
+ err(1, "stream.finish");
+
+ memcpy(header.signature, "BSDIFF40", sizeof(header.signature));
+ header.ctrl_block_length = 0;
+ header.diff_block_length = 0;
+ header.new_file_length = newsize;
+
if (fseek(pf, 0, SEEK_SET) ||
fwrite(&header.signature, sizeof(header.signature), 1, pf) != 1)
err(1, "Failed to write header");
diff --git a/bspatch.c b/bspatch.c
index 3b7eab4..423283b 100644
--- a/bspatch.c
+++ b/bspatch.c
@@ -43,9 +43,7 @@ struct bspatch_request
int64_t oldsize;
uint8_t* new;
int64_t newsize;
- struct bspatch_stream control;
- struct bspatch_stream diff;
- struct bspatch_stream extra;
+ struct bspatch_stream stream;
};
int bspatch(const struct bspatch_request req);
@@ -82,7 +80,7 @@ int bspatch(const struct bspatch_request req)
while(newpos<req.newsize) {
/* Read control data */
for(i=0;i<=2;i++) {
- lenread = req.control.read(&req.control, buf, 8);
+ lenread = req.stream.read(&req.stream, buf, 8);
if (lenread != 8)
return -1;
ctrl[i]=offtin(buf);
@@ -93,7 +91,7 @@ int bspatch(const struct bspatch_request req)
return -1;
/* Read diff string */
- lenread = req.diff.read(&req.diff, req.new + newpos, ctrl[0]);
+ lenread = req.stream.read(&req.stream, req.new + newpos, ctrl[0]);
if (lenread != ctrl[0])
return -1;
@@ -111,7 +109,7 @@ int bspatch(const struct bspatch_request req)
return -1;
/* Read extra string */
- lenread = req.extra.read(&req.extra, req.new + newpos, ctrl[1]);
+ lenread = req.stream.read(&req.stream, req.new + newpos, ctrl[1]);
if (lenread != ctrl[1])
return -1;
@@ -185,19 +183,14 @@ int main(int argc,char * argv[])
{
FILE * f;
int fd;
- int cbz2err, dbz2err, ebz2err;
+ int bz2err;
ssize_t bzctrllen,bzdatalen;
uint8_t header[32];
uint8_t *old;
- FILE *cpf, *dpf, *epf;
struct bspatch_request req;
- struct bspatch_bz2_buffer cbz2;
- struct bspatch_bz2_buffer dbz2;
- struct bspatch_bz2_buffer ebz2;
+ struct bspatch_bz2_buffer bz2;
- memset(&cbz2, 0, sizeof(cbz2));
- memset(&dbz2, 0, sizeof(dbz2));
- memset(&ebz2, 0, sizeof(ebz2));
+ memset(&bz2, 0, sizeof(bz2));
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
@@ -205,20 +198,6 @@ int main(int argc,char * argv[])
if ((f = fopen(argv[3], "r")) == NULL)
err(1, "fopen(%s)", argv[3]);
- /*
- File format:
- 0 8 "BSDIFF40"
- 8 8 X
- 16 8 Y
- 24 8 sizeof(newfile)
- 32 X bzip2(control block)
- 32+X Y bzip2(diff block)
- 32+X+Y ??? bzip2(extra block)
- with control block a set of triples (x,y,z) meaning "add x bytes
- from oldfile to x bytes from the diff block; copy y bytes from the
- extra block; seek forwards in oldfile by z bytes".
- */
-
/* Read header */
if (fread(header, 1, 32, f) < 32) {
if (feof(f))
@@ -238,24 +217,6 @@ int main(int argc,char * argv[])
errx(1,"Corrupt patch\n");
/* Close patch file and re-open it via libbzip2 at the right places */
- if (fclose(f))
- err(1, "fclose(%s)", argv[3]);
- if ((cpf = fopen(argv[3], "r")) == NULL)
- err(1, "fopen(%s)", argv[3]);
- if (fseeko(cpf, 32, SEEK_SET))
- err(1, "fseeko64(%s, %lld)", argv[3],
- (long long)32);
- if ((dpf = fopen(argv[3], "r")) == NULL)
- err(1, "fopen(%s)", argv[3]);
- if (fseeko(dpf, 32 + bzctrllen, SEEK_SET))
- err(1, "fseeko64(%s, %lld)", argv[3],
- (long long)(32 + bzctrllen));
- if ((epf = fopen(argv[3], "r")) == NULL)
- err(1, "fopen(%s)", argv[3]);
- if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
- err(1, "fseeko64(%s, %lld)", argv[3],
- (long long)(32 + bzctrllen + bzdatalen));
-
if(((fd=open(argv[1],O_RDONLY,0))<0) ||
((req.oldsize=lseek(fd,0,SEEK_END))==-1) ||
((old=malloc(req.oldsize+1))==NULL) ||
@@ -265,30 +226,19 @@ int main(int argc,char * argv[])
req.old = old;
if((req.new=malloc(req.newsize+1))==NULL) err(1,NULL);
- cbz2.pf = cpf;
- req.control.opaque = &cbz2;
- req.control.read = readcompress;
- dbz2.pf = dpf;
- req.diff.opaque = &dbz2;
- req.diff.read = readcompress;
- ebz2.pf = epf;
- req.extra.opaque = &ebz2;
- req.extra.read = readcompress;
-
- if (BZ_OK != (cbz2err = BZ2_bzDecompressInit(&cbz2.bz2, 0, 0)))
- errx(1, "BZ2_bzDecompressInit, bz2err = %d", cbz2err);
- if (BZ_OK != (dbz2err = BZ2_bzDecompressInit(&dbz2.bz2, 0, 0)))
- errx(1, "BZ2_bzDecompressInit, bz2err = %d", dbz2err);
- if (BZ_OK != (ebz2err = BZ2_bzDecompressInit(&ebz2.bz2, 0, 0)))
- errx(1, "BZ2_bzDecompressInit, bz2err = %d", ebz2err);
+ bz2.pf = f;
+ req.stream.opaque = &bz2;
+ req.stream.read = readcompress;
+
+ if (BZ_OK != (bz2err = BZ2_bzDecompressInit(&bz2.bz2, 0, 0)))
+ errx(1, "BZ2_bzDecompressInit, bz2err = %d", bz2err);
if (bspatch(req))
err(1, "bspatch");
/* Clean up the bzip2 reads */
- BZ2_bzDecompressEnd(&cbz2.bz2);
- BZ2_bzDecompressEnd(&dbz2.bz2);
- BZ2_bzDecompressEnd(&ebz2.bz2);
+ BZ2_bzDecompressEnd(&bz2.bz2);
+ fclose(f);
/* Write the new file */
if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) ||