115 lines
3.2 KiB
C
115 lines
3.2 KiB
C
//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 <errno.h>
|
|
#include <stdbool.h>
|
|
#include <unistd.h>
|
|
|
|
//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);
|
|
}
|
|
}
|