home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
bbbsr2.zip
/
misc
/
msgview.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-26
|
5KB
|
157 lines
/* $Id: msgview.c,v 1.1 1996/11/05 18:49:44 b Exp $ */
#define __BBBS_NO_EXTERNS__
#include <stdio.h>
#include <stdlib.h>
#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; w<next; w++)
if (tree[w].p>0)
if (tree[w].p<tree[min1].p) {
min2=min1;
min1=w;
} else
if (tree[w].p<tree[min2].p) min2=w;
tree[next].p=tree[min1].p+tree[min2].p;
tree[next].c0=min1;
tree[next].c1=min2;
tree[min1].p=0;
tree[min2].p=0;
}
}
void unpack(byte *s) {
if (*s<128) { /* not packed, first char (len) is <128 */
s[*s+1]=0;
strcpy(s,s+1);
} else { /* packed, len is >=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<h.lines; ) { /* message text */
*s=0;
fread(s,1,1,ft);
if (*s) fread(s+1,1,(byte)s[0] & 127,ft);
unpack(s);
if (*s==1) printf("@%s\n",s+1);
else {
printf("%s\n",s);
i++;
}
}
printf("\f\n");
}
fclose(ft);
fclose(fh);
} else fprintf(stderr,"example \"%s 00000001\" in main directory",argv[0]);
}