source: trunk/gsdl/src/mgpp/text/comp_dict.cpp@ 2541

Last change on this file since 2541 was 2541, checked in by jrm21, 23 years ago

1) replaced obsolete bzero() calls with memset() calls.
2) Makefile.in fixed for c++ variables (CXX instead of CPP), and GSDLOS is now

set from configure, so files are installed in the right place.

3) text.pass1.cpp now prints an error message if index file can't be created.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/**************************************************************************
2 *
3 * comp_dict.cpp -- Functions for loading the compression dictionary
4 * Copyright (C) 1994 Neil Sharman
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 **************************************************************************/
21
22#include "sysfuncs.h"
23
24#include "huffman.h"
25#include "local_strings.h"
26#include "memlib.h"
27#include "messages.h"
28
29#include "mg.h"
30#include "hash.h"
31#include "text.h"
32#include "comp_dict.h"
33#include "locallib.h"
34#include "mg_files.h"
35
36compression_dict_header cdh;
37compressed_text_header cth;
38comp_frags_header cfh[2];
39
40dict_hash_table *ht[2];
41
42huff_data char_huff[2];
43huff_data lens_huff[2];
44u_long *char_codes[2], *lens_codes[2];
45u_long Words_disk = 0;
46u_long Chars_disk = 0;
47
48
49static dict_hash_table *
50ReadInWords (FILE * dict, comp_frags_header * cfh,
51 int esc)
52{
53 int i;
54 u_char *allwords, *prev = NULL;
55 dict_hash_table *ht;
56 u_char **words;
57 u_long ht_size;
58
59 ht_size = prime (cfh->hd.num_codes * HASH_RATIO);
60 if (!(ht = (dict_hash_table *) Xmalloc (sizeof (dict_hash_table) +
61 (ht_size - 1) * sizeof (ht->table[0]))))
62 {
63 Message ("no memory for hash_table\n");
64 return NULL;
65 }
66
67 ht->size = ht_size;
68 ht->hd = &cfh->hd;
69
70 if (!(ht->codes = Generate_Huffman_Codes (&cfh->hd, NULL)))
71 {
72 Message ("no memory for huffman codes\n");
73 return NULL;
74 }
75
76 if (!(ht->words = (u_char **) Xmalloc (sizeof (u_char *) * cfh->hd.num_codes)))
77 {
78 Message ("no memory for word pointers\n");
79 return NULL;
80 }
81 words = ht->words;
82
83 memset (ht->table, '\0', ht_size * sizeof (ht->table[0]));
84
85 if (!(allwords = (u_char *) Xmalloc (sizeof (u_char) * cfh->uncompressed_size)))
86 {
87 Message ("no memory for words\n");
88 return NULL;
89 }
90
91 for (i = 0; i < cfh->hd.num_codes; i++, words++)
92 {
93 register int val, copy;
94 val = fgetc (dict);
95 copy = (val >> 4) & 0xf;
96 val &= 0xf;
97
98 *words = allwords;
99
100 memcpy (allwords + 1, prev + 1, copy);
101 fread (allwords + copy + 1, sizeof (u_char), val, dict);
102 *allwords = val + copy;
103
104 Words_disk += val + 1;
105
106 /* insert into the hash table */
107 if (i < cfh->hd.num_codes - esc)
108 {
109 register u_char **wptr;
110 register unsigned long tsize = ht->size;
111 register unsigned long hashval, step;
112
113 HASH (hashval, step, allwords, tsize);
114
115 wptr = ht->table[hashval];
116 for (; wptr;)
117 {
118 hashval += step;
119 if (hashval >= tsize)
120 hashval -= tsize;
121 wptr = ht->table[hashval];
122 }
123 ht->table[hashval] = words;
124 }
125 prev = allwords;
126 allwords += *allwords + 1;
127 }
128 return ht;
129}
130
131inline int LoadWords(FILE *dict, int which)
132{
133 if (Read_cfh (dict, &cfh[which], NULL, &Words_disk) == -1)
134 return 1;
135
136 if (!(ht[which] = ReadInWords (dict, &cfh[which], 0)))
137 return 1;
138
139 return 0;
140}
141
142inline int LoadHuffmanCodes(FILE *dict, int which)
143{
144 if (Read_Huffman_Data (dict, &char_huff[which], NULL,
145 &Chars_disk) == -1)
146 return 1;
147 if (!(char_codes[which] =
148 Generate_Huffman_Codes (&char_huff[which], NULL)))
149 return 2;
150 if (Read_Huffman_Data (dict, &lens_huff[which], NULL,
151 &Chars_disk) == -1)
152 return 3;
153 if (!(lens_codes[which] =
154 Generate_Huffman_Codes (&lens_huff[which], NULL)))
155 return 4;
156
157 return 0;
158}
159
160int
161LoadCompressionDictionary (char *dict_file_name)
162{
163 FILE *dict;
164 int which;
165 if (!(dict = open_named_file (dict_file_name, "rb", MAGIC_DICT, MG_MESSAGE))) /* [RPAP - Feb 97: WIN32 Port] */
166 return COMPERROR;
167
168 Words_disk = sizeof (u_long);
169
170 if (Read_cdh (dict, &cdh, NULL, &Words_disk) == -1)
171 goto error;
172
173 for (which = 0; which < 2; which++)
174 switch (cdh.dict_type)
175 {
176 case MG_COMPLETE_DICTIONARY:
177 {
178 if (LoadWords(dict, which) != 0)
179 goto error;
180 }
181 break;
182 case MG_PARTIAL_DICTIONARY:
183 {
184 if (cdh.num_words[which])
185 {
186 if (LoadWords(dict, which) != 0)
187 goto error;
188 }
189 else
190 ht[which] = NULL;
191 if (LoadHuffmanCodes(dict, which) != 0)
192 goto error;
193 }
194 break;
195 case MG_SEED_DICTIONARY:
196 {
197 if (cdh.num_words[which])
198 {
199 if (LoadWords(dict, which) != 0)
200 goto error;
201 }
202 else
203 ht[which] = NULL;
204 switch (cdh.novel_method)
205 {
206 case MG_NOVEL_HUFFMAN_CHARS:
207 if (LoadHuffmanCodes(dict, which) != 0)
208 goto error;
209 break;
210 case MG_NOVEL_DELTA:
211 break;
212 case MG_NOVEL_HYBRID:
213 break;
214 default:
215 FatalError (1, "Bad novel method");
216 }
217 }
218 break;
219 default:
220 FatalError (1, "Bad dictionary kind\n");
221 }
222
223 return (COMPALLOK);
224
225
226error:
227 fclose (dict);
228 return (COMPERROR);
229}
Note: See TracBrowser for help on using the repository browser.