From 44b983ce05f482969dbb490c46681b530c8c37b8 Mon Sep 17 00:00:00 2001 From: "Pawel S. Veselov" Date: Tue, 7 Mar 2017 14:13:31 -0800 Subject: [PATCH 1/5] * Removed unused operation --- bsdiff.c | 1 - 1 file changed, 1 deletion(-) diff --git a/bsdiff.c b/bsdiff.c index 628f1c1..6dda451 100644 --- a/bsdiff.c +++ b/bsdiff.c @@ -105,7 +105,6 @@ static void qsufsort(int64_t *I,int64_t *V,const uint8_t *old,int64_t oldsize) buckets[0]=0; for(i=0;i Date: Tue, 7 Mar 2017 16:47:34 -0800 Subject: [PATCH 2/5] * Reformat --- bsdiff.c | 763 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 401 insertions(+), 362 deletions(-) diff --git a/bsdiff.c b/bsdiff.c index 6dda451..fd48a12 100644 --- a/bsdiff.c +++ b/bsdiff.c @@ -30,322 +30,361 @@ #include #include -#define MIN(x,y) (((x)<(y)) ? (x) : (y)) - -static void split(int64_t *I,int64_t *V,int64_t start,int64_t len,int64_t h) -{ - int64_t i,j,k,x,tmp,jj,kk; - - if(len<16) { - for(k=start;kstart) split(I,V,start,jj-start,h); - - for(i=0;ikk) split(I,V,kk,start+len-kk,h); +#define MIN(x, y) (((x)<(y)) ? (x) : (y)) + +static void split(int64_t *I, int64_t *V, int64_t start, int64_t len, int64_t h) { + int64_t i, j, k, x, tmp, jj, kk; + + if (len < 16) { + for (k = start; k < start + len; k += j) { + j = 1; + x = V[I[k] + h]; + for (i = 1; k + i < start + len; i++) { + if (V[I[k + i] + h] < x) { + x = V[I[k + i] + h]; + j = 0; + }; + if (V[I[k + i] + h] == x) { + tmp = I[k + j]; + I[k + j] = I[k + i]; + I[k + i] = tmp; + j++; + }; + }; + for (i = 0; i < j; i++) V[I[k + i]] = k + j - 1; + if (j == 1) I[k] = -1; + }; + return; + }; + + x = V[I[start + len / 2] + h]; + jj = 0; + kk = 0; + for (i = start; i < start + len; i++) { + if (V[I[i] + h] < x) jj++; + if (V[I[i] + h] == x) kk++; + }; + jj += start; + kk += jj; + + i = start; + j = 0; + k = 0; + while (i < jj) { + if (V[I[i] + h] < x) { + i++; + } else if (V[I[i] + h] == x) { + tmp = I[i]; + I[i] = I[jj + j]; + I[jj + j] = tmp; + j++; + } else { + tmp = I[i]; + I[i] = I[kk + k]; + I[kk + k] = tmp; + k++; + }; + }; + + while (jj + j < kk) { + if (V[I[jj + j] + h] == x) { + j++; + } else { + tmp = I[jj + j]; + I[jj + j] = I[kk + k]; + I[kk + k] = tmp; + k++; + }; + }; + + if (jj > start) split(I, V, start, jj - start, h); + + for (i = 0; i < kk - jj; i++) V[I[jj + i]] = kk - 1; + if (jj == kk - 1) I[jj] = -1; + + if (start + len > kk) split(I, V, kk, start + len - kk, h); } -static void qsufsort(int64_t *I,int64_t *V,const uint8_t *old,int64_t oldsize) -{ - int64_t buckets[256]; - int64_t i,h,len; - - for(i=0;i<256;i++) buckets[i]=0; - for(i=0;i0;i--) buckets[i]=buckets[i-1]; - buckets[0]=0; - - for(i=0;i 0; i--) buckets[i] = buckets[i - 1]; + buckets[0] = 0; + + for (i = 0; i < oldsize; i++) I[++buckets[old[i]]] = i; + for (i = 0; i < oldsize; i++) V[i] = buckets[old[i]]; + V[oldsize] = 0; + for (i = 1; i < 256; i++) if (buckets[i] == buckets[i - 1] + 1) I[buckets[i]] = -1; + I[0] = -1; + + for (h = 1; I[0] != -(oldsize + 1); h += h) { + len = 0; + for (i = 0; i < oldsize + 1;) { + if (I[i] < 0) { + len -= I[i]; + i -= I[i]; + } else { + if (len) I[i - len] = -len; + len = V[I[i]] + 1 - i; + split(I, V, i, len, h); + i += len; + len = 0; + }; + }; + if (len) I[i - len] = -len; + }; + + for (i = 0; i < oldsize + 1; i++) I[V[i]] = i; } -static int64_t matchlen(const uint8_t *old,int64_t oldsize,const uint8_t *new,int64_t newsize) -{ - int64_t i; +static int64_t matchlen(const uint8_t *old, int64_t oldsize, const uint8_t *new, int64_t newsize) { + int64_t i; - for(i=0;(iy) { - *pos=I[st]; - return x; - } else { - *pos=I[en]; - return y; - } - }; - - x=st+(en-st)/2; - if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) { - return search(I,old,oldsize,new,newsize,x,en,pos); - } else { - return search(I,old,oldsize,new,newsize,st,x,pos); - }; +static int64_t search(const int64_t *I, const uint8_t *old, int64_t oldsize, + const uint8_t *new, int64_t newsize, int64_t st, int64_t en, int64_t *pos) { + int64_t x, y; + + if (en - st < 2) { + x = matchlen(old + I[st], oldsize - I[st], new, newsize); + y = matchlen(old + I[en], oldsize - I[en], new, newsize); + + if (x > y) { + *pos = I[st]; + return x; + } else { + *pos = I[en]; + return y; + } + }; + + x = st + (en - st) / 2; + if (memcmp(old + I[x], new, MIN(oldsize - I[x], newsize)) < 0) { + return search(I, old, oldsize, new, newsize, x, en, pos); + } else { + return search(I, old, oldsize, new, newsize, st, x, pos); + }; } -static void offtout(int64_t x,uint8_t *buf) -{ - int64_t y; +static void offtout(int64_t x, uint8_t *buf) { + int64_t y; + + if (x < 0) y = -x; else y = x; + + buf[0] = y % 256; + y -= buf[0]; + y = y / 256; + buf[1] = y % 256; + y -= buf[1]; + y = y / 256; + buf[2] = y % 256; + y -= buf[2]; + y = y / 256; + buf[3] = y % 256; + y -= buf[3]; + y = y / 256; + buf[4] = y % 256; + y -= buf[4]; + y = y / 256; + buf[5] = y % 256; + y -= buf[5]; + y = y / 256; + buf[6] = y % 256; + y -= buf[6]; + y = y / 256; + buf[7] = y % 256; + + if (x < 0) buf[7] |= 0x80; +} - if(x<0) y=-x; else y=x; +static int64_t writedata(struct bsdiff_stream *stream, const void *buffer, int64_t length) { + int64_t result = 0; - buf[0]=y%256;y-=buf[0]; - y=y/256;buf[1]=y%256;y-=buf[1]; - y=y/256;buf[2]=y%256;y-=buf[2]; - y=y/256;buf[3]=y%256;y-=buf[3]; - y=y/256;buf[4]=y%256;y-=buf[4]; - y=y/256;buf[5]=y%256;y-=buf[5]; - y=y/256;buf[6]=y%256;y-=buf[6]; - y=y/256;buf[7]=y%256; + while (length > 0) { + const int smallsize = (int) MIN(length, INT_MAX); + const int writeresult = stream->write(stream, buffer, smallsize); + if (writeresult == -1) { + return -1; + } - if(x<0) buf[7]|=0x80; -} + result += writeresult; + length -= smallsize; + buffer = (uint8_t *) buffer + smallsize; + } -static int64_t writedata(struct bsdiff_stream* stream, const void* buffer, int64_t length) -{ - int64_t result = 0; - - while (length > 0) - { - const int smallsize = (int)MIN(length, INT_MAX); - const int writeresult = stream->write(stream, buffer, smallsize); - if (writeresult == -1) - { - return -1; - } - - result += writeresult; - length -= smallsize; - buffer = (uint8_t*)buffer + smallsize; - } - - return result; + return result; } -struct bsdiff_request -{ - const uint8_t* old; - int64_t oldsize; - const uint8_t* new; - int64_t newsize; - struct bsdiff_stream* stream; - int64_t *I; - uint8_t *buffer; +struct bsdiff_request { + const uint8_t *old; + int64_t oldsize; + const uint8_t *new; + int64_t newsize; + struct bsdiff_stream *stream; + int64_t *I; + uint8_t *buffer; }; -static int bsdiff_internal(const struct bsdiff_request req) -{ - int64_t *I,*V; - int64_t scan,pos,len; - int64_t lastscan,lastpos,lastoffset; - int64_t oldscore,scsc; - int64_t s,Sf,lenf,Sb,lenb; - int64_t overlap,Ss,lens; - int64_t i; - uint8_t *buffer; - uint8_t buf[8 * 3]; - - if((V=req.stream->malloc((req.oldsize+1)*sizeof(int64_t)))==NULL) return -1; - I = req.I; - - qsufsort(I,V,req.old,req.oldsize); - req.stream->free(V); - - buffer = req.buffer; - - /* Compute the differences, writing ctrl as we go */ - scan=0;len=0;pos=0; - lastscan=0;lastpos=0;lastoffset=0; - while(scanoldscore+8)) break; - - if((scan+lastoffsetSf*2-lenf) { Sf=s; lenf=i; }; - }; - - lenb=0; - if(scan=lastscan+i)&&(pos>=i);i++) { - if(req.old[pos-i]==req.new[scan-i]) s++; - if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; }; - }; - }; - - if(lastscan+lenf>scan-lenb) { - overlap=(lastscan+lenf)-(scan-lenb); - s=0;Ss=0;lens=0; - for(i=0;iSs) { Ss=s; lens=i+1; }; - }; - - lenf+=lens-overlap; - lenb-=lens; - }; - - offtout(lenf,buf); - offtout((scan-lenb)-(lastscan+lenf),buf+8); - offtout((pos-lenb)-(lastpos+lenf),buf+16); - - /* Write control data */ - if (writedata(req.stream, buf, sizeof(buf))) - return -1; - - /* Write diff data */ - for(i=0;imalloc((req.oldsize + 1) * sizeof(int64_t))) == NULL) return -1; + I = req.I; + + qsufsort(I, V, req.old, req.oldsize); + req.stream->free(V); + + buffer = req.buffer; + + /* Compute the differences, writing ctrl as we go */ + + scan = 0; // position we are scanning New from. + len = 0; + pos = 0; + lastscan = 0; + lastpos = 0; + lastoffset = 0; + + + while (scan < req.newsize) { + oldscore = 0; + + for (scsc = scan += len; scan < req.newsize; scan++) { + len = search(I, req.old, req.oldsize, req.new + scan, req.newsize - scan, + 0, req.oldsize, &pos); + + for (; scsc < scan + len; scsc++) + if ((scsc + lastoffset < req.oldsize) && + (req.old[scsc + lastoffset] == req.new[scsc])) + oldscore++; + + if (((len == oldscore) && (len != 0)) || + (len > oldscore + 8)) + break; + + if ((scan + lastoffset < req.oldsize) && + (req.old[scan + lastoffset] == req.new[scan])) + oldscore--; + }; + + if ((len != oldscore) || (scan == req.newsize)) { + s = 0; + Sf = 0; + lenf = 0; + for (i = 0; (lastscan + i < scan) && (lastpos + i < req.oldsize);) { + if (req.old[lastpos + i] == req.new[lastscan + i]) s++; + i++; + if (s * 2 - i > Sf * 2 - lenf) { + Sf = s; + lenf = i; + }; + }; + + lenb = 0; + if (scan < req.newsize) { + s = 0; + Sb = 0; + for (i = 1; (scan >= lastscan + i) && (pos >= i); i++) { + if (req.old[pos - i] == req.new[scan - i]) s++; + if (s * 2 - i > Sb * 2 - lenb) { + Sb = s; + lenb = i; + }; + }; + }; + + if (lastscan + lenf > scan - lenb) { + overlap = (lastscan + lenf) - (scan - lenb); + s = 0; + Ss = 0; + lens = 0; + for (i = 0; i < overlap; i++) { + if (req.new[lastscan + lenf - overlap + i] == + req.old[lastpos + lenf - overlap + i]) + s++; + if (req.new[scan - lenb + i] == + req.old[pos - lenb + i]) + s--; + if (s > Ss) { + Ss = s; + lens = i + 1; + }; + }; + + lenf += lens - overlap; + lenb -= lens; + }; + + offtout(lenf, buf); + offtout((scan - lenb) - (lastscan + lenf), buf + 8); + offtout((pos - lenb) - (lastpos + lenf), buf + 16); + + /* Write control data */ + if (writedata(req.stream, buf, sizeof(buf))) + return -1; + + /* Write diff data */ + for (i = 0; i < lenf; i++) + buffer[i] = req.new[lastscan + i] - req.old[lastpos + i]; + if (writedata(req.stream, buffer, lenf)) + return -1; + + /* Write extra data */ + for (i = 0; i < (scan - lenb) - (lastscan + lenf); i++) + buffer[i] = req.new[lastscan + lenf + i]; + if (writedata(req.stream, buffer, (scan - lenb) - (lastscan + lenf))) + return -1; + + lastscan = scan - lenb; + lastpos = pos - lenb; + lastoffset = pos - scan; + }; + }; + + return 0; } -int bsdiff(const uint8_t* old, int64_t oldsize, const uint8_t* new, int64_t newsize, struct bsdiff_stream* stream) -{ - int result; - struct bsdiff_request req; +int bsdiff(const uint8_t *old, int64_t oldsize, const uint8_t *new, int64_t newsize, struct bsdiff_stream *stream) { + int result; + struct bsdiff_request req; - if((req.I=stream->malloc((oldsize+1)*sizeof(int64_t)))==NULL) - return -1; + if ((req.I = stream->malloc((oldsize + 1) * sizeof(int64_t))) == NULL) + return -1; - if((req.buffer=stream->malloc(newsize+1))==NULL) - { - stream->free(req.I); - return -1; - } + if ((req.buffer = stream->malloc(newsize + 1)) == NULL) { + stream->free(req.I); + return -1; + } - req.old = old; - req.oldsize = oldsize; - req.new = new; - req.newsize = newsize; - req.stream = stream; + req.old = old; + req.oldsize = oldsize; + req.new = new; + req.newsize = newsize; + req.stream = stream; - result = bsdiff_internal(req); + result = bsdiff_internal(req); - stream->free(req.buffer); - stream->free(req.I); + stream->free(req.buffer); + stream->free(req.I); - return result; + return result; } #if defined(BSDIFF_EXECUTABLE) @@ -361,84 +400,84 @@ int bsdiff(const uint8_t* old, int64_t oldsize, const uint8_t* new, int64_t news static int bz2_write(struct bsdiff_stream* stream, const void* buffer, int size) { - int bz2err; - BZFILE* bz2; + int bz2err; + BZFILE* bz2; - bz2 = (BZFILE*)stream->opaque; - BZ2_bzWrite(&bz2err, bz2, (void*)buffer, size); - if (bz2err != BZ_STREAM_END && bz2err != BZ_OK) - return -1; + bz2 = (BZFILE*)stream->opaque; + BZ2_bzWrite(&bz2err, bz2, (void*)buffer, size); + if (bz2err != BZ_STREAM_END && bz2err != BZ_OK) + return -1; - return 0; + return 0; } int main(int argc,char *argv[]) { - int fd; - int bz2err; - uint8_t *old,*new; - off_t oldsize,newsize; - uint8_t buf[8]; - FILE * pf; - struct bsdiff_stream stream; - BZFILE* bz2; - - memset(&bz2, 0, sizeof(bz2)); - stream.malloc = malloc; - stream.free = free; - stream.write = bz2_write; - - if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); - - /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure - that we never try to malloc(0) and get a NULL pointer */ - if(((fd=open(argv[1],O_RDONLY,0))<0) || - ((oldsize=lseek(fd,0,SEEK_END))==-1) || - ((old=malloc(oldsize+1))==NULL) || - (lseek(fd,0,SEEK_SET)!=0) || - (read(fd,old,oldsize)!=oldsize) || - (close(fd)==-1)) err(1,"%s",argv[1]); - - - /* Allocate newsize+1 bytes instead of newsize bytes to ensure - that we never try to malloc(0) and get a NULL pointer */ - if(((fd=open(argv[2],O_RDONLY,0))<0) || - ((newsize=lseek(fd,0,SEEK_END))==-1) || - ((new=malloc(newsize+1))==NULL) || - (lseek(fd,0,SEEK_SET)!=0) || - (read(fd,new,newsize)!=newsize) || - (close(fd)==-1)) err(1,"%s",argv[2]); - - /* Create the patch file */ - if ((pf = fopen(argv[3], "w")) == NULL) - err(1, "%s", argv[3]); - - /* Write header (signature+newsize)*/ - offtout(newsize, buf); - if (fwrite("ENDSLEY/BSDIFF43", 16, 1, pf) != 1 || - fwrite(buf, sizeof(buf), 1, pf) != 1) - err(1, "Failed to write header"); - - - if (NULL == (bz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0))) - errx(1, "BZ2_bzWriteOpen, bz2err=%d", bz2err); - - stream.opaque = bz2; - if (bsdiff(old, oldsize, new, newsize, &stream)) - err(1, "bsdiff"); - - BZ2_bzWriteClose(&bz2err, bz2, 0, NULL, NULL); - if (bz2err != BZ_OK) - err(1, "BZ2_bzWriteClose, bz2err=%d", bz2err); - - if (fclose(pf)) - err(1, "fclose"); - - /* Free the memory we used */ - free(old); - free(new); - - return 0; + int fd; + int bz2err; + uint8_t *old,*new; + off_t oldsize,newsize; + uint8_t buf[8]; + FILE * pf; + struct bsdiff_stream stream; + BZFILE* bz2; + + memset(&bz2, 0, sizeof(bz2)); + stream.malloc = malloc; + stream.free = free; + stream.write = bz2_write; + + if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); + + /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure + that we never try to malloc(0) and get a NULL pointer */ + if(((fd=open(argv[1],O_RDONLY,0))<0) || + ((oldsize=lseek(fd,0,SEEK_END))==-1) || + ((old=malloc(oldsize+1))==NULL) || + (lseek(fd,0,SEEK_SET)!=0) || + (read(fd,old,oldsize)!=oldsize) || + (close(fd)==-1)) err(1,"%s",argv[1]); + + + /* Allocate newsize+1 bytes instead of newsize bytes to ensure + that we never try to malloc(0) and get a NULL pointer */ + if(((fd=open(argv[2],O_RDONLY,0))<0) || + ((newsize=lseek(fd,0,SEEK_END))==-1) || + ((new=malloc(newsize+1))==NULL) || + (lseek(fd,0,SEEK_SET)!=0) || + (read(fd,new,newsize)!=newsize) || + (close(fd)==-1)) err(1,"%s",argv[2]); + + /* Create the patch file */ + if ((pf = fopen(argv[3], "w")) == NULL) + err(1, "%s", argv[3]); + + /* Write header (signature+newsize)*/ + offtout(newsize, buf); + if (fwrite("ENDSLEY/BSDIFF43", 16, 1, pf) != 1 || + fwrite(buf, sizeof(buf), 1, pf) != 1) + err(1, "Failed to write header"); + + + if (NULL == (bz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0))) + errx(1, "BZ2_bzWriteOpen, bz2err=%d", bz2err); + + stream.opaque = bz2; + if (bsdiff(old, oldsize, new, newsize, &stream)) + err(1, "bsdiff"); + + BZ2_bzWriteClose(&bz2err, bz2, 0, NULL, NULL); + if (bz2err != BZ_OK) + err(1, "BZ2_bzWriteClose, bz2err=%d", bz2err); + + if (fclose(pf)) + err(1, "fclose"); + + /* Free the memory we used */ + free(old); + free(new); + + return 0; } #endif From 58a1a30f2c2fd07cc16a521a97ea4463b1a260ce Mon Sep 17 00:00:00 2001 From: "Pawel S. Veselov" Date: Tue, 7 Mar 2017 16:48:10 -0800 Subject: [PATCH 3/5] * added CLion files --- .idea/bsdiff.iml | 2 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .idea/workspace.xml | 390 ++++++++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 13 ++ 6 files changed, 423 insertions(+) create mode 100644 .idea/bsdiff.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 CMakeLists.txt diff --git a/.idea/bsdiff.iml b/.idea/bsdiff.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/bsdiff.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5d56335 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..6c26edc --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + search + len + scan + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + true + + + + DIRECTORY + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1488932062518 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7a25e8a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.6) +project(bsdiff) + +set(CMAKE_CXX_STANDARD 11) + +set(SOURCE_FILES + bsdiff.c + bsdiff.h + bspatch.c + bspatch.h + config.h) + +add_executable(bsdiff ${SOURCE_FILES}) \ No newline at end of file From b9c4248b00ac6140248cbf33ee04e3958efefbff Mon Sep 17 00:00:00 2001 From: "Pawel S. Veselov" Date: Wed, 8 Mar 2017 22:14:23 -0800 Subject: [PATCH 4/5] check point --- .idea/workspace.xml | 153 ++++++++++++++++++++++++++++++++++++-------- CMakeLists.txt | 1 + bsdiff.c | 145 +++++++++++++++++++++++++++++++++++------ 3 files changed, 254 insertions(+), 45 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 6c26edc..821cbcc 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -11,7 +11,11 @@ - + + + + +