qboolean Q_STShrink(stable_t *st, size_t newSize) { assert(st->st != NULL); // make sure that this is a valid resize if (newSize > MIN_SIZE && newSize < st->size) { // pack the string table into the smallest possible footprint int32_t size = nfst_pack((struct nfst_StringTable *)st->st); // if the string table can fit into if (size <= newSize) { void *new_one = NULL; if ((new_one = Z_Realloc(st->st, newSize)) != NULL) { st->st = new_one; st->size = newSize; nfst_grow((struct nfst_StringTable *)st->st, st->size); return true; } } // if it got here the allocation didn't change // either it's not small enough, or realloc failed // either way, expand the string table back to fit the allocation nfst_grow((struct nfst_StringTable *)st->st, st->size); } return false; }
int32_t Q_STAutoPack(stable_t *st) { int32_t size; assert(st->st != NULL); size = nfst_pack((struct nfst_StringTable *)st->st); if (size <= st->size) { void *new_one = NULL; if ((new_one = Z_Realloc(st->st, size)) != NULL) { st->st = new_one; st->size = size; return size; } } // if the reallocation failed, expand the string table again nfst_grow((struct nfst_StringTable *)st->st, st->size); return st->size; }
qboolean Q_STGrow(stable_t *st, size_t newSize) { assert(st->st != NULL); // check to see if it's a valid size if (newSize > st->size && newSize > MIN_SIZE) { void *new_one = NULL; // try to reallocate it into the larger size if ((new_one = Z_Realloc(st->st, newSize)) != NULL) { // if that succeeds, save the size and grow the string table st->st = new_one; st->size = newSize; nfst_grow((struct nfst_StringTable *)st->st, newSize); return true; } } // leave everything untouched return false; }
int32_t Q_STRegister(stable_t *st, const char *string) { int result = nfst_to_symbol((struct nfst_StringTable *)st->st, string); if (result == NFST_STRING_TABLE_FULL && st->heap) { void *new_one = NULL; int newsize = st->size * 2; if ((new_one = Z_Realloc(st->st, newsize)) != NULL) { st->st = new_one; st->size = newsize; nfst_grow((struct nfst_StringTable *)st->st, newsize); result = nfst_to_symbol((struct nfst_StringTable *)st->st, string); } } if (result == NFST_STRING_TABLE_FULL) { Com_Printf(S_COLOR_RED"Error: could not register string: %s\n",string); } return result; }
// Adds the string `s` to the config data and returns its reference. nfcd_loc nfcd_add_string(struct ConfigData **cdp, const char *s) { struct ConfigData *cd = *cdp; struct nfst_StringTable *st = STRINGTABLE(cd); int sym = nfst_to_symbol(st, s); while (sym < 0) { int string_bytes = cd->total_bytes - cd->allocated_bytes; int new_string_bytes = string_bytes * 2; int new_total_bytes = cd->allocated_bytes + new_string_bytes; cd = (ConfigData*)cd->realloc(cd->realloc_user_data, cd, cd->total_bytes, new_total_bytes, __FILE__, __LINE__); cd->total_bytes = new_total_bytes; st = STRINGTABLE(cd); nfst_grow(st, new_string_bytes); sym = nfst_to_symbol(st, s); *cdp = cd; } return MAKE_LOC(NFCD_TYPE_STRING, sym); }