✨ Add xdelta3 decoding support
This commit is contained in:
parent
ae59ce2256
commit
31ec793781
5 changed files with 124 additions and 13 deletions
|
@ -37,7 +37,7 @@ int main_file_read (main_file *ifile,
|
||||||
size_t size,
|
size_t size,
|
||||||
size_t *nread,
|
size_t *nread,
|
||||||
const char *msg);
|
const char *msg);
|
||||||
int main_file_write (main_file *ofile, uint8_t *buf,
|
int main_file_write (main_file *ofile, uint8_t *buf,
|
||||||
usize_t size, const char *msg);
|
usize_t size, const char *msg);
|
||||||
void* main_malloc (size_t size);
|
void* main_malloc (size_t size);
|
||||||
void main_free (void *ptr);
|
void main_free (void *ptr);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
void errorAndExit() {
|
void errorAndExit() {
|
||||||
fprintf(stderr, "\nUsage:\n");
|
fprintf(stderr, "\nUsage:\n");
|
||||||
fprintf(stderr, " ./patcher-installer --disk main.z01 --offset 456z --size 1000 [--keys 123,123,123] [--prev oldfile.tor]\n");
|
fprintf(stderr, " ./patcher-installer --disk main.z01 --offset 456z --size 1000 [--keys 123,456,789] [--previous oldfile.tor]\n");
|
||||||
fprintf(stderr, "Options:\n");
|
fprintf(stderr, "Options:\n");
|
||||||
fprintf(stderr, " -d, --disk: The path to the disk file that contains the file we want to extract.\n");
|
fprintf(stderr, " -d, --disk: The path to the disk file that contains the file we want to extract.\n");
|
||||||
fprintf(stderr, " -o, --offset: The offset into the disk, given in bytes, where the local file header of the file we want to extract starts.\n");
|
fprintf(stderr, " -o, --offset: The offset into the disk, given in bytes, where the local file header of the file we want to extract starts.\n");
|
||||||
|
|
24
src/main.c
24
src/main.c
|
@ -5,12 +5,13 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
//Import our code
|
//Import our code
|
||||||
|
#include "utils/min.h"
|
||||||
#include "decrypt.h"
|
#include "decrypt.h"
|
||||||
#include "errorAndExit.h"
|
#include "errorAndExit.h"
|
||||||
#include "fileReader.h"
|
#include "fileReader.h"
|
||||||
#include "inflate.h"
|
#include "inflate.h"
|
||||||
#include "parseArguments.h"
|
#include "parseArguments.h"
|
||||||
#include "utils/min.h"
|
#include "xdelta3.h"
|
||||||
|
|
||||||
//The size of the buffers where the compressed and uncompressed data is stored
|
//The size of the buffers where the compressed and uncompressed data is stored
|
||||||
#define BUFFER_SIZE 512UL * 1024UL //512 KiB
|
#define BUFFER_SIZE 512UL * 1024UL //512 KiB
|
||||||
|
@ -75,6 +76,11 @@ int main(int argc, char *argv[]) {
|
||||||
decrypt(compressedChunk, ENCRYPTION_HEADER_LENGTH);
|
decrypt(compressedChunk, ENCRYPTION_HEADER_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Initialize xdelta3
|
||||||
|
if (state.prevFile) {
|
||||||
|
xdelta3Init(state.prevFile);
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
struct InflateOutput inflateResult;
|
struct InflateOutput inflateResult;
|
||||||
|
@ -106,19 +112,17 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
//important: we must not modify uncompressedChunk since miniz may use it as dictionary and read from it during the next invocation of inflateInflate()
|
//important: we must not modify uncompressedChunk since miniz may use it as dictionary and read from it during the next invocation of inflateInflate()
|
||||||
|
|
||||||
//Write to stdout
|
//Optionally perform xdelta3
|
||||||
write(1, uncompressedChunk + uncompressedPosition, inflateResult.numBytesWrittenToOutput);
|
if (state.prevFile) {
|
||||||
|
xdelta3AddInput(uncompressedChunk + uncompressedPosition, inflateResult.numBytesWrittenToOutput, remainingBytes == 0 && hasReachedEnd);
|
||||||
|
} else { //otherwise write to stdout
|
||||||
|
write(1, uncompressedChunk + uncompressedPosition, inflateResult.numBytesWrittenToOutput);
|
||||||
|
}
|
||||||
|
|
||||||
uncompressedPosition += inflateResult.numBytesWrittenToOutput;
|
uncompressedPosition += inflateResult.numBytesWrittenToOutput;
|
||||||
while (uncompressedPosition >= BUFFER_SIZE) {
|
while (uncompressedPosition >= BUFFER_SIZE) {
|
||||||
uncompressedPosition -= BUFFER_SIZE;
|
uncompressedPosition -= BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Optionally perform xdelta3
|
|
||||||
if (state.prevFile) {
|
|
||||||
//TODO
|
|
||||||
fprintf(stderr, "xdelta3 is not yet implemented.\n");
|
|
||||||
errorAndExit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//release memory
|
//release memory
|
||||||
|
|
102
src/xdelta3.c
102
src/xdelta3.c
|
@ -2,7 +2,107 @@
|
||||||
#define SIZEOF_SIZE_T 4
|
#define SIZEOF_SIZE_T 4
|
||||||
#define static_assert(e,m) /* do nothing */
|
#define static_assert(e,m) /* do nothing */
|
||||||
#define XD3_ENCODER 0
|
#define XD3_ENCODER 0
|
||||||
|
#define XD3_USE_LARGESIZET 0
|
||||||
typedef unsigned int usize_t;
|
typedef unsigned int usize_t;
|
||||||
typedef unsigned long long xoff_t;
|
typedef unsigned long long xoff_t;
|
||||||
|
//Include xdelta3
|
||||||
|
#include "../lib/xdelta3/xdelta3.c"
|
||||||
|
|
||||||
#include "../lib/xdelta3/xdelta3.h"
|
//Include other libraries
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//Include our own files
|
||||||
|
#include "errorAndExit.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.\n", prevFile);
|
||||||
|
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) {
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
7
src/xdelta3.h
Normal file
7
src/xdelta3.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/** Initializes xdelta3 with the given previous file */
|
||||||
|
void xdelta3Init(char* prevFile);
|
||||||
|
|
||||||
|
/** Supplies the given input buffer to xdelta3 and undiffs the data. */
|
||||||
|
void xdelta3AddInput(unsigned char* inputBuffer, unsigned int inputLength, bool isLastPart);
|
Loading…
Reference in a new issue