NSAPI_PUBLIC int PListAssignValue(PList_t plist, const char *pname, const void *pvalue, PList_t ptype) { PListStruct_t *pl = (PListStruct_t *)plist; PLValueStruct_t *pv; int pindex; int i; if (!plist) return ERRPLUNDEF; /* Got a symbol table for this property list? */ if (pl->pl_symtab) { /* Yes, compute hash of specified name */ i = PListHashName(pl->pl_symtab, pname); /* Search hash collision list for matching name */ for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) { if (!strcmp(pname, pv->pv_name)) { /* Name match, get property index */ pindex = pv->pv_pi; /* Set the new value */ pv->pv_value = (char *)pvalue; /* Set type if type is given */ if (ptype) pv->pv_type = (PListStruct_t *)ptype; /* Return the property index */ return pindex; } } } /* Error - specified property name is undefined */ return ERRPLUNDEF; }
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; pt->pt_nsyms--; break; } } /* Free the current name string */ pool_free(pv->pv_mempool, (void *)(pv->pv_name)); } /* Got a new name? */ if (pname) { /* Allocate/grow the symbol table as needed */ pt = PListSymbolTable(pl); if (!pt) { return ERRPLNOMEM; } /* Duplicate the name string */ pv->pv_name = pool_strdup(pv->pv_mempool, (char *)pname); /* Add name to symbol table */ i = PListHashName(pt, pname); pv->pv_next = pt->pt_hash[i]; pt->pt_hash[i] = pv; pt->pt_nsyms++; } /* Successful return */ return pindex; } } /* Error - invalid property index or non-existent property */ return ERRPLINVPI; }
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 const void * PListDeleteProp(PList_t plist, int pindex, const char *pname_in) { PListStruct_t *pl = (PListStruct_t *)plist; PLValueStruct_t **ppval; PLValueStruct_t **pvp; PLValueStruct_t *pv = NULL; int i; const void *pvalue = NULL; char *pname = (char *)pname_in; if (!plist) return NULL; ppval = (PLValueStruct_t **)(pl->pl_ppval); /* Check for valid property index */ if ((pindex > 0) && (pindex <= pl->pl_initpi)) { /* Get the pointer to the property structure */ pv = ppval[pindex - 1]; pname = 0; if (pv) { pname = pv->pv_name; } } if (pname && pl->pl_symtab) { /* Compute hash of specified property name */ i = PListHashName(pl->pl_symtab, pname); /* Search hash collision list for matching name */ for (pvp = &pl->pl_symtab->pt_hash[i]; *pvp; pvp = &(*pvp)->pv_next) { pv = *pvp; if (!strcmp(pname, pv->pv_name)) { /* Found it. Get its index and remove it. */ pindex = pv->pv_pi; *pvp = pv->pv_next; pl->pl_symtab->pt_nsyms--; break; } pv = NULL; } } /* Found the indicated property by index or name? */ if (pv) { /* Yes, remove it from the property list */ ppval[pindex - 1] = NULL; /* Free the property name, if any */ if (pv->pv_name) { pool_free(pv->pv_mempool, (void *)(pv->pv_name)); } pvalue = pv->pv_value; /* Free the property */ pool_free(pv->pv_mempool, (void *)pv); } return(pvalue); }
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; }