PLSymbolTable_t * PListSymbolTable(PListStruct_t *pl) { PLSymbolTable_t *pt; int i; pt = pl->pl_symtab; /* Is there a hash table? */ if (!pl->pl_symtab) { /* No, create one */ pt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1, PLHASHSIZE(0)); pl->pl_symtab = pt; } else { /* Is it time to grow the hash table? */ i = PLSIZENDX(pt->pt_sizendx); if ((pt->pt_sizendx < PLMAXSIZENDX) && pt->pt_nsyms >= (i + i)) { PLSymbolTable_t *npt; /* Yes, allocate the new table */ npt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1, PLHASHSIZE(pt->pt_sizendx+1)); if (npt) { npt->pt_sizendx = pt->pt_sizendx + 1; npt->pt_nsyms = pt->pt_nsyms; /* Rehash all the names into the new table, preserving order */ for (i = 0; i < PLSIZENDX(pt->pt_sizendx); ++i) { /* While there are names at this hash index... */ while (pt->pt_hash[i]) { PLValueStruct_t **pvp; int j; /* Find the last name at this hash index */ for (pvp = &pt->pt_hash[i]; (*pvp)->pv_next; pvp = &(*pvp)->pv_next); /* Move the name to the new table */ j = PListHashName(npt, (*pvp)->pv_name); (*pvp)->pv_next = npt->pt_hash[j]; npt->pt_hash[j] = (*pvp); /* Remove the name from the old table */ *pvp = NULL; } } pl->pl_symtab = npt; /* Free the old symbol table */ pool_free(pl->pl_mempool, (void *)pt); pt = npt; } } } return pl->pl_symtab; }
NSAPI_PUBLIC int PListNameProp(PList_t plist, int pindex, const char *pname) { PListStruct_t *pl = (PListStruct_t *)plist; PLValueStruct_t *pv; PLSymbolTable_t *pt; int i; if (!plist) return ERRPLUNDEF; pt = pl->pl_symtab; /* Check for valid property index */ if ((pindex > 0) && (pindex <= pl->pl_initpi)) { /* Does the property exist? */ pv = ((PLValueStruct_t **)(pl->pl_ppval))[pindex - 1]; if (pv) { /* If it has a name already, unname it */ if (pv->pv_name) { PLValueStruct_t **pvp; /* Get hash bucket index */ i = PListHashName(pt, pv->pv_name); /* Seach hash collision list for this property */ for (pvp = &pt->pt_hash[i]; *pvp; pvp = &(*pvp)->pv_next) { if (*pvp == pv) { /* Remove it from the list */ *pvp = pv->pv_next; break; } } /* Free the current name string */ pool_free(pl->pl_mempool, (void *)(pv->pv_name)); } /* Got a new name? */ if (pname) { /* Yes, is there a hash table? */ if (!pt) { /* No, create one */ pt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1, PLHASHSIZE(0)); if (!pt) { return ERRPLNOMEM; } pl->pl_symtab = pt; } else { /* Is it time to grow the hash table? */ i = PLSIZENDX(pt->pt_sizendx); /* cannot allow pt->pt_sizendx == PLMAXSIZENDX */ if (((size_t)(pt->pt_sizendx + 1) < PLMAXSIZENDX) && pt->pt_nsyms >= (i + i)) { PLSymbolTable_t *npt; /* Yes, allocate the new table */ npt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1, PLHASHSIZE(pt->pt_sizendx+1)); if (npt) { PLValueStruct_t *opv; PLValueStruct_t *npv; int j; npt->pt_sizendx = pt->pt_sizendx + 1; npt->pt_nsyms = pt->pt_nsyms; /* Rehash all the names into the new table */ for (i = 0; i < PLSIZENDX(pt->pt_sizendx); ++i) { for (opv = pt->pt_hash[i]; opv; opv = npv) { npv = opv->pv_next; j = PListHashName(npt, opv->pv_name); opv->pv_next = npt->pt_hash[j]; npt->pt_hash[j] = opv; } } pl->pl_symtab = npt; /* Free the old symbol table */ pool_free(pl->pl_mempool, (void *)pt); pt = npt; } } } /* Duplicate the name string */ pv->pv_name = pool_strdup(pl->pl_mempool, (char *)pname); /* Add name to symbol table */ i = PListHashName(pt, pname); pv->pv_next = pt->pt_hash[i]; pt->pt_hash[i] = pv; } /* Successful return */ return pindex; } } /* Error - invalid property index or non-existent property */ return ERRPLINVPI; }