Merge 14981:15268 from trunk
[reactos.git] / rosapps / lib / dflat32 / decomp.c
1 /* ------------------- decomp.c -------------------- */
2
3 /*
4 * Decompress the application.HLP file
5 * or load the application.TXT file if the .HLP file
6 * does not exist
7 */
8
9 #include "dflat32/dflat.h"
10 #include "dflat32/htree.h"
11
12 static int in8;
13 static int ct8 = 8;
14 static FILE *fi;
15 static BYTECOUNTER bytectr;
16 static int LoadingASCII;
17 struct htr *HelpTree;
18 static int root;
19
20 /* ------- open the help database file -------- */
21 FILE *OpenHelpFile(void)
22 {
23 char *cp;
24 int treect, i;
25 char helpname[65];
26
27 /* -------- get the name of the help file ---------- */
28 BuildFileName(helpname, ".hlp");
29 LoadingASCII = FALSE;
30 if ((fi = fopen(helpname, "rb")) == NULL) {
31 /* ---- no .hlp file, look for .txt file ---- */
32 if ((cp = strrchr(helpname, '.')) != NULL) {
33 strcpy(cp, ".TXT");
34 fi = fopen(helpname, "rt");
35 }
36 if (fi == NULL)
37 return NULL;
38 LoadingASCII = TRUE;
39 }
40
41 if (!LoadingASCII && HelpTree == NULL) {
42 /* ----- read the byte count ------ */
43 fread(&bytectr, sizeof bytectr, 1, fi);
44 /* ----- read the frequency count ------ */
45 fread(&treect, sizeof treect, 1, fi);
46 /* ----- read the root offset ------ */
47 fread(&root, sizeof root, 1, fi);
48 HelpTree = DFcalloc(treect-256, sizeof(struct htr));
49 /* ---- read in the tree --- */
50 for (i = 0; i < treect-256; i++) {
51 fread(&HelpTree[i].left, sizeof(int), 1, fi);
52 fread(&HelpTree[i].right, sizeof(int), 1, fi);
53 }
54 }
55 return fi;
56 }
57
58 /* ----- read a line of text from the help database ----- */
59 void *GetHelpLine(char *line)
60 {
61 int h;
62 if (LoadingASCII) {
63 void *hp;
64 do
65 hp = fgets(line, 160, fi);
66 while (*line == ';');
67 return hp;
68 }
69 *line = '\0';
70 while (TRUE) {
71 /* ----- decompress a line from the file ------ */
72 h = root;
73 /* ----- walk the Huffman tree ----- */
74 while (h > 255) {
75 /* --- h is a node pointer --- */
76 if (ct8 == 8) {
77 /* --- read 8 bits of compressed data --- */
78 if ((in8 = fgetc(fi)) == EOF) {
79 *line = '\0';
80 return NULL;
81 }
82 ct8 = 0;
83 }
84 /* -- point to left or right node based on msb -- */
85 if (in8 & 0x80)
86 h = HelpTree[h-256].left;
87 else
88 h = HelpTree[h-256].right;
89 /* --- shift the next bit in --- */
90 in8 <<= 1;
91 ct8++;
92 }
93 /* --- h < 255 = decompressed character --- */
94 if (h == '\r')
95 continue; /* skip the '\r' character */
96 /* --- put the character in the buffer --- */
97 *line++ = h;
98 /* --- if '\n', end of line --- */
99 if (h == '\n')
100 break;
101 }
102 *line = '\0'; /* null-terminate the line */
103 return line;
104 }
105
106 /* --- compute the database file byte and bit position --- */
107 void HelpFilePosition(long *offset, int *bit)
108 {
109 *offset = ftell(fi);
110 if (LoadingASCII)
111 *bit = 0;
112 else {
113 if (ct8 < 8)
114 --*offset;
115 *bit = ct8;
116 }
117 }
118
119 /* -- position the database to the specified byte and bit -- */
120 void SeekHelpLine(long offset, int bit)
121 {
122 int i;
123 fseek(fi, offset, 0);
124 if (!LoadingASCII) {
125 ct8 = bit;
126 if (ct8 < 8) {
127 in8 = fgetc(fi);
128 for (i = 0; i < bit; i++)
129 in8 <<= 1;
130 }
131 }
132 }
133
134