Skip to content

Commit

Permalink
Merge pull request #3 from LYF1999/lyf/add-buf-dif
Browse files Browse the repository at this point in the history
feat: 增加在buffer中进行diff的特性
  • Loading branch information
tsyeyuanfeng authored Oct 24, 2019
2 parents dbe5bfb + 3106f55 commit 8b8351e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 44 deletions.
118 changes: 74 additions & 44 deletions src/bsdiff/bsdiff.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,36 +195,22 @@ static void offtout(off_t x,u_char *buf)
if(x<0) buf[7]|=0x80;
}

int bsdiff(const char* error, const char* oldfile, const char* newfile, const char* patchfile) {
int fd;
u_char *old,*new;
off_t oldsize,newsize;
int bsdiff_buf(const char* error, const char *old, size_t oldsize, char *new, size_t newsize, char **patch_buf) {
off_t *I,*V;
u_char *db,*eb;
off_t scan,pos,len;
off_t lastscan,lastpos,lastoffset;
u_char header[32];
off_t oldscore,scsc;
off_t s,Sf,lenf,Sb,lenb;
off_t overlap,Ss,lens;
off_t lastscan,lastpos,lastoffset;
off_t i;
off_t dblen,eblen;
u_char *db,*eb;
u_char buf[8];
u_char header[32];
FILE * pf;
BZFILE * pfbz2;
off_t overlap,Ss,lens;
off_t dblen,eblen;
int bz2err;

/* 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(oldfile,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)) {
sprintf((char*)error, "\"%s\" %s", oldfile, strerror(errno));
return -1;
}
BZFILE * pfbz2;
FILE * pf;
size_t patch_len;

if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) ||
((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) {
Expand All @@ -236,28 +222,16 @@ int bsdiff(const char* error, const char* oldfile, const char* newfile, const ch

free(V);

/* 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(newfile,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)) {
sprintf((char*)error, "\"%s\" %s", newfile, strerror(errno));
return -1;
}

if(((db=malloc(newsize+1))==NULL) ||
((eb=malloc(newsize+1))==NULL)) err(1,NULL);
dblen=0;
eblen=0;

/* Create the patch file */
if ((pf = fopen(patchfile, "w")) == NULL) {
sprintf((char*)error, "\"%s\" %s", patchfile, strerror(errno));

if ((pf = open_memstream(patch_buf, &patch_len)) == NULL) {
sprintf((char*)error, "open patch_buf failed: %s", strerror(errno));
return -1;
}
}


/* Header is
0 8 "BSDIFF40"
Expand All @@ -273,10 +247,12 @@ int bsdiff(const char* error, const char* oldfile, const char* newfile, const ch
offtout(0, header + 8);
offtout(0, header + 16);
offtout(newsize, header + 24);

if (fwrite(header, 32, 1, pf) != 1) {
sprintf((char*)error, "\"%s\" %s", patchfile, strerror(errno));
sprintf((char*)error, "write header for patch failed: %s", strerror(errno));
return -1;
}
}


/* Compute the differences, writing ctrl as we go */
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) {
Expand Down Expand Up @@ -372,6 +348,8 @@ int bsdiff(const char* error, const char* oldfile, const char* newfile, const ch
lastoffset=pos-scan;
};
};


BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
if (bz2err != BZ_OK) {
sprintf((char*)error, "BZ2_bzWriteClose, bz2err = %d", bz2err);
Expand Down Expand Up @@ -403,6 +381,7 @@ int bsdiff(const char* error, const char* oldfile, const char* newfile, const ch
return -1;
}


/* Compute size of compressed diff data */
if ((newsize = ftello(pf)) == -1) {
sprintf((char*)error, "\"ftello\" %s", strerror(errno));
Expand All @@ -428,15 +407,18 @@ int bsdiff(const char* error, const char* oldfile, const char* newfile, const ch
return -1;
}

// 只有在这里才能去到正确的长度,否则之后的代码会把pos设置为0
size_t real_len = ftello(pf);
/* Seek to the beginning, write the header, and close the file */
if (fseeko(pf, 0, SEEK_SET)) {
sprintf((char*)error, "\"fseeko\" %s", strerror(errno));
return -1;
}
if (fwrite(header, 32, 1, pf) != 1) {
sprintf((char*)error, "\"%s\" %s", patchfile, strerror(errno));
sprintf((char*)error, "write header for patch failed: %s", strerror(errno));
return -1;
}
}

if (fclose(pf)) {
sprintf((char*)error, "\"fclose\" %s", strerror(errno));
return -1;
Expand All @@ -446,6 +428,54 @@ int bsdiff(const char* error, const char* oldfile, const char* newfile, const ch
free(db);
free(eb);
free(I);
return real_len;
}

int bsdiff(const char* error, const char* oldfile, const char* newfile, const char* patchfile) {
int fd;
u_char *old,*new;
off_t oldsize,newsize;
FILE * pf;
char *patch_buf;
off_t patch_size;

/* 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(oldfile,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)) {
sprintf((char*)error, "\"%s\" %s", oldfile, strerror(errno));
return -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(newfile,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)) {
sprintf((char*)error, "\"%s\" %s", newfile, strerror(errno));
return -1;
}


if ((pf = fopen(patchfile, "w")) == NULL) {
sprintf((char*)error, "\"%s\" %s", patchfile, strerror(errno));
return -1;
}

patch_size = bsdiff_buf(error, old, oldsize, new, newsize, &patch_buf);
fwrite(patch_buf, sizeof(char), patch_size, pf);
free(patch_buf);
if (fclose(pf)) {
sprintf((char*)error, "\"fclose\" %s", strerror(errno));
return -1;
}
free(old);
free(new);

Expand Down
1 change: 1 addition & 0 deletions src/bsdiff/bsdiff.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
#include <stdint.h>

int bsdiff(const char* error, const char* oldfile, const char* newfile, const char* patchfile);
int bsdiff_buf(const char* error, const char *old_buf, size_t oldsize, char *new_buf, size_t newsize, char **patch_buf);

#endif
28 changes: 28 additions & 0 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,33 @@ namespace bsdpNode {
}
}

void diff_buf(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope scope(isolate);

if (!node::Buffer::HasInstance(args[0]) || !node::Buffer::HasInstance(args[1])) {
isolate->ThrowException(Exception::Error(
String::NewFromUtf8(isolate, "Invalid arguments.")));
return;
}

char* old_buf = node::Buffer::Data(args[0]);
size_t old_len = node::Buffer::Length(args[0]);
char* new_buf = node::Buffer::Data(args[1]);
size_t new_len = node::Buffer::Length(args[1]);
char error[1024];

char *patch_buf;
int ret = bsdiff_buf(error, old_buf, old_len, new_buf, new_len, &patch_buf);
if(ret < 0) {
isolate->ThrowException(Exception::Error(
String::NewFromUtf8(isolate, error)));
}
Local<Object> buf;
node::Buffer::New(isolate, patch_buf, ret).ToLocal(&buf);
args.GetReturnValue().Set(buf);
}

void patch(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope scope(isolate);
Expand All @@ -60,6 +87,7 @@ namespace bsdpNode {
void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "diff", diff);
NODE_SET_METHOD(exports, "patch", patch);
NODE_SET_METHOD(exports, "diff_buf", diff_buf);
}

NODE_MODULE(bsdp, init)
Expand Down

0 comments on commit 8b8351e

Please sign in to comment.