Mercurial > hg > early-roguelike
comparison urogue/dictutil.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 31 Jan 2017 19:56:04 -0500 |
parents | |
children | c4b12d2d1dcd |
comparison
equal
deleted
inserted
replaced
253:d9badb9c0179 | 256:c495a4f288c6 |
---|---|
1 /* | |
2 dictutil.c | |
3 | |
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom | |
5 Copyright (C) 1995 Herb Chong | |
6 All rights reserved. | |
7 | |
8 See the file LICENSE.TXT for full copyright and licensing information. | |
9 */ | |
10 | |
11 /************************************************************************* | |
12 ** Utilities for Dictionary Maintenence Functions | |
13 *************************************************************************/ | |
14 | |
15 static char sccsid[] = "%W% %G%"; | |
16 | |
17 #include <stdio.h> | |
18 #include <string.h> | |
19 #include <stdlib.h> | |
20 #if !defined(OS2) && !defined(_WIN32) | |
21 #include <unistd.h> | |
22 #else | |
23 #include <io.h> | |
24 #include <fcntl.h> | |
25 #endif | |
26 | |
27 #include "dict.h" | |
28 #include "dictutil.h" | |
29 #include "rogue.h" | |
30 | |
31 int trace; | |
32 FILE *ft; | |
33 | |
34 | |
35 /*********** | |
36 ** Read 'count' characters into 'buffer' at 'offset' in a binary file | |
37 ** Return 0 on success; -1 on failure; | |
38 ***********/ | |
39 | |
40 int block_read( FILE *fi , char *buffer , size_t count , long offset ) | |
41 { | |
42 if ( fseek(fi,offset,SEEK_SET) == -1 ) | |
43 return( -1 ); | |
44 | |
45 if ( fread(buffer,1,count,fi) != count ) | |
46 return( -1 ); | |
47 return( 0 ); | |
48 } | |
49 | |
50 /*********** | |
51 ** Write 'count' characters from 'buffer' to a binary file. | |
52 ** Return -1 on failure; 0 on success. | |
53 ***********/ | |
54 | |
55 int block_write( FILE *fo , char *buffer , size_t count ) | |
56 { | |
57 if ( fwrite(buffer,1,count,fo) != count ) | |
58 return( -1 ); | |
59 return( 0 ); | |
60 } | |
61 | |
62 /*********** | |
63 ** Load a dictionary table entry with id TOC_id into memory pointed to by block. | |
64 ** Update the dictionary TOC. | |
65 ** If *block=NULL, allocate the block of memory. | |
66 ** Return 0 on success; -1 on failure. | |
67 ** Set dt_entry->ptr to where the block is stored. | |
68 ***********/ | |
69 | |
70 void *dict_load_block( DICTIONARY *dict , char *toc_id , | |
71 FILE *fi , void *block ) | |
72 { DICT_TOC_ENTRY *dt_entry; | |
73 static void *ptr; | |
74 int index, ret_code; | |
75 | |
76 index = dict_toc_index( dict , toc_id ); | |
77 if ( index != -1 ) { /* Found the id */ | |
78 dt_entry = &(dict->toc[index]); | |
79 } else { | |
80 signal_error( "dict_load_block: could not find TOC_id" , toc_id , 1 ); | |
81 return( NULL ); | |
82 } /* endif */ | |
83 | |
84 if ( block == NULL ) { | |
85 ptr = malloc( dt_entry->size ); | |
86 if ( trace > 3 ) { | |
87 fprintf( ft , "\ndict_load_block allocates %lx bytes at location %p\n" , | |
88 dt_entry->size , ptr ); | |
89 } /* endif */ | |
90 } else { | |
91 ptr = block; | |
92 if ( trace > 3 ) { | |
93 fprintf( ft , "\ndict_load_block uses memory at location %p\n" , ptr ); | |
94 } /* endif */ | |
95 } /* endif */ | |
96 if ( ptr == NULL ) { | |
97 signal_error( "dict_load_block: alloc failed " , toc_id , 1 ); | |
98 return( NULL ); | |
99 } /* endif */ | |
100 | |
101 ret_code = block_read( fi , | |
102 (char*)ptr , | |
103 dt_entry->size , | |
104 dt_entry->offset ); | |
105 if ( ret_code == -1 ) | |
106 return( NULL ); | |
107 | |
108 if ( dt_entry->checksum != | |
109 compute_checksum( dt_entry->size , (char*)ptr ) ) { | |
110 signal_error( "dict_load_block: invalid checksum ", toc_id, 1); | |
111 return( NULL ); | |
112 } /* endif */ | |
113 | |
114 dt_entry->ptr = ptr; | |
115 | |
116 if ( trace > 3 ) { | |
117 fprintf( ft , "\nLoaded block\nTOC entry: id:%s offset:%lx size:%lx ptr:%p checksum:%lx type:%d\n" , | |
118 dict->toc[index].id , dict->toc[index].offset , | |
119 dict->toc[index].size , dict->toc[index].ptr , | |
120 dict->toc[index].checksum , dict->toc[index].type ); | |
121 } /* endif */ | |
122 | |
123 return( ptr ); | |
124 } | |
125 | |
126 /*********** | |
127 ** Save a dictionary table entry. | |
128 ** Update the dictionary TOC entry offset and checksum fields. | |
129 ** Return 0 on success, -1 on failure. | |
130 ** Note: It is assumed that the size and pointer fields in TOC entry are | |
131 ** already up to date; i.e., that they are consistent with the current | |
132 ** location and size of the block being written. This is essential | |
133 ** because the table of contents must have already been written | |
134 ** into the file. | |
135 ***********/ | |
136 | |
137 BOOLEANC dict_save_block( DICTIONARY *dict , char *toc_id , FILE *fo ) | |
138 { DICT_TOC_ENTRY *dt_entry; | |
139 int index, ret_code; | |
140 char *block; | |
141 | |
142 index = dict_toc_index( dict , toc_id ); | |
143 if ( index == -1 ) { | |
144 signal_error( "dict_save_block: id not found " , toc_id , 1 ); | |
145 return( FALSE ); | |
146 } /* endif */ | |
147 dt_entry = &(dict->toc[index]); | |
148 block = (char*)(dt_entry->ptr); | |
149 | |
150 if ( block == NULL ) { | |
151 signal_error( "dict_save_block: NULL block " , toc_id , 1 ); | |
152 return( FALSE ); | |
153 } /* endif */ | |
154 | |
155 /* dt_entry->offset = fseek( fo , 0 , SEEK_END ); */ | |
156 dt_entry->checksum = compute_checksum( dt_entry->size , block ); | |
157 ret_code = block_write( fo , dt_entry->ptr , dt_entry->size ); | |
158 if ( ret_code == -1 ) { | |
159 signal_error( "dict_save_block: block_write failed " , toc_id , 1 ); | |
160 return( FALSE ); | |
161 } /* endif */ | |
162 | |
163 if ( trace > 3 ) { | |
164 fprintf( ft , "\nStored block\nTOC entry: id:%s offset:%lx size:%lx ptr:%p checksum:%lx type:%d\n" , | |
165 dict->toc[index].id , dict->toc[index].offset , | |
166 dict->toc[index].size , dict->toc[index].ptr , | |
167 dict->toc[index].checksum , dict->toc[index].type ); | |
168 } /* endif */ | |
169 | |
170 return( TRUE ); | |
171 } | |
172 | |
173 /*********** | |
174 ** Look up and id in the table of contents. | |
175 ** Return its index (-1 on failure). | |
176 ***********/ | |
177 | |
178 int dict_toc_index( DICTIONARY *dict , char *toc_id ) | |
179 { int index; | |
180 | |
181 for ( index = 0 ; index < dict->sig->toc_size ; index++ ) { | |
182 if ( strcmp(dict->toc[index].id,toc_id) == 0 ) | |
183 return( index ); | |
184 } /* endfor */ | |
185 | |
186 return( -1 ); | |
187 } | |
188 | |
189 /*********** | |
190 ** Compute a block checksum. | |
191 ** (Currently just returns 0.) | |
192 ***********/ | |
193 | |
194 unsigned long compute_checksum( size_t size , char *block ) | |
195 { | |
196 NOOP(size); | |
197 NOOP(block); | |
198 return( 0 ); | |
199 } | |
200 | |
201 /*********** | |
202 ** Create a dictionary paramter entry. | |
203 ***********/ | |
204 | |
205 DICT_PARM_ENTRY *dict_make_parm_entry( char *id , unsigned long value ) | |
206 { static DICT_PARM_ENTRY *entry; | |
207 | |
208 entry = (DICT_PARM_ENTRY *) malloc( sizeof(DICT_PARM_ENTRY) ); | |
209 if ( entry == NULL ) | |
210 return(NULL); | |
211 | |
212 strncpy( entry->id , id , 13 ); | |
213 entry->value = value; | |
214 | |
215 return( entry ); | |
216 } | |
217 | |
218 /*********** | |
219 ** Look up and id in the parameter array. | |
220 ** Return its index (-1 on failure). | |
221 ***********/ | |
222 | |
223 int dict_parm_index( DICTIONARY *dict , char *parm_id ) | |
224 { long index; | |
225 | |
226 for ( index = 0 ; index < dict->sig->nparms ; index++ ) { | |
227 if ( strcmp( dict->parm[index].id , parm_id ) == 0 ) | |
228 return( (int) index ); | |
229 } /* endfor */ | |
230 | |
231 return( -1 ); | |
232 } | |
233 | |
234 /*********** | |
235 ** Reset table of contents offsets and checksums | |
236 ** in preparation for dict_save(). | |
237 ***********/ | |
238 | |
239 BOOLEANC dict_reset_toc_offsets( DICTIONARY *dict ) | |
240 { int i; | |
241 long offset; | |
242 | |
243 offset = sizeof(DICT_SIG) | |
244 + dict->sig->toc_size * sizeof(DICT_TOC_ENTRY); | |
245 for ( i = 0 ; i < dict->sig->toc_size ; i++ ) { | |
246 dict->toc[i].offset = offset; | |
247 offset += dict->toc[i].size; | |
248 dict->toc[i].checksum = | |
249 compute_checksum( dict->toc[i].size , dict->toc[i].ptr ); | |
250 } /* endfor */ | |
251 | |
252 return( TRUE ); | |
253 } | |
254 | |
255 /*********** | |
256 ** Load the names of the dictionary parameters. | |
257 ** 14 parms | |
258 ***********/ | |
259 | |
260 BOOLEANC dict_set_parm_ids( DICTIONARY *dict ) | |
261 { | |
262 if ( dict==NULL || dict->sig == NULL ) { | |
263 signal_error( "dict_set_parm_ids: Allocate dict and signature first." , "" , 0 ); | |
264 return( FALSE ); | |
265 } | |
266 dict->sig->nparms = 14; | |
267 strcpy( dict->parm[0].id , "FLAGS_______" ); | |
268 strcpy( dict->parm[1].id , "ENTRY_COUNT_" ); | |
269 strcpy( dict->parm[2].id , "ARRAY_SIZE__" ); | |
270 strcpy( dict->parm[3].id , "ARRAY_USED__" ); | |
271 strcpy( dict->parm[4].id , "ARR_GROW_CT_" ); | |
272 strcpy( dict->parm[5].id , "STRING_MAX__" ); | |
273 strcpy( dict->parm[6].id , "STR_GROW_CT_" ); | |
274 strcpy( dict->parm[7].id , "LONG_CHAIN__" ); | |
275 strcpy( dict->parm[8].id , "ALLOW_CHAIN_" ); | |
276 strcpy( dict->parm[9].id , "HASH_TAB_SIZ" ); | |
277 strcpy( dict->parm[10].id , "HASH_MASK___" ); | |
278 strcpy( dict->parm[11].id , "HASH_GROW_CT" ); | |
279 strcpy( dict->parm[12].id , "CHECK_VALUE_" ); | |
280 strcpy( dict->parm[13].id , "SCAN_STR_IX_" ); | |
281 | |
282 return( TRUE ); | |
283 } | |
284 | |
285 /*********** | |
286 ** Set the dictionary parm structure from the values in the dict structure. | |
287 ** 14 parms | |
288 ***********/ | |
289 | |
290 BOOLEANC dict_set_parm_values( DICTIONARY *dict ) | |
291 { int index; | |
292 | |
293 if ( (index=dict_parm_index(dict,"FLAGS_______")) == -1 ) | |
294 return( FALSE ); | |
295 dict->parm[index].value = (unsigned long)dict->flags; | |
296 | |
297 if ( (index=dict_parm_index(dict,"ENTRY_COUNT_")) == -1 ) | |
298 return( FALSE ); | |
299 dict->parm[index].value = (unsigned long)dict->entry_count; | |
300 | |
301 if ( (index=dict_parm_index(dict,"ARRAY_SIZE__")) == -1 ) | |
302 return( FALSE ); | |
303 dict->parm[index].value = (unsigned long)dict->array_size; | |
304 | |
305 if ( (index=dict_parm_index(dict,"ARRAY_USED__")) == -1 ) | |
306 return( FALSE ); | |
307 dict->parm[index].value = (unsigned long)dict->array_used; | |
308 | |
309 if ( (index=dict_parm_index(dict,"ARR_GROW_CT_")) == -1 ) | |
310 return( FALSE ); | |
311 dict->parm[index].value = (unsigned long)dict->array_growth_count; | |
312 | |
313 if ( (index=dict_parm_index(dict,"STRING_MAX__")) == -1 ) | |
314 return( FALSE ); | |
315 dict->parm[index].value = (unsigned long)dict->string_max; | |
316 | |
317 if ( (index=dict_parm_index(dict,"STR_GROW_CT_")) == -1 ) | |
318 return( FALSE ); | |
319 dict->parm[index].value = (unsigned long)dict->string_growth_count; | |
320 | |
321 if ( (index=dict_parm_index(dict,"LONG_CHAIN__")) == -1 ) | |
322 return( FALSE ); | |
323 dict->parm[index].value = (unsigned long)dict->longest_chain_length; | |
324 | |
325 if ( (index=dict_parm_index(dict,"ALLOW_CHAIN_")) == -1 ) | |
326 return( FALSE ); | |
327 dict->parm[index].value = (unsigned long)dict->allowable_chain_length; | |
328 | |
329 if ( (index=dict_parm_index(dict,"HASH_TAB_SIZ")) == -1 ) | |
330 return( FALSE ); | |
331 dict->parm[index].value = (unsigned long)dict->table_size; | |
332 | |
333 if ( (index=dict_parm_index(dict,"HASH_MASK___")) == -1 ) | |
334 return( FALSE ); | |
335 dict->parm[index].value = (unsigned long)dict->hash_mask; | |
336 | |
337 if ( (index=dict_parm_index(dict,"HASH_GROW_CT")) == -1 ) | |
338 return( FALSE ); | |
339 dict->parm[index].value = (unsigned long)dict->hash_growth_count; | |
340 | |
341 if ( (index=dict_parm_index(dict,"CHECK_VALUE_")) == -1 ) | |
342 return( FALSE ); | |
343 dict->parm[index].value = (unsigned long)dict->check_value; | |
344 | |
345 if ( (index=dict_parm_index(dict,"SCAN_STR_IX_")) == -1 ) | |
346 return( FALSE ); | |
347 dict->parm[index].value = (unsigned long)dict->scan_string_index; | |
348 | |
349 return( TRUE ); | |
350 } | |
351 | |
352 | |
353 /*********** | |
354 ** Set the values in the dict structure from the dictionary parm structure. | |
355 ** 14 parms | |
356 ***********/ | |
357 | |
358 BOOLEANC dict_set_parm_variables( DICTIONARY *dict ) | |
359 { int index; | |
360 | |
361 if ( (index=dict_parm_index(dict,"FLAGS_______")) == -1 ) | |
362 return( FALSE ); | |
363 dict->flags = (unsigned long)dict->parm[index].value; | |