ssn-installer/src/xdelta3.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);
}
}