| // |
| // Permission to distribute this example by |
| // Copyright (C) 2007 Ralf Junker |
| // Ralf Junker <delphi@yunqa.de> |
| // http://www.yunqa.de/delphi/ |
| |
| //--------------------------------------------------------------------------- |
| |
| #include <stdio.h> |
| #include <sys/stat.h> |
| #include "xdelta3.h" |
| #include "xdelta3.c" |
| |
| //--------------------------------------------------------------------------- |
| |
| int code ( |
| int encode, |
| FILE* InFile, |
| FILE* SrcFile , |
| FILE* OutFile, |
| int BufSize ) |
| { |
| int r, ret; |
| struct stat statbuf; |
| xd3_stream stream; |
| xd3_config config; |
| xd3_source source; |
| void* Input_Buf; |
| int Input_Buf_Read; |
| |
| if (BufSize < XD3_ALLOCSIZE) |
| BufSize = XD3_ALLOCSIZE; |
| |
| memset (&stream, 0, sizeof (stream)); |
| memset (&source, 0, sizeof (source)); |
| |
| xd3_init_config(&config, XD3_ADLER32); |
| config.winsize = BufSize; |
| xd3_config_stream(&stream, &config); |
| |
| if (SrcFile) |
| { |
| r = fstat(fileno(SrcFile), &statbuf); |
| if (r) |
| return r; |
| source.size = statbuf.st_size; |
| source.blksize = BufSize; |
| source.curblk = malloc(source.blksize); |
| |
| /* Load 1st block of stream. */ |
| r = fseek(SrcFile, 0, SEEK_SET); |
| if (r) |
| return r; |
| source.onblk = fread((void*)source.curblk, 1, source.blksize, SrcFile); |
| source.curblkno = 0; |
| /* Set the stream. */ |
| xd3_set_source(&stream, &source); |
| } |
| |
| Input_Buf = malloc(BufSize); |
| |
| fseek(InFile, 0, SEEK_SET); |
| do |
| { |
| Input_Buf_Read = fread(Input_Buf, 1, BufSize, InFile); |
| if (Input_Buf_Read < BufSize) |
| { |
| xd3_set_flags(&stream, XD3_FLUSH | stream.flags); |
| } |
| xd3_avail_input(&stream, Input_Buf, Input_Buf_Read); |
| |
| process: |
| if (encode) |
| ret = xd3_encode_input(&stream); |
| else |
| ret = xd3_decode_input(&stream); |
| |
| switch (ret) |
| { |
| case XD3_INPUT: |
| { |
| fprintf (stderr,"XD3_INPUT\n"); |
| continue; |
| } |
| |
| case XD3_OUTPUT: |
| { |
| fprintf (stderr,"XD3_OUTPUT\n"); |
| r = fwrite(stream.next_out, 1, stream.avail_out, OutFile); |
| if (r != (int)stream.avail_out) |
| return r; |
| xd3_consume_output(&stream); |
| goto process; |
| } |
| |
| case XD3_GETSRCBLK: |
| { |
| fprintf (stderr,"XD3_GETSRCBLK %qd\n", source.getblkno); |
| if (SrcFile) |
| { |
| r = fseek(SrcFile, source.blksize * source.getblkno, SEEK_SET); |
| if (r) |
| return r; |
| 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,"!!! INVALID %s %d !!!\n", |
| stream.msg, ret); |
| return ret; |
| } |
| |
| } |
| |
| } |
| while (Input_Buf_Read == BufSize); |
| |
| free(Input_Buf); |
| |
| free((void*)source.curblk); |
| xd3_close_stream(&stream); |
| xd3_free_stream(&stream); |
| |
| return 0; |
| |
| }; |
| |
| |
| int main(int argc, char* argv[]) |
| { |
| FILE* InFile; |
| FILE* SrcFile; |
| FILE* OutFile; |
| int r; |
| |
| if (argc != 3) { |
| fprintf (stderr, "usage: %s source input output\n", argv[0]); |
| return 1; |
| } |
| |
| char *input = argv[2]; |
| char *source = argv[1]; |
| const char *output = "encoded.testdata"; |
| const char *decoded = "decoded.testdata"; |
| |
| /* Encode */ |
| |
| InFile = fopen(input, "rb"); |
| SrcFile = fopen(source, "rb"); |
| OutFile = fopen(output, "wb"); |
| |
| r = code (1, InFile, SrcFile, OutFile, 0x1000); |
| |
| fclose(OutFile); |
| fclose(SrcFile); |
| fclose(InFile); |
| |
| if (r) { |
| fprintf (stderr, "Encode error: %d\n", r); |
| return r; |
| } |
| |
| /* Decode */ |
| |
| InFile = fopen(output, "rb"); |
| SrcFile = fopen(source, "rb"); |
| OutFile = fopen(decoded, "wb"); |
| |
| r = code (0, InFile, SrcFile, OutFile, 0x1000); |
| |
| fclose(OutFile); |
| fclose(SrcFile); |
| fclose(InFile); |
| |
| if (r) { |
| fprintf (stderr, "Decode error: %d\n", r); |
| return r; |
| } |
| |
| return 0; |
| } |