You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

100 lines
2.0 KiB

#include "assert.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "unistd.h"
#include "tree.h"
//Print to binary
static inline void itob(int i, int len, FILE *f) {
for (int j = len-1; j > -1; --j) {
fputc('0' + ((i >> j) & 1), f);
}
}
//LZ77 compression
void jabber(char *buff, int buff_len, FILE *f) {
tree *t = newt();
node *n = t->root;
int len = 0, bound = 1;
for (int i = 0; i < buff_len; ++i) {
if (buff[i] == '0') {
if (n->zero == NULL) {
n->zero = newn(++t->size);
itob(n->index, len, f);
fputc('0', f);
}
else {
n = n->zero;
continue;
}
}
else {
if (n->one == NULL) {
n->one = newn(++t->size);
itob(n->index, len, f);
fputc('1', f);
fflush(f);
}
else {
n = n->one;
continue;
}
}
//Reset node after printing
n = t->root;
//Check if upper bound needs to be increased
if (t->size == bound) {
++len;
bound <<= 1;
}
}
//Print last index
if (!isleaf(n))
itob(n->index, len, f);
}
int main(int argc, char **argv) {
assert(argc == 3);
struct stat sbuf = {};
if (stat(argv[1], &sbuf) != 0) {
fprintf(stderr, "Error finding file\n");
return -1;
}
//Assume we can read the file
char *inbuff = (char*) malloc((sbuf.st_size+1) * sizeof(char));
char *outbuff = (char*) malloc((sbuf.st_size+1) * sizeof(char));
int out_len = 0;
FILE *f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "Error opening input file\n");
return -1;
}
if (fread(inbuff, sizeof(char), sbuf.st_size, f) != sbuf.st_size) {
fclose(f);
fprintf(stderr, "Error reading file\n");
return -1;
}
//Close file when done reading
fclose(f);
f = fopen(argv[2], "w");
if (f == NULL) {
fprintf(stderr, "Error opening output file\n");
return -1;
}
//Write contents of jabber back out
jabber(inbuff, sbuf.st_size, f);
fclose(f);
return 0;
}