| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191 |
- /** 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);
- if (((size_t)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) {
- 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);
- }
|