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