| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163 |
- /** BEGIN COPYRIGHT BLOCK
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- *
- * License: GPL (version 3 or any later version).
- * See LICENSE for details.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- /*
- * MODULE: plist.c
- *
- * DESCRIPTION:
- *
- * This module implements property lists. A property list is an
- * ordered array of property values. Each property value has an
- * handle for some data item, and may have a reference to
- * another property list which describes the type of the data
- * item. Each property value has a property index which specifies
- * its position in the property list. A property value may also
- * have a name. Since the data item associated with a property
- * value may reference another property list, it is possible to
- * construct arbitrary linked structures of property lists.
- *
- * IMPLEMENTATION NOTES:
- */
- #include "netsite.h"
- #include "base/plist.h"
- #include "plist_pvt.h"
- int plistHashSizes[] = PLSTSIZES;
- /*
- * FUNCTION: PListAssignValue
- *
- * DESCRIPTION:
- *
- * This function sets the value and/or type of a defined property
- * in given property list. If the property type is specified as
- * NULL, it is unchanged. However, the property value is always
- * set to the specified value.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pname - the property name
- * pvalue - the new property value
- * ptype - the new property type, or NULL
- *
- * RETURNS:
- *
- * If successful, the property index of the referenced property is
- * returned as the function value. Errors are indicated by a
- * negative return code as defined in plist.h.
- */
- 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;
- }
- /*
- * FUNCTION: PListCreate
- *
- * DESCRIPTION:
- *
- * This function creates a new property list and returns a handle for
- * it. It allows the caller to reserve a specified number of
- * property indices at the beginning of the list, and also to limit
- * the total number of property values that may be added to the list.
- *
- * ARGUMENTS:
- *
- * mempool - handle for a memory pool to be associated
- * with the new property list
- * resvprop - number of reserved property indices
- * maxprop - maximum number of properties in list
- * (zero or negative imposes no limit)
- * flags - unused, reserved, must be zero
- *
- * RETURNS:
- *
- * If successful, the function return value is a handle for the new
- * property list. Otherwise NULL is returned.
- */
- NSAPI_PUBLIC PList_t
- PListCreate(pool_handle_t *mempool, int resvprop, int maxprop, int flags)
- {
- PListStruct_t *plist; /* pointer to property list structure */
- int i;
- plist = (PListStruct_t *)pool_malloc(mempool, sizeof(PListStruct_t));
- if (plist) {
- /* Negative maxprop is the same as zero, i.e. no limit */
- if (maxprop < 0) maxprop = 0;
- /* If resvprop and maxprop are both specified, limit resvprop */
- if (resvprop > 0) {
- if (maxprop && (resvprop > maxprop)) resvprop = maxprop;
- }
- else resvprop = 0;
- /* Initialize property list structure */
- plist->pl_mempool = mempool;
- plist->pl_symtab = NULL;
- plist->pl_maxprop = maxprop;
- plist->pl_resvpi = resvprop;
- plist->pl_initpi = resvprop;
- plist->pl_lastpi = resvprop;
- /* Set initialize size for array of property value pointers */
- plist->pl_cursize = (resvprop) ? resvprop : PLIST_DEFSIZE;
- /* Allocate the initial array of property value pointers */
- plist->pl_ppval = (pb_entry **)pool_malloc(mempool,
- (plist->pl_cursize *
- sizeof(PLValueStruct_t *)));
- if (!plist->pl_ppval) {
- /* Failed - insufficient memory */
- pool_free(mempool, (void *)plist);
- plist = NULL;
- }
- else {
- /* NULL out pointers in the reserved index range, if any */
- for (i = 0; i < plist->pl_lastpi; ++i) {
- plist->pl_ppval[i] = 0;
- }
- }
- }
- return (PList_t)plist;
- }
- /*
- * FUNCTION: PListDefProp
- *
- * DESCRIPTION:
- *
- * This function creates a new property in a specified property list.
- * The 'pindex' argument may be used to request a particular property
- * index for the new property. If 'pindex' is greater than zero,
- * the specified value is used as the new property's index, provided
- * there is no property at that index already. If 'pindex' is zero,
- * then the next available property index is assigned to the new
- * property. A name may optionally be specified for the new property.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pindex - new property index (or zero)
- * pname - new property name (or NULL)
- *
- * RETURNS:
- *
- * If successful, the index of the new property is returned as the
- * function value. Errors are indicated by a negative return code
- * as defined in plist.h.
- */
- NSAPI_PUBLIC int
- PListDefProp(PList_t plist, int pindex, const char *pname, const int flags)
- {
- PListStruct_t *pl = (PListStruct_t *)plist;
- PLValueStruct_t **ppval;
- PLValueStruct_t *pv;
- int cursize;
- int i;
- int wrapped;
- if (!plist) return ERRPLUNDEF;
- ppval = (PLValueStruct_t **)(pl->pl_ppval);
- /* Is pindex specified? */
- if (pindex > 0) {
- /* Yes, is it in the reserved range? */
- if (flags != PLFLG_IGN_RES && pindex > pl->pl_resvpi) {
- /* No, error */
- return ERRPLINVPI;
- }
- i = pindex - 1;
- if (ppval[i]) {
- /* Error - property already exists at specified index */
- return ERRPLEXIST;
- }
- }
- else {
- /*
- * Look for a free property index, starting at pl_lastpi + 1.
- * (Note that i is the property index - 1)
- */
- for (wrapped = 0, i = pl->pl_lastpi; ;) {
- /* Are we in an initialized part of the array? */
- if (i < pl->pl_initpi) {
- /* Yes, use this index if it's free */
- if (ppval[i] == 0) break;
- /* Otherwise step to the next one */
- ++i;
- }
- else {
- /* Have we reached the end yet? */
- if (i < pl->pl_cursize) {
- /*
- * We are above the highest initialized index, but
- * still within the allocated size. An index in
- * this range can be used with no further checks.
- */
- ppval[i] = 0;
- }
- else {
- /*
- * It's looking like time to grow the array, but
- * first go back and look for an unused, unreserved
- * index that might have been freed.
- */
- if (!wrapped) {
- i = pl->pl_resvpi;
- wrapped = 1;
- continue;
- }
- /*
- * Grow the array unless there is a specified maximum
- * size and we've reached it.
- */
- i = pl->pl_cursize;
- if (pl->pl_maxprop && (i > pl->pl_maxprop)) {
- /* Error - property list is full */
- return ERRPLFULL;
- }
- /* Increase planned size of list */
- cursize = i + PLIST_DEFGROW;
- /* Reallocate the array of property value pointers */
- ppval = (PLValueStruct_t **)pool_realloc(pl->pl_mempool,
- (void *)ppval,
- (cursize * sizeof(PLValueStruct_t *)));
- if (!ppval) {
- /* Error - insufficient memory */
- return ERRPLNOMEM;
- }
- /* Initialize the first new entry and select it */
- ppval[i] = NULL;
- pl->pl_ppval = (pb_entry **)ppval;
- pl->pl_cursize = cursize;
- }
- /* Update the highest initialized index value */
- pl->pl_initpi = i + 1;
- break;
- }
- }
- /* Set the starting point for the next allocation */
- pl->pl_lastpi = i + 1;
- }
- /* We have a property index (i + 1). Create a new property value */
- pv = (PLValueStruct_t *)pool_calloc(pl->pl_mempool,
- 1, sizeof(PLValueStruct_t));
- if (!pv) {
- /* Error - insufficient memory */
- return ERRPLNOMEM;
- }
- pv->pv_pbentry.param = &pv->pv_pbparam;
- pv->pv_pi = i + 1;
- ppval[i] = pv;
- /* Name the property if the name was specified */
- if (pname) {
- /* XXX Maybe should delete property if naming fails */
- return PListNameProp(plist, i + 1, pname);
- }
- /* Return the property index of the new property */
- return i + 1;
- }
- /*
- * FUNCTION: PListDeleteProp
- *
- * DESCRIPTION:
- *
- * This function deletes a property from a specified property list.
- * The property can be specified by its property index, using a
- * pindex value greater than zero, or by its name, by specifying
- * pindex as zero and pname as the property name. This does not
- * have any effect on the data referenced by the property value,
- * if any, nor does it have any effect on the property list that
- * describes the property value's type, if any.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pindex - the property index, or zero
- * pname - the property name, or NULL
- */
- 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;
- break;
- }
- }
- }
- /* 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(pl->pl_mempool, (void *)(pv->pv_name));
- }
- pvalue = pv->pv_value;
- /* Free the property */
- pool_free(pl->pl_mempool, (void *)pv);
- }
- return(pvalue);
- }
- /*
- * FUNCTION: PListFindValue
- *
- * DESCRIPTION:
- *
- * This function retrieves the value and type of a property with a
- * specified property name. If the pvalue argument is non-NULL,
- * it specifies a location in which to return the property value.
- * Similarly, if ptype is non-NULL, it specifies where the property
- * list describing the property type is to be returned. If a
- * property has no value, the value returned for pvalue is NULL.
- * If a property has no type, the value returned for ptype is NULL.
- * A property can have a value, a type, both, or neither.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pname - pointer to property name string
- * pvalue - property value return pointer
- * ptype - property type return pointer
- *
- * RETURNS:
- *
- * If successful, the index of the referenced property is returned
- * as the function value. Errors are indicated by a negative
- * return code as defined in plist.h.
- */
- NSAPI_PUBLIC int
- PListFindValue(PList_t plist, const char *pname, 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;
- /* Return the value if requested */
- if (pvalue) *pvalue = (void *)(pv->pv_value);
- /* Return the type if requested */
- if (ptype) *ptype = (PList_t)(pv->pv_type);
- /* Return the property index */
- return pindex;
- }
- }
- }
- /* Error - specified property name is undefined */
- return ERRPLUNDEF;
- }
- /*
- * FUNCTION: PListInitProp
- *
- * DESCRIPTION:
- *
- * This function combines the functions of PListDefProp() and
- * PListSetValue(), defining a new property and assigning it an
- * initial value and optionally a type and/or a name.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pindex - a reserved property index, or zero
- * pname - the new property name, or NULL
- * pvalue - the new property value
- * ptype - the new property type, or NULL
- *
- * RETURNS:
- *
- * If successful, the property index (pindex) is returned as the
- * function value. Errors are indicated by a negative return code
- * as defined in plist.h.
- */
- NSAPI_PUBLIC int
- PListInitProp(PList_t plist, int pindex, const char *pname,
- const void *pvalue, PList_t ptype)
- {
- int rv;
- if (!plist) return ERRPLUNDEF;
- /* Create the property */
- rv = PListDefProp(plist, pindex, pname, PLFLG_USE_RES);
- if (rv > 0) {
- /* If that worked, set the value and type */
- rv = PListSetValue(plist, rv, pvalue, ptype);
- }
- return rv;
- }
- /*
- * FUNCTION: PListNew
- *
- * DESCRIPTION:
- *
- * This function creates a new property list, using the specified
- * memory pool for allocating the internal data structures used to
- * represent it. If the mempool argument is NULL, the default
- * memory pool is used.
- *
- * ARGUMENTS:
- *
- * mempool - handle for a memory pool to be associated
- * with the new property list
- *
- * RETURNS:
- *
- * If successful, the function return value is a handle for the new
- * property list. Otherwise NULL is returned.
- */
- NSAPI_PUBLIC PList_t
- PListNew(pool_handle_t *mempool)
- {
- /* Just call PListCreate with default parameters */
- return PListCreate(mempool, 0, 0, 0);
- }
- /*
- * FUNCTION: PListDestroy
- *
- * DESCRIPTION:
- *
- * This function destroys a specified property list. This means
- * that any dynamic memory which was allocated as a result of calls
- * to the property list API is freed to the memory pool from which
- * it was allocated. Property value data is not freed, nor are
- * any property lists associated with property types.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- */
- void
- PListDestroy(PList_t plist)
- {
- PListStruct_t *pl = (PListStruct_t *)plist;
- PLValueStruct_t **ppval;
- PLValueStruct_t *pv;
- int i;
- if (!plist) return;
- /* Free the property name symbol table if any */
- if (pl->pl_symtab) {
- pool_free(pl->pl_mempool, (void *)(pl->pl_symtab));
- }
- ppval = (PLValueStruct_t **)(pl->pl_ppval);
- /* Loop over the initialized property indices */
- for (i = 0; i < pl->pl_initpi; ++i) {
- /* Got a property here? */
- pv = ppval[i];
- if (pv) {
- /* Free the property name string if any */
- if (pv->pv_name) {
- pool_free(pl->pl_mempool, (void *)(pv->pv_name));
- }
- /* Free the property value structure */
- pool_free(pl->pl_mempool, (void *)pv);
- }
- }
- /* Free the array of pointers to property values */
- pool_free(pl->pl_mempool, (void *)ppval);
- /* Free the property list head */
- pool_free(pl->pl_mempool, (void *)pl);
- }
- /*
- * FUNCTION: PListGetValue
- *
- * DESCRIPTION:
- *
- * This function retrieves the value and type of the property with
- * the property index given by pindex in the specified property
- * list. The pindex argument must specify the index of a defined
- * property. If the pvalue argument is non-NULL, it specifies a
- * location in which to return the property value. Similarly, if
- * ptype is non-NULL, it specifies where the property list
- * describing the property type is to be returned. If a property
- * has no value, the value returned for pvalue is NULL. If a
- * property has no type, the value returned for ptype is NULL. A
- * property can have a value, a type, both, or neither.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pindex - the property index
- * pvalue - property value return pointer
- * ptype - property type return pointer
- *
- * RETURNS:
- *
- * If successful, the property index (pindex) is returned as the
- * function value. Errors are indicated by a negative return code
- * as defined in plist.h.
- */
- NSAPI_PUBLIC int
- PListGetValue(PList_t plist, int pindex, void **pvalue, PList_t *ptype)
- {
- PListStruct_t *pl = (PListStruct_t *)plist;
- PLValueStruct_t **ppval;
- PLValueStruct_t *pv;
- if (!plist) return ERRPLUNDEF;
- ppval = (PLValueStruct_t **)(pl->pl_ppval);
- /* Check for valid property index */
- if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
- /* Does the property exist? */
- pv = ppval[pindex - 1];
- if (pv) {
- /* Yes, return the value if requested */
- if (pvalue) *pvalue = (void *)(pv->pv_value);
- /* Return the type if requested */
- if (ptype) *ptype = (PList_t)(pv->pv_type);
- /* Successful return */
- return pindex;
- }
- }
- /* Error - invalid property index or non-existent property */
- return ERRPLINVPI;
- }
- /*
- * FUNCTION: PListHashName
- *
- * DESCRIPTION:
- *
- * This function hashes a given property name for a specified
- * symbol table. It produces a value that can be used as an
- * index in the pt_hash array associated with the symbol table.
- *
- * ARGUMENTS:
- *
- * symtab - pointer to the symbol table
- * pname - pointer to the property name string
- *
- * RETURNS:
- *
- * The hash index is returned as the function value.
- */
- int
- PListHashName(PLSymbolTable_t *symtab, const char *pname)
- {
- unsigned int hashval = 0; /* hash value */
- while (*pname) {
- hashval = (hashval<<5) ^ (*pname++ & 0x7f);
- }
- return hashval % PLSIZENDX(symtab->pt_sizendx);
- }
- /*
- * FUNCTION: PListNameProp
- *
- * DESCRIPTION:
- *
- * This function assigns a name to a defined property with the
- * property index, pindex. If the property has an existing name,
- * it will be replaced with the name specified by pname.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pindex - the property index
- * pname - the new property name
- *
- * RETURNS:
- *
- * If successful, the property index (pindex) is returned as the
- * function value. Errors are indicated by a negative return code
- * as defined in plist.h.
- */
- 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;
- }
- /*
- * FUNCTION: PListSetType
- *
- * DESCRIPTION:
- *
- * This function sets the property type of the defined property
- * with the property index, pindex. The property list describing
- * the property type is specified by ptype. If ptype is NULL,
- * the property type will be set to be undefined (NULL).
- *
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pindex - the property index
- * ptype - the new property type, or NULL
- *
- * RETURNS:
- *
- * If successful, the property index (pindex) is returned as the
- * function value. Errors are indicated by a negative return code
- * as defined in plist.h.
- */
- NSAPI_PUBLIC int
- PListSetType(PList_t plist, int pindex, PList_t ptype)
- {
- PListStruct_t *pl = (PListStruct_t *)plist;
- PLValueStruct_t **ppval;
- PLValueStruct_t *pv;
- if (!plist) return ERRPLUNDEF;
- ppval = (PLValueStruct_t **)(pl->pl_ppval);
- /* Check for valid property index */
- if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
- /* Does the property exist? */
- pv = ppval[pindex - 1];
- if (pv) {
- /* Yes, set the new type */
- pv->pv_type = ptype;
- /* Successful return */
- return pindex;
- }
- }
- /* Error - invalid property index or non-existent property */
- return ERRPLINVPI;
- }
- /*
- * FUNCTION: PListSetValue
- *
- * DESCRIPTION:
- *
- * This function sets the value and optionally the type of a
- * defined property in a given property list. The pindex argument
- * specifies the property index, which must be greater than zero.
- * The ptype argument specifies a property list that describes the
- * property type. If ptype is NULL, the property type, if any, is
- * unchanged by this function. However, the property value is
- * always set to the value given by pvalue.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * pindex - the property index
- * pvalue - the new property value
- * ptype - the new property type, or NULL
- *
- * RETURNS:
- *
- * If successful, the property index (pindex) is returned as the
- * function value. Errors are indicated by a negative return code
- * as defined in plist.h.
- */
- NSAPI_PUBLIC int
- PListSetValue(PList_t plist, int pindex, const void *pvalue, PList_t ptype)
- {
- PListStruct_t *pl = (PListStruct_t *)plist;
- PLValueStruct_t **ppval;
- PLValueStruct_t *pv;
- if (!plist) return ERRPLUNDEF;
- ppval = (PLValueStruct_t **)(pl->pl_ppval);
- /* Check for valid property index */
- if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
- /* Does the property exist? */
- pv = ppval[pindex - 1];
- if (pv) {
- /* Yes, set the new value */
- pv->pv_value = (char *)pvalue;
- /* Set type if type is given */
- if (ptype) pv->pv_type = (PListStruct_t *)ptype;
- /* Successful return */
- return pindex;
- }
- }
- /* Error - invalid property index or non-existent property */
- return ERRPLINVPI;
- }
- /*
- * FUNCTION: PListEnumerate
- *
- * DESCRIPTION:
- *
- * This function walks through a specified property list
- * calling a user supplied function with the property
- * name and value as parameters.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * user_func - handle for the user function
- */
- NSAPI_PUBLIC void
- PListEnumerate(PList_t plist, PListFunc_t *user_func, void *user_data)
- {
- PListStruct_t *pl = (PListStruct_t *)plist;
- PLValueStruct_t **ppval;
- PLValueStruct_t *pv;
- int i;
- if (!plist) return;
- ppval = (PLValueStruct_t **)(pl->pl_ppval);
- /* Loop over the initialized property indices */
- for (i = 0; i < pl->pl_initpi; ++i) {
- /* Got a property here? */
- pv = ppval[i];
- if (pv) {
- (*user_func)(pv->pv_name, pv->pv_value, user_data);
- }
- }
- }
- /*
- * FUNCTION: PListCreateDuplicate
- *
- * DESCRIPTION:
- *
- * This function creates a new property list and returns a handle for
- * it. The source plist provides the new plists parameters.
- *
- * ARGUMENTS:
- *
- * src_plist - source plist to duplicate
- * mempool - handle for a memory pool to be associated
- * with the new property list, only
- * used if flags is set to PLFLG_NEW_MPOOL
- * flags - if PLFLG_NEW_MPOOL uses new_mempool
- * parameter
- *
- * RETURNS:
- *
- * If successful, the function return value is a handle for the new
- * property list. Otherwise NULL is returned.
- */
- static PList_t
- PListCreateDuplicate(PList_t src_plist, pool_handle_t *new_mempool, int flags)
- {
- PListStruct_t *plist; /* pointer to property list structure */
- int i;
- pool_handle_t *mempool;
- mempool = (flags == PLFLG_NEW_MPOOL) ? new_mempool : src_plist->pl_mempool;
- plist = (PListStruct_t *)pool_malloc(mempool, sizeof(PListStruct_t));
- if (plist) {
- /* Initialize property list structure */
- plist->pl_mempool = mempool;
- plist->pl_symtab = NULL;
- plist->pl_maxprop = src_plist->pl_maxprop;
- plist->pl_resvpi = src_plist->pl_resvpi;
- plist->pl_initpi = src_plist->pl_initpi;
- plist->pl_lastpi = src_plist->pl_lastpi;
- /* Set initialize size for array of property value pointers */
- plist->pl_cursize = src_plist->pl_cursize;
- /* Allocate the initial array of property value pointers */
- plist->pl_ppval = (pb_entry **)pool_malloc(mempool,
- (plist->pl_cursize *
- sizeof(PLValueStruct_t *)));
- if (!plist->pl_ppval) {
- /* Failed - insufficient memory */
- pool_free(mempool, (void *)plist);
- plist = NULL;
- }
- else {
- /* NULL out pointers in the reserved index range, if any */
- for (i = 0; i < plist->pl_lastpi; ++i) {
- plist->pl_ppval[i] = 0;
- }
- }
- }
- return (PList_t)plist;
- }
- /*
- * FUNCTION: PListDuplicate
- *
- * DESCRIPTION:
- *
- * This function duplicates a specified PList_t.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- * mempool - handle for a memory pool to be associated
- * with the new property list
- * resvprop - number of reserved property indices
- * maxprop - maximum number of properties in list
- * (zero or negative imposes no limit)
- * flags - unused, reserved, must be zero
- *
- * RETURNS:
- *
- * If successful, the function return value is a handle for the new
- * property list. Otherwise NULL is returned.
- */
- NSAPI_PUBLIC PList_t
- PListDuplicate(PList_t plist, pool_handle_t *new_mempool, int flags)
- {
- PListStruct_t *pl = (PListStruct_t *)plist;
- PLValueStruct_t **ppval;
- PLValueStruct_t *pv;
- int i;
- int rv = 0;
- PList_t new_plist;
- if (!plist) return NULL;
- new_plist = PListCreateDuplicate(plist, new_mempool, flags);
- if (new_plist == NULL) {
- return(NULL);
- }
- ppval = (PLValueStruct_t **)(pl->pl_ppval);
- /* Loop over the initialized property indices */
- for (i = 0; i < pl->pl_initpi; ++i) {
- /* Got a property here? */
- pv = ppval[i];
- if (pv) {
- /* Create the property */
- rv = PListDefProp(new_plist, i + 1, pv->pv_name, PLFLG_IGN_RES);
- if (rv > 0) {
-
- /* If that worked, set the value and type */
- rv = PListSetValue(new_plist, rv, pv->pv_value, pv->pv_type);
- }
-
- if ( rv <= 0 ) {
- PListDestroy(new_plist);
- return(NULL);
- }
- }
- }
- return(new_plist);
- }
- /*
- * FUNCTION: PListGetPool
- *
- * DESCRIPTION:
- *
- * This function returns the memory pool the PList is allocated from.
- *
- * ARGUMENTS:
- *
- * plist - handle for the property list
- *
- * RETURNS:
- *
- * The memory pool address, which can be NULL.
- */
- NSAPI_PUBLIC pool_handle_t *
- PListGetPool(PList_t plist)
- {
- if (!plist) return NULL;
- return(plist->pl_mempool);
- }
|