diff options
author | Matthew Endsley <mendsley@gmail.com> | 2012-05-13 23:11:32 -0700 |
---|---|---|
committer | Matthew Endsley <mendsley@gmail.com> | 2012-05-14 01:04:25 -0700 |
commit | 9e42fa58dbb3847ae71cfbba0800184b755f0c9e (patch) | |
tree | a4dc8f81d8b23e7a9e6edb317f9373bae604c99a | |
parent | 025c1b0195d4b63503385d0ef7a0c9118a96c922 (diff) | |
download | bsdiff-9e42fa58dbb3847ae71cfbba0800184b755f0c9e.tar.gz |
interleaving control, diff and extra data
-rw-r--r-- | bsdiff.c | 87 | ||||
-rw-r--r-- | bspatch.c | 80 |
2 files changed, 37 insertions, 130 deletions
@@ -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"); @@ -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) || |