/* $Id: msgview.c,v 1.1 1996/11/05 18:49:44 b Exp $ */ #define __BBBS_NO_EXTERNS__ #include #include #include "bbbsdef.h" /* * The probabilities of all characters. These are generated from my * message base a long time ago. They might not be optimal for today's * messages, but close to it anyway. Note the zeros (0-31, 127, 255). */ long prob[256]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2688178,22507,10532,10785,1030,1938,1988,18628,39803,46743,48027,9695, 89854,156418,216849,33096,77158,69186,90106,36509,29784,31908,19369, 16922,19979,30665,66818,6498,2965,17669,73798,28337,311,50889,43547, 29496,25005,43291,18512,16180,28333,45128,24129,26630,27169,60235,30926, 49095,32264,3198,29501,80544,57730,13651,18069,10699,4898,8495,2736,516, 1504,493,2477,14580,613,841426,45761,65887,126778,720498,50492,75721, 186931,844770,103502,322169,422678,253604,667615,510966,141568,2547, 275806,552109,728818,332062,138751,36308,12000,140316,4946,634,404,277, 2762,0,13,71,138,162,268060,16,1179,14,28,30,24,19,53,31,4608,1185,1413, 74,21,22,23699,28,22,29,3,1899,29,9,22,9,18,15,45,14,40,6,7,15,10,5,69, 11,4,47,11,17,35,2391,515,1167,650,1227,6,12,12,9,7,19,159,19,18,5,11,15, 32,85,96,24,2504,58,6,7,29,19,3,7,14,1571,4,3,14,9,8,4,7,12,7,5,8,14,21, 1281,385,151,178,610,34,98,8,4,118,7,17,8,268,8,6,10,5,5,9,9,68,7,20,3, 12,7,24,29,564,51,153,70,5,9,2150,0}; struct { int c0, c1; long p; } tree[445]; /* * Generate an optimal Huffman tree with all chars (p>0). Slow... * * This routine is only an example, you should use static pre-generated tree * in your own program. In BBBS, for example, this tree (two trees, another * for packing and another for unpacking) is formatted and packed to 223 32bit * numbers. */ void init_huff(void) { int w, next, min1, min2; for (w=0; w<223; w++) { tree[w].c0=0xFFFF; tree[w].c1=0xFFFF; tree[w].p =prob[w+32]; } tree[444].p=0x7FFFFFFF; for (next=223; next<444; next++) { min1=444; min2=444; for (w=0; w0) if (tree[w].p=128 (actual packed len is (len-128)*8 bits) */ int b, i, w, p; char s1[128], c; for (i=1, w=443, p=0, b=(int)(*s & 127) << 3; b; b--) { if (!(b & 7)) c=s[i++]; if (c & 1) w=tree[w].c1; else w=tree[w].c0; if (w<223) { s1[p++]=w+32; w=443; } c>>=1; } s1[p]=0; strcpy(s,s1); } } /* * How about packing, then? Well, you should know something about Huffman * encoding first, so go to your library and read! For example Introduction * to Algorithms (by Cormen, Leiserson and Rivest, pages 337-344) has a nice * explanation. * * I will not include full source code for packing, though. If you really need * it, it should be quite easy to code. * * - pack the string (fill last char with 1's) * - if packed is longer than unpacked, save it as unpacked (len = len) * else save it as packed (len = bits/8 + 128) * * * And remember, you can always save the message unpacked! */ void main(int argc, char *argv[]) { FILE *fh, *ft; struct msgrec h; int i; char s[128]; init_huff(); /* initialize Huffman stuff */ if (argc==2) { sprintf(s,"%s.hdr",argv[1]); fh=fopen(s,"rb"); sprintf(s,"%s.txt",argv[1]); ft=fopen(s,"rb"); while (fread(&h,1,sizeof(h),fh)) { printf("#%u, %s, %02u.%02u.%04u\n",h.number,h.msgfrom,bun_day(h.dated),bun_month(h.dated),bun_year(h.dated)+1900); fseek(ft,h.offset,SEEK_SET); if (h.status & mstat_extraline) /* a kludge for kludges */ for (;;) { *s=0; fread(s,1,1,ft); if (!*s) break; fread(s+1,1,(byte)s[0] & 127,ft); unpack(s); printf("@%s\n",s); } for (i=0; i