diff --git a/compress-test/simple1.c b/compress-test/simple1.c new file mode 100644 index 0000000..91bf565 --- /dev/null +++ b/compress-test/simple1.c @@ -0,0 +1,199 @@ +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 32 + +int refill_input_buffer(FILE *fp, b_ringbuffer *dest) +{ + while (1) { + void *buf; + size_t capacity; + b_status status + = b_ringbuffer_open_write_buffer(dest, &buf, &capacity); + if (status == B_ERR_NO_SPACE) { + break; + } + + if (!B_OK(status)) { + return -1; + } + + size_t r = fread(buf, 1, capacity, fp); + + b_ringbuffer_close_write_buffer(dest, &buf, r); + + if (r == 0) { + return ferror(fp) ? -1 : 0; + } + + if (r < capacity) { + break; + } + } + + return 0; +} + +int flush_output_buffer(FILE *fp, b_ringbuffer *src) +{ + while (1) { + void *buf; + size_t capacity; + b_status status + = b_ringbuffer_open_read_buffer(src, &buf, &capacity); + if (status == B_ERR_NO_DATA) { + break; + } + + if (!B_OK(status)) { + return -1; + } + + size_t w = fwrite(buf, 1, capacity, fp); + + b_ringbuffer_close_read_buffer(src, &buf, w); + + if (w < capacity) { + return -1; + } + } + + return 0; +} + +int main(int argc, const char **argv) +{ + if (argc < 4) { + fprintf(stderr, "usage: %s \n", argv[0]); + return -1; + } + + const b_compression_function *zstd + = b_compression_function_get_by_id(B_COMPRESSOR_FUNCTION_ZSTD); + if (!zstd) { + fprintf(stderr, "zstd support not enabled\n"); + return -1; + } + + b_compressor_mode mode; + if (!strcmp(argv[1], "C")) { + mode = B_COMPRESSOR_MODE_COMPRESS; + } else if (!strcmp(argv[1], "D")) { + mode = B_COMPRESSOR_MODE_DECOMPRESS; + } else { + fprintf(stderr, "invalid mode %s\n", argv[1]); + return -1; + } + + size_t inbuf_size, outbuf_size; + b_compression_function_get_buffer_size( + zstd, mode, &inbuf_size, &outbuf_size); + + b_ringbuffer *in = b_ringbuffer_create(inbuf_size); + b_ringbuffer *out = b_ringbuffer_create(outbuf_size); + + if (!in || !out) { + fprintf(stderr, "memory allocation failure"); + return -1; + } + + FILE *in_fp = fopen(argv[2], "rb"); + if (!in_fp) { + fprintf(stderr, "cannot open input file %s\n", argv[2]); + return -1; + } + + FILE *out_fp = fopen(argv[3], "wb"); + if (!out_fp) { + fclose(in_fp); + fprintf(stderr, "cannot open output file %s\n", argv[3]); + return -1; + } + + b_compressor *compressor; + b_status status = b_compressor_create(zstd, mode, in, out, &compressor); + if (!B_OK(status)) { + fprintf(stderr, "cannot initialise compressor\n"); + fclose(in_fp); + fclose(out_fp); + return -1; + } + + int ret = 0; + while (1) { + ret = refill_input_buffer(in_fp, in); + if (ret != 0) { + fprintf(stderr, "read error\n"); + break; + } + + if (!b_ringbuffer_available_data_remaining(in)) { + break; + } + + switch (mode) { + case B_COMPRESSOR_MODE_COMPRESS: + status = b_compressor_compress(compressor); + break; + case B_COMPRESSOR_MODE_DECOMPRESS: + status = b_compressor_decompress(compressor); + break; + } + + if (status == B_ERR_NO_DATA) { + break; + } else if (status == B_ERR_NO_SPACE) { + ret = flush_output_buffer(out_fp, out); + if (ret != 0) { + fprintf(stderr, "write error\n"); + break; + } + } else if (!B_OK(status)) { + ret = -1; + break; + } + } + + ret = flush_output_buffer(out_fp, out); + if (ret != 0) { + fprintf(stderr, "write error\n"); + return -1; + } + + if (mode == B_COMPRESSOR_MODE_COMPRESS) { + while (!b_compressor_eof(compressor)) { + status = b_compressor_compress_end(compressor); + if (!B_OK(status)) { + fprintf(stderr, + "compression finalisation error\n"); + return -1; + } + + if (!b_ringbuffer_available_data_remaining(out)) { + break; + } + + ret = flush_output_buffer(out_fp, out); + if (ret != 0) { + fprintf(stderr, "write error\n"); + return -1; + } + } + } + + printf("Done\n"); + + b_compressor_destroy(compressor); + + fclose(in_fp); + fclose(out_fp); + + b_ringbuffer_destroy(in); + b_ringbuffer_destroy(out); + + return ret; +}