#include #include #include #include #include #include #include #include #include #include #define CHUNK 16384 #define CHUNK_IN CHUNK #define CHUNK_OUT (CHUNK_IN << 1) /* Ensure enough output space */ enum encode_mode { UNKNOWN, SOLE, SOLEGMP, NAIVE }; void usage(const char *msg, char *args[]) { if (msg) fprintf(stderr, "%s\n", msg); fprintf(stderr, "usage: %s [-h|--help] <[--sole|--naive|--sole-gmp]> \n", args[0]); exit(1); } void print_err(const char *msg) { fprintf(stderr, "error: %s", msg); } int encode_sole(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) { print_err("Init failed\n"); return ret; } do { strm.avail_in = fread(in, 1, CHUNK_IN, source); if (ferror(source)) { print_err("Could not read input!\n"); return SOLE_ERRNO; } eof = feof(source); strm.inp = in; strm.avail_out = CHUNK_OUT; strm.outp = out; ret = sole_encode(&strm); if (ret != 0) { print_err("Could not encode\n"); return ret; } /* Consume encoded values */ if (!eof) { available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { print_err("Writing output"); return SOLE_ERRNO; } } } while (!eof); sole_encode_end(&strm); available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { print_err("Writing output"); return SOLE_ERRNO; } /* 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) { print_err("Init failed\n"); return ret; } do { strm.avail_in = fread(in, 1, CHUNK_IN, source); if (ferror(source)) { print_err("Could not read input!\n"); return NAIVE_ERRNO; } eof = feof(source); strm.inp = in; strm.avail_out = CHUNK_OUT; strm.outp = out; ret = naive_encode(&strm); if (ret) { print_err("Could not encode\n"); return ret; } /* Consume encoded values */ if (!eof) { available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { print_err("error: Writing output"); return NAIVE_ERRNO; } } } while (!eof); naive_encode_end(&strm); 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 encode_gmp(FILE *source, FILE *dest) { int ret, eof; uint available; soleg_stream strm; unsigned char in[CHUNK_IN]; unsigned char out[CHUNK_OUT]; ret = soleg_stream_init(&strm); if (ret != SOLEG_OK) { print_err("Init failed\n"); return ret; } do { strm.avail_in = fread(in, 1, CHUNK_IN, source); if (ferror(source)) { print_err("Could not read input!\n"); return SOLEG_ERRNO; } eof = feof(source); strm.inp = in; strm.avail_out = CHUNK_OUT; strm.outp = out; ret = soleg_encode(&strm); if (ret != 0) { print_err("Could not encode\n"); return ret; } /* Consume encoded values */ if (!eof) { available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { print_err("Writing output"); return SOLEG_ERRNO; } } } while (!eof); soleg_encode_end(&strm); available = CHUNK_OUT - strm.avail_out; if (fwrite(out, 1, available, dest) != available || ferror(dest)) { print_err("Writing output"); return SOLEG_ERRNO; } /* Missing encoded EOF */ soleg_stream_free(&strm); return SOLEG_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("%f\n", time_spent); return ret; } int get_encode_mode(const char *arg) { if (!strcmp(arg, "--sole")) return SOLE; if (!strcmp(arg, "--naive")) return NAIVE; if (!strcmp(arg, "--sole-gmp")) return SOLEGMP; return UNKNOWN; } /* Method: This program takes a size, an iteration count and a method name and does the following: */ int main(int argc, char *argv[]) { if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) usage(NULL, argv); if (argc < 4) usage("Must have at least three arguments: encoding mode, input and output\n", argv); int mode = get_encode_mode(argv[1]); if (mode == UNKNOWN) usage("Could not determine encoding mode\n", argv); FILE *source = fopen(argv[2], "rb"); if (source == NULL) { fprintf(stderr, "error: Could not open input file '%s'\n", argv[2]); return 1; } FILE *dest = fopen(argv[3], "wb"); if (dest == NULL) { fprintf(stderr, "error: Could not open output '%s'.\n", argv[3]); return 1; } int ret = 0; switch (mode) { case SOLE: ret = time_call(encode_sole, source, dest); break; case NAIVE: ret = time_call(encode_naive, source, dest); break; case SOLEGMP: ret = time_call(encode_gmp, source, dest); } fclose(source); fclose(dest); return ret; }