#include "arch.h"
#include "buffer.c"
#include "arch.c"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void die(const char *msg) {
fputs(msg, stderr);
fputc('\n', stderr);
fflush(stderr);
exit(1);
}
void usage()
{ die( "Usage: arch deflate|inflate <input> <output>" ); }
void print_buffer(const char *name, const Buffer *b) {
printf("%s: %p, size: %d, processed: %d, bits: %d, remain: %d\n",
name,
b->begin,
(int)(b->end - b->begin),
(int)(b->cur - b->begin),
(int)b->bits,
(int)(b->end - b->cur) );
}
int main(int argc, char **argv) {
if (argc != 4) usage();
int mode;
if (!strcmp(argv[1], "deflate")) mode = 0; else
if (!strcmp(argv[1], "inflate")) mode = 1; else usage();
FILE *fi = fopen(argv[2], "rb");
if (!fi) die("cannot open input file");
FILE *fo = fopen(argv[3], "wb");
if (!fo) die("cannot open output file");
Arch a;
if (RES_DONE != arch_init(&a)) die("cannot init arch");
size_t size = 1024*1024;
Byte *buf0 = malloc(2*size), *buf1 = buf0 + size;
if (!buf0) die("not enough memory");
a.rb.begin = a.rb.cur = a.rb.end = buf0;
a.wb.begin = a.wb.cur = buf1; a.wb.end = a.wb.begin + size;
int res = RES_RETRY;
while(res == RES_RETRY) {
// move previously read data into a beginning of the buffer
assert(a.rb.cur <= a.rb.end);
size_t s = a.rb.end - a.rb.cur;
memmove(a.rb.begin, a.rb.cur, s);
a.rb.cur = a.rb.begin;
a.rb.end = a.rb.cur + s;
// read new data into a remaining part of the buffer
assert(a.rb.begin + size >= a.rb.end);
s = a.rb.begin + size - a.rb.end;
s = fread(a.rb.end, 1, s, fi);
if (!s && ferror(fi)) die("cannot read from the input file");
a.rb.end += s;
//print_buffer("read buffer", &a.rb);
// process data
res = mode ? arch_inflate(&a, !s) : arch_deflate(&a, !s);
if (res == RES_FAIL) die("arch failed");
//printf("res: %d\n", res);
//print_buffer("write buffer", &a.wb);
// write results
if (a.wb.cur > a.wb.begin) {
if (!fwrite(a.wb.begin, a.wb.cur - a.wb.begin, 1, fo)) die("cannot write into the output file");
if (a.wb.bits) *a.wb.begin = *a.wb.cur;
a.wb.cur = a.wb.begin;
}
}
arch_deinit(&a);
free(buf0);
fclose(fo);
fclose(fi);
return 0;
}