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; | |
