interleaving control, diff and extra data
authorMatthew Endsley <mendsley@gmail.com>
Mon, 14 May 2012 06:11:32 +0000 (23:11 -0700)
committerMatthew Endsley <mendsley@gmail.com>
Mon, 14 May 2012 08:04:25 +0000 (01:04 -0700)
bsdiff.c
bspatch.c

index 88936aa..c4da099 100644 (file)
--- 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");
index 3b7eab4..423283b 100644 (file)
--- 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) ||