#include #include #include #include #include #include #include #include #include /* #define CHUNK 16384 */ #define CHUNK 4096 #define CHUNK_IN CHUNK #define CHUNK_OUT (CHUNK_IN << 1) /* Ensure enough output space */ void usage(char *args[]) { printf("usage: %s [-h|--help] [-d|--naive] [] []\n", args[0]); exit(0); } /* Debugging! */ /* #define print_output_blocks(strm, out) \ */ /* do { \ */ /* int i; \ */ /* uint64_t blk[2]; \ */ /* for (i = 0; i < CHUNK_OUT - strm.avail_out; i += BLK128SIZ) { \ */ /* memcpy(&blk, out + i, BLK128SIZ); \ */ /* printf("%lu,%lu,", blk[0], blk[1]); \ */ /* } \ */ /* } while(0) */ int encode(FILE *source, FILE *dest) { int ret, eof; uint available; sole_stream strm; unsigned char in[CHUNK_IN]; unsigned char out[CHUNK_OUT]; ret = sole_stream_init(&strm); if (ret != SOLE_OK) { printf("Init failed\n"); return ret; } do { strm.avail_in = fread(in, 1, CHUNK_IN, source); if (ferror(source)) { printf("error: Could not read input!\n"); return SOLE_ERRNO; } eof = feof(source); assert(strm.avail_in != 0); strm.inp = in; strm.avail_out = CHUNK_OUT; strm.outp = out; ret = sole_encode(&strm); if (ret != 0) { printf("error: Could not encode\n"); return ret; } /* if (!eof) */ /* print_output_blocks(strm, out); */ /* Consume encoded values */ if (!eof) { available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { printf("error: Writing output"); return SOLE_ERRNO; } } } while (!eof); sole_encode_end(&strm); /* print_output_blocks(strm, out); */ available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { printf("error: Writing output"); return SOLE_ERRNO; } /* Missing encoded EOF */ sole_stream_free(&strm); return SOLE_OK; } /** * Decode */ int decode(FILE *source, FILE *dest) { int ret; uint available; sole_stream strm; unsigned char in[CHUNK_IN]; unsigned char out[CHUNK_OUT]; ret = sole_stream_init(&strm); if (ret != SOLE_OK) { printf("Init failed\n"); return ret; } do { strm.avail_in = fread(in, 1, CHUNK_IN, source); if (ferror(source)) { printf("error: Could not read input!\n"); return SOLE_ERRNO; } strm.inp = in; strm.avail_out = CHUNK_OUT; strm.outp = out; ret = sole_decode(&strm); if (ret != SOLE_OK && ret != SOLE_DECODE_FINISH) { printf("error: Could not encode\n"); return ret; } /* print_output_blocks(strm, out); */ /* Consume encoded values */ available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { printf("error: Writing output"); return SOLE_ERRNO; } } while (ret != SOLE_DECODE_FINISH && !feof(source)); /* Missing encoded EOF */ sole_stream_free(&strm); return SOLE_OK; } int encode_naive(FILE *source, FILE *dest) { int ret, eof; uint available; naive_stream strm; unsigned char in[CHUNK_IN]; unsigned char out[CHUNK_OUT]; ret = naive_stream_init(&strm); if (ret != NAIVE_OK) { printf("Init failed\n"); return ret; } do { strm.avail_in = fread(in, 1, CHUNK_IN, source); if (ferror(source)) { printf("error: Could not read input!\n"); return NAIVE_ERRNO; } eof = feof(source); assert(strm.avail_in != 0); strm.inp = in; strm.avail_out = CHUNK_OUT; strm.outp = out; ret = naive_encode(&strm); if (ret != 0) { printf("error: Could not encode\n"); return ret; } /* if (!eof) */ /* print_output_blocks(strm, out); */ /* Consume encoded values */ if (!eof) { available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { printf("error: Writing output"); return NAIVE_ERRNO; } } } while (!eof); naive_encode_end(&strm); /* print_output_blocks(strm, out); */ available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { printf("error: Writing output"); return NAIVE_ERRNO; } return NAIVE_OK; } int time_call(int (*f)(FILE *source, FILE *dest), FILE *source, FILE *dest) { int ret; double time_spent; clock_t begin, end; begin = clock(); ret = f(source, dest); end = clock(); time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf("Time spent: %f\n", time_spent); return ret; } /** * Usage: ./sole_file [-d|--naive] [] [] */ int main(int argc, char *argv[]) { if (argc == 1) return encode(stdin, stdout); if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) usage(argv); int i = 1; int mode = strcmp(argv[1], "-d") ? (strcmp(argv[1], "--naive") ? 0 : 2) : 1; if (mode) i++; printf("mode=%d, i=%d\n", mode, i); FILE *source = stdin; if (argc > i) { source = fopen(argv[i], "rb"); if (source == NULL) { printf("Could not open file '%s'\n", argv[i]); return 1; } } FILE *dest = stdout; if (argc > ++i) { dest = fopen(argv[i], "wb"); if (dest == NULL) { printf("error: Could not open '%s'.\n", argv[i]); return 1; } } int ret; switch (mode) { case 0: ret = time_call(encode, source, dest); break; case 1: ret = time_call(decode, source, dest); break; case 2: ret = time_call(encode_naive, source, dest); break; } fclose(source); fclose(dest); return ret; }