| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192 |
- /** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * 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);
- }
|