home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / bbbsr2.zip / misc / msgview.c < prev    next >
C/C++ Source or Header  |  1997-06-26  |  5KB  |  157 lines

  1. /* $Id: msgview.c,v 1.1 1996/11/05 18:49:44 b Exp $ */
  2.  
  3. #define __BBBS_NO_EXTERNS__
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include "bbbsdef.h"
  7.  
  8. /* 
  9.  * The probabilities of all characters. These are generated from my
  10.  * message base a long time ago. They might not be optimal for today's
  11.  * messages, but close to it anyway. Note the zeros (0-31, 127, 255).
  12.  */
  13.  
  14. long prob[256]={
  15. 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,
  16. 2688178,22507,10532,10785,1030,1938,1988,18628,39803,46743,48027,9695,
  17. 89854,156418,216849,33096,77158,69186,90106,36509,29784,31908,19369,
  18. 16922,19979,30665,66818,6498,2965,17669,73798,28337,311,50889,43547,
  19. 29496,25005,43291,18512,16180,28333,45128,24129,26630,27169,60235,30926,
  20. 49095,32264,3198,29501,80544,57730,13651,18069,10699,4898,8495,2736,516,
  21. 1504,493,2477,14580,613,841426,45761,65887,126778,720498,50492,75721,
  22. 186931,844770,103502,322169,422678,253604,667615,510966,141568,2547,
  23. 275806,552109,728818,332062,138751,36308,12000,140316,4946,634,404,277,
  24. 2762,0,13,71,138,162,268060,16,1179,14,28,30,24,19,53,31,4608,1185,1413,
  25. 74,21,22,23699,28,22,29,3,1899,29,9,22,9,18,15,45,14,40,6,7,15,10,5,69,
  26. 11,4,47,11,17,35,2391,515,1167,650,1227,6,12,12,9,7,19,159,19,18,5,11,15,
  27. 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,
  28. 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,
  29. 12,7,24,29,564,51,153,70,5,9,2150,0};
  30.  
  31. struct {
  32.   int c0, c1;
  33.   long p;
  34. } tree[445];
  35.  
  36. /*
  37.  * Generate an optimal Huffman tree with all chars (p>0). Slow...
  38.  *
  39.  * This routine is only an example, you should use static pre-generated tree
  40.  * in your own program. In BBBS, for example, this tree (two trees, another
  41.  * for packing and another for unpacking) is formatted and packed to 223 32bit 
  42.  * numbers.
  43.  */
  44.  
  45. void init_huff(void) {
  46.   int w, next, min1, min2;
  47.  
  48.   for (w=0; w<223; w++) {
  49.     tree[w].c0=0xFFFF;
  50.     tree[w].c1=0xFFFF;
  51.     tree[w].p =prob[w+32];
  52.   }
  53.   tree[444].p=0x7FFFFFFF;
  54.   for (next=223; next<444; next++) {
  55.     min1=444;
  56.     min2=444;
  57.     for (w=0; w<next; w++)
  58.       if (tree[w].p>0)
  59.         if (tree[w].p<tree[min1].p) {
  60.           min2=min1;
  61.           min1=w;
  62.         } else
  63.           if (tree[w].p<tree[min2].p) min2=w;
  64.  
  65.     tree[next].p=tree[min1].p+tree[min2].p;
  66.     tree[next].c0=min1;
  67.     tree[next].c1=min2;
  68.     tree[min1].p=0;
  69.     tree[min2].p=0;
  70.   }
  71. }
  72.  
  73. void unpack(byte *s) {
  74.   if (*s<128) {     /* not packed, first char (len) is <128 */
  75.     s[*s+1]=0;
  76.     strcpy(s,s+1);
  77.   } else {          /* packed, len is >=128 (actual packed len is (len-128)*8 bits) */
  78.     int b, i, w, p;
  79.     char s1[128], c;
  80.  
  81.     for (i=1, w=443, p=0, b=(int)(*s & 127) << 3; b; b--) {
  82.       if (!(b & 7)) c=s[i++];
  83.  
  84.       if (c & 1) w=tree[w].c1;
  85.       else w=tree[w].c0;
  86.  
  87.       if (w<223) {
  88.         s1[p++]=w+32;
  89.         w=443;
  90.       }
  91.  
  92.       c>>=1;
  93.     }
  94.     s1[p]=0;
  95.     strcpy(s,s1);
  96.   }
  97. }
  98.  
  99. /*
  100.  * How about packing, then? Well, you should know something about Huffman
  101.  * encoding first, so go to your library and read! For example Introduction
  102.  * to Algorithms (by Cormen, Leiserson and Rivest, pages 337-344) has a nice
  103.  * explanation.
  104.  *
  105.  * I will not include full source code for packing, though. If you really need
  106.  * it, it should be quite easy to code.
  107.  *
  108.  * - pack the string (fill last char with 1's)
  109.  * - if packed is longer than unpacked, save it as unpacked (len = len)
  110.  *   else save it as packed (len = bits/8 + 128)
  111.  *
  112.  *
  113.  * And remember, you can always save the message unpacked!
  114.  */
  115.  
  116. void main(int argc, char *argv[]) {
  117.   FILE *fh, *ft;
  118.   struct msgrec h;
  119.   int i;
  120.   char s[128];
  121.  
  122.   init_huff(); /* initialize Huffman stuff */
  123.   if (argc==2) {
  124.     sprintf(s,"%s.hdr",argv[1]);
  125.     fh=fopen(s,"rb");
  126.     sprintf(s,"%s.txt",argv[1]);
  127.     ft=fopen(s,"rb");
  128.     while (fread(&h,1,sizeof(h),fh)) {
  129.       printf("#%u, %s, %02u.%02u.%04u\n",h.number,h.msgfrom,bun_day(h.dated),bun_month(h.dated),bun_year(h.dated)+1900);
  130.       fseek(ft,h.offset,SEEK_SET);
  131.       if (h.status & mstat_extraline) /* a kludge for kludges */
  132.         for (;;) {
  133.           *s=0;
  134.           fread(s,1,1,ft);
  135.           if (!*s) break;
  136.           fread(s+1,1,(byte)s[0] & 127,ft);
  137.           unpack(s);
  138.           printf("@%s\n",s);
  139.         }
  140.       for (i=0; i<h.lines; ) {     /* message text */
  141.         *s=0;
  142.         fread(s,1,1,ft);
  143.         if (*s) fread(s+1,1,(byte)s[0] & 127,ft);
  144.         unpack(s);
  145.         if (*s==1) printf("@%s\n",s+1);
  146.         else {
  147.           printf("%s\n",s);
  148.           i++;
  149.         }
  150.       }
  151.       printf("\f\n");
  152.     }
  153.     fclose(ft);
  154.     fclose(fh);
  155.   } else fprintf(stderr,"example \"%s 00000001\" in main directory",argv[0]);
  156. }
  157.