From: fredrik Date: Fri, 14 Oct 2005 23:40:00 +0000 (+0000) Subject: Add trivial HM decoder X-Git-Tag: 0.1~217 X-Git-Url: http://dolda2000.com/gitweb/?a=commitdiff_plain;h=d72b557161cb62387d2d6b0311fa664ba09d1655;p=doldaconnect.git Add trivial HM decoder git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/doldaconnect@358 959494ce-11ee-0310-bf91-de5d638817bd --- diff --git a/daemon/hmdec.c b/daemon/hmdec.c new file mode 100644 index 0000000..bf11c1f --- /dev/null +++ b/daemon/hmdec.c @@ -0,0 +1,99 @@ +#include +#include + +struct node +{ + int l, r, c; +}; + +struct node tree[512]; +int newnode = 1; + +int getbits(int numbits) +{ + static int cb = 8, c; + int ret; + + if(numbits < 0) + { + cb = 8; + return(0); + } + ret = 0; + for(; numbits > 0; numbits--) + { + if(cb >= 8) + { + c = getc(stdin); + cb = 0; + } + ret <<= 1; + if(c & (1 << (cb++))) + ret |= 1; + } + return(ret); +} + +int main(int argc, char **argv) { + int i, o; + int n; + int size, ts, c; + int chars[256], lens[256]; + + for(i = 0; i < 512; i++) + tree[i].l = tree[i].r = tree[i].c = -1; + if((getc(stdin) != 'H') || + (getc(stdin) != 'E') || + (getc(stdin) != '3') || + (getc(stdin) != 13)) { + fprintf(stderr, "not a HE3 file\n"); + exit(1); + } + getc(stdin); + fread(&size, 4, 1, stdin); + ts = 0; + fread(&ts, 2, 1, stdin); + for(i = 0; i < ts; i++) { + chars[i] = getc(stdin); + lens[i] = getc(stdin); + } + for(i = 0; i < ts; i++) { + n = 0; + for(o = 0; o < lens[i]; o++) { + if(getbits(1)) { + if(tree[n].r < 0) + n = tree[n].r = newnode++; + else + n = tree[n].r; + } else { + if(tree[n].l < 0) + n = tree[n].l = newnode++; + else + n = tree[n].l; + } + } + if(tree[n].c >= 0) { + fprintf(stderr, "double-used node: \"%c\"\n", chars[i]); + exit(1); + } + tree[n].c = chars[i]; + } + getbits(-1); + n = 0; + for(i = 0; i < size;) { + if(getbits(1)) + n = tree[n].r; + else + n = tree[n].l; + if(n < 0) { + fprintf(stderr, "invalid path"); + exit(1); + } + if(tree[n].c >= 0) { + putc(tree[n].c, stdout); + n = 0; + i++; + } + } + return(0); +}