Blob Blame Raw

#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;
}