Skip to content

Instantly share code, notes, and snippets.

@romuloceccon
Last active December 31, 2015 06:58
Show Gist options
  • Select an option

  • Save romuloceccon/7950566 to your computer and use it in GitHub Desktop.

Select an option

Save romuloceccon/7950566 to your computer and use it in GitHub Desktop.
xdelta3 decode test
.PHONY: all
all : xdeltadecode
xdeltadecode : xdeltadecode.o xdelta3.o
gcc -o $@ $^ -llzma
%.o :
gcc -Wall -I /home/romulo/Downloads/xdelta3-3.0.6 -DHAVE_CONFIG_H -DXD3_POSIX=1 -DXD3_USE_LARGEFILE64=1 -DNOT_MAIN -c $^ -o $@
xdeltadecode.o : xdeltadecode.c
xdelta3.o : /home/romulo/Downloads/xdelta3-3.0.6/xdelta3.c
#include <xdelta3.h>
#include <stdio.h>
static const int block_size = 32768;
char source_buffer[32768];
int do_input(xd3_stream *stream, char *input_buffer, int input_size,
FILE *source_file, FILE *output_file)
{
int ret;
xd3_source *source;
int nread, nwrite;
xd3_avail_input(stream, (unsigned char *) input_buffer, input_size);
while (1)
{
ret = xd3_decode_input(stream);
if (ret == XD3_INPUT)
return 0;
if (ret == XD3_OUTPUT)
{
nwrite = fwrite(stream->next_out, 1, stream->avail_out, output_file);
if (nwrite == -1)
{
fprintf(stderr, "fwrite failed\n");
return -1;
}
else
{
xd3_consume_output(stream);
fprintf(stderr, "wrote %d bytes\n", nwrite);
}
}
else if (ret == XD3_GETSRCBLK)
{
source = stream->src;
if (fseek(source_file, block_size * source->getblkno, SEEK_SET) == -1)
{
fprintf(stderr, "fseek failed (source)\n");
return -1;
}
nread = fread(source_buffer, 1, block_size, source_file);
if (nread == -1)
{
fprintf(stderr, "fread failed (source)\n");
return -1;
}/*
else
{
fprintf(stderr, "read %d bytes from source at block %zd\n", nread, source->getblkno);
}*/
source->curblkno = source->getblkno;
source->onblk = nread;
source->curblk = (unsigned char *) source_buffer;
}
else if (ret != XD3_GOTHEADER && ret != XD3_WINSTART && ret != XD3_WINFINISH)
{
fprintf(stderr, "xd3_decode_input failed: %d\n", ret);
return -1;
}
}
}
int decode_file(FILE *source_file, FILE *input_file, FILE *output_file)
{
int ret;
xd3_stream stream;
xd3_config config;
xd3_source source;
char input_buffer[block_size];
int nread;
int input_pos;
memset(&stream, 0, sizeof(stream));
memset(&config, 0, sizeof(config));
memset(&source, 0, sizeof(source));
xd3_init_config(&config, 0);
config.winsize = block_size;
ret = xd3_config_stream(&stream, &config);
if (ret != 0)
{
fprintf(stderr, "xd3_config_stream failed: %d\n", ret);
return -1;
}
source.ioh = source_file;
source.blksize = block_size;
source.curblkno = (xoff_t) -1;
source.curblk = NULL;
ret = xd3_set_source(&stream, &source);
if (ret != 0)
{
fprintf(stderr, "xd3_set_source failed: %d\n", ret);
return -1;
}
do
{
input_pos = ftell(input_file);
nread = fread(input_buffer, 1, block_size, input_file);
if (nread == -1)
{
fprintf(stderr, "fread failed (input)\n");
ret = -1;
break;
}
else
{
fprintf(stderr, "read %d bytes from input at byte %d\n", nread, input_pos);
}
if ((ret = do_input(&stream, input_buffer, nread, source_file, output_file)))
break;
} while (nread == block_size);
if (ret == 0)
ret = xd3_close_stream(&stream);
else
xd3_abort_stream(&stream);
xd3_free_stream(&stream);
return ret;
}
int main(int argc, char *argv[])
{
int res;
FILE *source, *input, *output;
if (argc != 4)
return 3;
source = fopen(argv[1], "r");
if (source == NULL)
return 2;
input = fopen(argv[2], "r");
if (input == NULL)
return 2;
output = fopen(argv[3], "w+");
if (output == NULL)
return 2;
res = decode_file(source, input, output);
fclose(source);
fclose(input);
fclose(output);
if (res)
return 1;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment