Reaching *reaching(Cfg *cfg) { Bitset **in, **out; Bitset **gen, **kill; Bitset *bbin, *bbout; Reaching *reaching; size_t **defs; /* mapping from did => [def,list] */ size_t *ndefs; size_t i, j; int changed; in = zalloc(cfg->nbb * sizeof(Bb*)); out = zalloc(cfg->nbb * sizeof(Bb*)); gen = zalloc(cfg->nbb * sizeof(Bb*)); kill = zalloc(cfg->nbb * sizeof(Bb*)); defs = zalloc(ndecls * sizeof(size_t*)); ndefs = zalloc(ndecls * sizeof(size_t)); collectdefs(cfg, defs, ndefs); for (i = 0; i < cfg->nbb; i++) { in[i] = mkbs(); out[i] = mkbs(); gen[i] = mkbs(); kill[i] = mkbs(); if (cfg->bb[i]) genkill(cfg->bb[i], defs, ndefs, gen[i], kill[i]); } do { changed = 0; for (i = 0; i < cfg->nbb; i++) { if (!cfg->bb[i]) continue; bbin = mkbs(); for (j = 0; bsiter(cfg->bb[i]->pred, &j); j++) bsunion(bbin, out[j]); bbout = bsdup(bbin); bsdiff(bbout, kill[i]); bsunion(bbout, gen[i]); if (!bseq(out[i], bbout) || !bseq(in[i], bbin)) { changed = 1; bsfree(in[i]); bsfree(out[i]); in[i] = bbin; out[i] = bbout; } } } while (changed); reaching = xalloc(sizeof(Reaching)); reaching->in = in; reaching->out = out; reaching->defs = defs; reaching->ndefs = ndefs; return reaching; }
bool BSDiff::Diff(char8 *origData, uint32 origSize, char8 *newData, uint32 newSize, File *patchFile, BSType type) { bool ret = false; ZLibOStream outStream(patchFile); if(NULL != patchFile) { // write BS type uint32 typeToWrite = type; patchFile->Write(&typeToWrite); bsdiff_stream diffStream; diffStream.type = type; diffStream.free = &BSDiff::BSFree; diffStream.malloc = &BSDiff::BSMalloc; diffStream.write = &BSDiff::BSWrite; switch(type) { case BS_ZLIB: diffStream.opaque = &outStream; break; case BS_PLAIN: diffStream.opaque = patchFile; break; default: DVASSERT(0 && "Unknow BS-type"); break; } // make bsdiff if(0 == bsdiff((uint8_t *) origData, origSize, (uint8_t *) newData, newSize, &diffStream)) { ret = true; } } return ret; }
size_t generateBsDiff( void *baseData, size_t baseSize, void *variantData, size_t variantSize, fWriteDiffCallback callback ) { DiffBuffer buffer; buffer.callback = callback; buffer.status = 0; DiffStream stream; stream.opaque = &buffer; stream.write = writeStream; stream.writeHeader = writeHeaderStream; stream.init = initStream; stream.end = endStream; size_t size = bsdiff((uint8_t *) baseData, baseSize, (uint8_t *) variantData, variantSize, &stream ); if ( size == 0 ) { fprintf( stderr, "failed to bsdiff the stream\n" ); if ( buffer.buff != NULL ) { free( buffer.buff ); } return 0; } return size; }
static int do_diff(struct dirent *d1, struct dirent *d2) { int ret; struct stat sb; char realname1[PATH_MAX]; char realname2[PATH_MAX]; char savename[PATH_MAX]; //char cmd[4096]; fprintf(stderr, "%s/%s differs\n", prefix, d1->d_name); if(!t) return 0; sprintf(realname1, "%s%s/%s", base1, prefix, d1->d_name); sprintf(realname2, "%s%s/%s", base2, prefix, d2->d_name); sprintf(savename, "%s%s/%s", "diff", prefix, d1->d_name); //sprintf(cmd, "cp %s patch", realname2); //sprintf(cmd, "/home/stephan/rdiff %s %s patch", realname1, realname2); //sprintf(cmd, "/usr/bin/xdelta3 -e -s %s %s patch", realname1, realname2); //sprintf(cmd, "/usr/bin/xdelta3 -e -S djw -9 -s %s %s patch", realname1, realname2); //sprintf(cmd, "/usr/bin/bsdiff %s %s patch", realname1, realname2); //sprintf(cmd, "/home/stephan/src/fsdiff/bsdiff %s %s patch", realname1, realname2); //system(cmd); bsdiff(realname1, realname2, "patch"); ret = lstat(realname2, &sb); th_set_from_stat(t, &sb); th_set_path(t, savename); ret = lstat("patch", &sb); th_set_size(t, sb.st_size); th_finish(t); if(t->options & TAR_VERBOSE) th_print_long_ls(t); th_write(t); tar_append_regfile(t, "patch"); //system("rm patch"); unlink("patch"); }
jstring Java_com_jackwang_patchapk_PatchJNI_bsdiff(JNIEnv* env, jobject thiz, jstring oldFilePath, jstring newFilePath, jstring patchFilePath) { const char* oldFilePathChar = (*env)->GetStringUTFChars(env, oldFilePath, 0); const char* newFilePathChar = (*env)->GetStringUTFChars(env, newFilePath, 0); const char* patchFilePathChar = (*env)->GetStringUTFChars(env, patchFilePath, 0); LOGI("oldFilePath = %s", oldFilePathChar); LOGI("newFilePath = %s", newFilePathChar); LOGI("patchFilePath = %s", patchFilePathChar); int retCode = bsdiff(oldFilePathChar, newFilePathChar, patchFilePathChar); //releaseString (*env)->ReleaseStringUTFChars(env, oldFilePath, oldFilePathChar); (*env)->ReleaseStringUTFChars(env, newFilePath, newFilePathChar); (*env)->ReleaseStringUTFChars(env, patchFilePath, patchFilePathChar); if(retCode == 0){ return (*env)->NewStringUTF(env, "diff success"); }else{ return (*env)->NewStringUTF(env, "diff failure"); } }
bool GenPatch(const char* patch_file, CBundle& Origin, CBundle& Lastest) { CBundlePatcher patcher; if(!patcher.Open(patch_file)) return false; std::map<std::string, CFile>::iterator i; for(i=Origin._Files.begin(); i!=Origin._Files.end(); i++) { if(Lastest._Files.find(i->first)==Lastest._Files.end()) { if(!patcher.DelFile(i->first)) return false; } } for(i=Lastest._Files.begin(); i!=Lastest._Files.end(); i++) { if(Origin._Files.find(i->first)==Origin._Files.end()) { if(!patcher.AddFile(i->first, "", i->second._MD5)) return false; void* mem; size_t size, offset; if(!ReadFile(i->second, mem, size)) return false; offset = ftell(patcher._stub); if(!patcher.AddOperatorAppend(size, offset)) return false; int bzerror; BZFILE* bzf = BZ2_bzWriteOpen(&bzerror, patcher._stub, 9, 0, 0); if(bzf==NULL) { free(mem); return false; } BZ2_bzWrite(&bzerror, bzf, mem, size); free(mem); if(bzerror!=BZ_OK) { BZ2_bzWriteClose(&bzerror, bzf, 0, NULL, NULL); return false; } unsigned int inbytes, outbytes; BZ2_bzWriteClose(&bzerror, bzf, 0, &inbytes, &outbytes); if(bzerror!=BZ_OK) { return false; } if(!patcher.AddOperatorEnd()) return false; } else { CFile& srcf = Origin._Files[i->first]; CFile& dstf = i->second; if(srcf._MD5!=dstf._MD5) { if(!patcher.AddFile(i->first, srcf._MD5, dstf._MD5)) return false; void* src = NULL; void* dst = NULL; size_t src_size, dst_size, offset; for(size_t i=0; i<dstf._Sections.size(); i++) { offset = ftell(patcher._stub); CSection* s = srcf.GetSectionByMD5(dstf._Sections[i]._MD5); if(s==NULL) { s = srcf.GetSectionByName(dstf._Sections[i]._Name); } if(s) { if(s->_MD5==dstf._Sections[i]._MD5) { // copy patcher.AddOperatorCopy(s->_Size, s->_Offset); } else { if(src==NULL && !ReadFile(srcf, src, src_size)) return false; if(dst==NULL && !ReadFile(dstf, dst, dst_size)) return false; // patch patcher.AddOperatorPatch(s->_Offset, s->_Size, offset); bsdiff((u_char*)src+s->_Offset, s->_Size, (u_char*)dst+dstf._Sections[i]._Offset, dstf._Sections[i]._Size, patcher._stub); } } else { if(dst==NULL && !ReadFile(dstf, dst, dst_size)) return false; // append if(!patcher.AddOperatorAppend(dstf._Sections[i]._Size, offset)) return false; int bzerror; BZFILE* bzf = BZ2_bzWriteOpen(&bzerror, patcher._stub, 9, 0, 0); if(bzf==NULL) return false; BZ2_bzWrite(&bzerror, bzf, (char*)dst+dstf._Sections[i]._Offset, dstf._Sections[i]._Size); if(bzerror!=BZ_OK) { BZ2_bzWriteClose(&bzerror, bzf, 0, NULL, NULL); return false; } unsigned int inbytes, outbytes; BZ2_bzWriteClose(&bzerror, bzf, 0, &inbytes, &outbytes); if(bzerror!=BZ_OK) { return false; } } } if(!patcher.AddOperatorEnd()) return false; if(src) free(src); if(dst) free(dst); } } } if(!patcher.DelFile("")) return false; if(!patcher.Close(true)) return false; return true; }