Add trivial HM decoder
authorfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Fri, 14 Oct 2005 23:40:00 +0000 (23:40 +0000)
committerfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Fri, 14 Oct 2005 23:40:00 +0000 (23:40 +0000)
git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/doldaconnect@358 959494ce-11ee-0310-bf91-de5d638817bd

daemon/hmdec.c [new file with mode: 0644]

diff --git a/daemon/hmdec.c b/daemon/hmdec.c
new file mode 100644 (file)
index 0000000..bf11c1f
--- /dev/null
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+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);
+}