Subscribed unsubscribe Subscribe Subscribe

短期記憶があるうちに。

#ifndef __GNUC__
#error ぐにゅ〜
#endif /* __GNUC__ */

#include <stdio.h>
#include <stdlib.h>
#include <bzlib.h>

#define UNUSED(def) def __attribute__((unused))

int doit(FILE *out_strm, FILE *in_strm)
{
    int err = 0;
    int bzerr;
    unsigned char in_buf[256];
    unsigned char out_buf[256];
    size_t nelems_read;
    size_t total_alloc_sz = 0;
    bz_stream bzs;

    void *alloc(UNUSED(void *opaque), int sz, int nelems) {
        size_t r = (size_t)sz * (size_t)nelems;
        if (r / (size_t)sz != (size_t)nelems)
            return NULL; /* ! */
        total_alloc_sz += sz;
        return malloc(r);
    }

    void release(UNUSED(void *opaque), void *ptr) {
        free(ptr);
    }

    bzs.bzalloc = alloc;
    bzs.bzfree = release;
    bzs.avail_in = 0;

    bzerr = BZ2_bzDecompressInit(&bzs, 1, 0);
    if (bzerr)
        return 1;

    for (;;) {
        if (bzs.avail_in == 0) {
            nelems_read = fread(in_buf, sizeof(*in_buf),
                    sizeof(in_buf) / sizeof(*in_buf), in_strm);
            if (nelems_read == 0) {
                if (ferror(in_strm)) {
                    err = 1;
                    goto out;
                } else {
                    break; /* end of file */
                }
            }
            bzs.next_in = in_buf;
            bzs.avail_in = nelems_read * sizeof(*in_buf);
        }

        bzs.next_out = out_buf;
        bzs.avail_out = sizeof(out_buf);
        fprintf(stderr, "avail_in=%tu\n", bzs.avail_in);
        bzerr = BZ2_bzDecompress(&bzs);
        fprintf(stderr, "  bzerr=%d\n", bzerr);
        if (bzerr < 0) {
            err = 1;
            goto out;
        }
        fprintf(stderr, "  avail_in=%tu\n", bzs.avail_in);
        fprintf(stderr, "  avail_out=%tu\n", bzs.avail_out);
        {
            size_t nelems_written;
            unsigned char *p = out_buf;
            while (p < (unsigned char *)bzs.next_out) {
                nelems_written = fwrite(p, sizeof(*out_buf),
                        (unsigned char *)bzs.next_out - p, out_strm);
                if (nelems_written == 0) {
                    err = 1;
                    goto out;
                }
                p += nelems_written;
            }
        }
    }

out:
    fprintf(stderr, "Total number of bytes allocated: %tu\n", total_alloc_sz);
    if (BZ2_bzDecompressEnd(&bzs))
        fprintf(stderr, "WARN: BZ2_bzDecompressEnd returned error status\n");
    return err;
}

int main(UNUSED(int argc), UNUSED(void *argv))
{
    return !doit(stdout, stdin) ? 1: 0;
}

復活。