//Required to fix compile errors with xdelta3 #define SIZEOF_SIZE_T 4 #define static_assert(e,m) /* do nothing */ #define XD3_ENCODER 0 #define XD3_USE_LARGESIZET 0 typedef unsigned int usize_t; typedef unsigned long long xoff_t; //Include xdelta3 #include "../lib/xdelta3/xdelta3.c" //Include other libraries #include #include #include //Include our own files #include "errorAndExit.h" #include "rateLimiter.h" #include "xdelta3.h" //Various variables for Xdelta3 xd3_stream stream; xd3_config config; xd3_source source; //The previous version of the file we want to extract FILE* srcFile; //Total number of bytes written to output unsigned long totalOut = 0UL; /** Initializes xdelta3 with the given previous file */ void xdelta3Init(char* prevFile) { srcFile = fopen(prevFile, "rb"); if (srcFile == NULL) { fprintf(stderr, "Could not open previous file %s for reading during xdelta3: %s\n", prevFile, strerror(errno)); errorAndExit(); } xd3_init_config(&config, XD3_ADLER32); config.winsize = XD3_ALLOCSIZE; xd3_config_stream(&stream, &config); //Set source (= old file from previous release) source.blksize = XD3_ALLOCSIZE; source.curblk = malloc(source.blksize); if (source.curblk == NULL) { fprintf(stderr, "ERROR: Could not allocate source.blksize in VCDIFF.\n"); errorAndExit(); } fseek(srcFile, 0, SEEK_SET); source.onblk = fread((void*)source.curblk, 1, source.blksize, srcFile); source.curblkno = 0; xd3_set_source(&stream, &source); //Set input (= xdelta file from current release) xd3_set_flags(&stream, XD3_FLUSH | stream.flags); } /** Supplies the given input buffer to xdelta3 and undiffs the data. */ void xdelta3AddInput(unsigned char* inputBuffer, unsigned int inputLength, bool isLastPart, FILE* targetFile) { xd3_avail_input(&stream, inputBuffer, inputLength); int returnValue; process: returnValue = xd3_decode_input(&stream); switch (returnValue) { case XD3_INPUT: { //fprintf(stderr, "XD3_INPUT\n"); break; } case XD3_OUTPUT: { //fprintf(stderr, "XD3_OUTPUT\n"); totalOut += stream.avail_out; consumeCapacity(stream.avail_out); if (targetFile) { fwrite(stream.next_out, 1, stream.avail_out, targetFile); } else { write(1, stream.next_out, stream.avail_out); } xd3_consume_output(&stream); goto process; } case XD3_GETSRCBLK: { //fprintf(stderr, "XD3_GETSRCBLK\n"); fseek(srcFile, source.blksize * source.getblkno, SEEK_SET); source.onblk = fread((void*)source.curblk, 1, source.blksize, srcFile); source.curblkno = source.getblkno; goto process; } case XD3_GOTHEADER: { //fprintf(stderr, "XD3_GOTHEADER\n"); goto process; } case XD3_WINSTART: { //fprintf(stderr, "XD3_WINSTART\n"); goto process; } case XD3_WINFINISH: { //fprintf(stderr, "XD3_WINFINISH\n"); goto process; } default: { fprintf(stderr, "ERROR: !!! INVALID %s %d !!!\n", stream.msg, returnValue); errorAndExit(); } } //If we are done, free up memory if (isLastPart) { free((void*)source.curblk); xd3_close_stream(&stream); xd3_free_stream(&stream); fclose(srcFile); } }