mirror of
https://github.com/reactos/reactos.git
synced 2024-10-31 03:48:17 +00:00
135 lines
3.5 KiB
C
135 lines
3.5 KiB
C
|
/* ------------------- decomp.c -------------------- */
|
||
|
|
||
|
/*
|
||
|
* Decompress the application.HLP file
|
||
|
* or load the application.TXT file if the .HLP file
|
||
|
* does not exist
|
||
|
*/
|
||
|
|
||
|
#include "dflat32/dflat.h"
|
||
|
#include "dflat32/htree.h"
|
||
|
|
||
|
static int in8;
|
||
|
static int ct8 = 8;
|
||
|
static FILE *fi;
|
||
|
static BYTECOUNTER bytectr;
|
||
|
static int LoadingASCII;
|
||
|
struct htr *HelpTree;
|
||
|
static int root;
|
||
|
|
||
|
/* ------- open the help database file -------- */
|
||
|
FILE *OpenHelpFile(void)
|
||
|
{
|
||
|
char *cp;
|
||
|
int treect, i;
|
||
|
char helpname[65];
|
||
|
|
||
|
/* -------- get the name of the help file ---------- */
|
||
|
BuildFileName(helpname, ".hlp");
|
||
|
LoadingASCII = FALSE;
|
||
|
if ((fi = fopen(helpname, "rb")) == NULL) {
|
||
|
/* ---- no .hlp file, look for .txt file ---- */
|
||
|
if ((cp = strrchr(helpname, '.')) != NULL) {
|
||
|
strcpy(cp, ".TXT");
|
||
|
fi = fopen(helpname, "rt");
|
||
|
}
|
||
|
if (fi == NULL)
|
||
|
return NULL;
|
||
|
LoadingASCII = TRUE;
|
||
|
}
|
||
|
|
||
|
if (!LoadingASCII && HelpTree == NULL) {
|
||
|
/* ----- read the byte count ------ */
|
||
|
fread(&bytectr, sizeof bytectr, 1, fi);
|
||
|
/* ----- read the frequency count ------ */
|
||
|
fread(&treect, sizeof treect, 1, fi);
|
||
|
/* ----- read the root offset ------ */
|
||
|
fread(&root, sizeof root, 1, fi);
|
||
|
HelpTree = DFcalloc(treect-256, sizeof(struct htr));
|
||
|
/* ---- read in the tree --- */
|
||
|
for (i = 0; i < treect-256; i++) {
|
||
|
fread(&HelpTree[i].left, sizeof(int), 1, fi);
|
||
|
fread(&HelpTree[i].right, sizeof(int), 1, fi);
|
||
|
}
|
||
|
}
|
||
|
return fi;
|
||
|
}
|
||
|
|
||
|
/* ----- read a line of text from the help database ----- */
|
||
|
void *GetHelpLine(char *line)
|
||
|
{
|
||
|
int h;
|
||
|
if (LoadingASCII) {
|
||
|
void *hp;
|
||
|
do
|
||
|
hp = fgets(line, 160, fi);
|
||
|
while (*line == ';');
|
||
|
return hp;
|
||
|
}
|
||
|
*line = '\0';
|
||
|
while (TRUE) {
|
||
|
/* ----- decompress a line from the file ------ */
|
||
|
h = root;
|
||
|
/* ----- walk the Huffman tree ----- */
|
||
|
while (h > 255) {
|
||
|
/* --- h is a node pointer --- */
|
||
|
if (ct8 == 8) {
|
||
|
/* --- read 8 bits of compressed data --- */
|
||
|
if ((in8 = fgetc(fi)) == EOF) {
|
||
|
*line = '\0';
|
||
|
return NULL;
|
||
|
}
|
||
|
ct8 = 0;
|
||
|
}
|
||
|
/* -- point to left or right node based on msb -- */
|
||
|
if (in8 & 0x80)
|
||
|
h = HelpTree[h-256].left;
|
||
|
else
|
||
|
h = HelpTree[h-256].right;
|
||
|
/* --- shift the next bit in --- */
|
||
|
in8 <<= 1;
|
||
|
ct8++;
|
||
|
}
|
||
|
/* --- h < 255 = decompressed character --- */
|
||
|
if (h == '\r')
|
||
|
continue; /* skip the '\r' character */
|
||
|
/* --- put the character in the buffer --- */
|
||
|
*line++ = h;
|
||
|
/* --- if '\n', end of line --- */
|
||
|
if (h == '\n')
|
||
|
break;
|
||
|
}
|
||
|
*line = '\0'; /* null-terminate the line */
|
||
|
return line;
|
||
|
}
|
||
|
|
||
|
/* --- compute the database file byte and bit position --- */
|
||
|
void HelpFilePosition(long *offset, int *bit)
|
||
|
{
|
||
|
*offset = ftell(fi);
|
||
|
if (LoadingASCII)
|
||
|
*bit = 0;
|
||
|
else {
|
||
|
if (ct8 < 8)
|
||
|
--*offset;
|
||
|
*bit = ct8;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* -- position the database to the specified byte and bit -- */
|
||
|
void SeekHelpLine(long offset, int bit)
|
||
|
{
|
||
|
int i;
|
||
|
fseek(fi, offset, 0);
|
||
|
if (!LoadingASCII) {
|
||
|
ct8 = bit;
|
||
|
if (ct8 < 8) {
|
||
|
in8 = fgetc(fi);
|
||
|
for (i = 0; i < bit; i++)
|
||
|
in8 <<= 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|