NSAPI_PUBLIC int
PListAssignValue(PList_t plist, const char *pname,
                 const void *pvalue, PList_t ptype)
{
    PListStruct_t *pl = (PListStruct_t *)plist;
    PLValueStruct_t *pv;
    int pindex;
    int i;

    if (!plist) return ERRPLUNDEF;

    /* Got a symbol table for this property list? */
    if (pl->pl_symtab) {

        /* Yes, compute hash of specified name */
        i = PListHashName(pl->pl_symtab, pname);

        /* Search hash collision list for matching name */
        for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {

            if (!strcmp(pname, pv->pv_name)) {

                /* Name match, get property index */
                pindex = pv->pv_pi;

                /* Set the new value */
                pv->pv_value = (char *)pvalue;

                /* Set type if type is given */
                if (ptype) pv->pv_type = (PListStruct_t *)ptype;

                /* Return the property index */
                return pindex;
            }
        }
    }

    /* Error - specified property name is undefined */
    return ERRPLUNDEF;
}
NSAPI_PUBLIC int
PListNameProp(PList_t plist, int pindex, const char *pname)
{
    PListStruct_t *pl = (PListStruct_t *)plist;
    PLValueStruct_t *pv;
    PLSymbolTable_t *pt;
    int i;

    if (!plist) return ERRPLUNDEF;

    pt = pl->pl_symtab;

    /* Check for valid property index */
    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {

        /* Does the property exist? */
        pv = ((PLValueStruct_t **)(pl->pl_ppval))[pindex - 1];
        if (pv) {

            /* If it has a name already, unname it */
            if (pv->pv_name) {
                PLValueStruct_t **pvp;

                /* Get hash bucket index */
                i = PListHashName(pt, pv->pv_name);

                /* Seach hash collision list for this property */
                for (pvp = &pt->pt_hash[i];
                     *pvp; pvp = &(*pvp)->pv_next) {

                    if (*pvp == pv) {

                        /* Remove it from the list */
                        *pvp = pv->pv_next;
                        pt->pt_nsyms--;
                        break;
                    }
                }

                /* Free the current name string */
                pool_free(pv->pv_mempool, (void *)(pv->pv_name));
            }

            /* Got a new name? */
            if (pname) {

                /* Allocate/grow the symbol table as needed */
                pt = PListSymbolTable(pl);
                if (!pt) {
                    return ERRPLNOMEM;
                }

                /* Duplicate the name string */
                pv->pv_name = pool_strdup(pv->pv_mempool, (char *)pname);

                /* Add name to symbol table */
                i = PListHashName(pt, pname);
                pv->pv_next = pt->pt_hash[i];
                pt->pt_hash[i] = pv;
                pt->pt_nsyms++;
            }

            /* Successful return */
            return pindex;
        }
    }

    /* Error - invalid property index or non-existent property */
    return ERRPLINVPI;
}
PLSymbolTable_t *
PListSymbolTable(PListStruct_t *pl)
{
    PLSymbolTable_t *pt;
    int i;

    pt = pl->pl_symtab;

    /* Is there a hash table? */
    if (!pl->pl_symtab) {

        /* No, create one */
        pt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1, PLHASHSIZE(0));

        pl->pl_symtab = pt;
    }
    else {

        /* Is it time to grow the hash table? */
        i = PLSIZENDX(pt->pt_sizendx);
        if ((pt->pt_sizendx < PLMAXSIZENDX) && pt->pt_nsyms >= (i + i)) {

            PLSymbolTable_t *npt;

            /* Yes, allocate the new table */
            npt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1,
                                                 PLHASHSIZE(pt->pt_sizendx+1));
            if (npt) {
                npt->pt_sizendx = pt->pt_sizendx + 1;
                npt->pt_nsyms = pt->pt_nsyms;

                /* Rehash all the names into the new table, preserving order */
                for (i = 0; i < PLSIZENDX(pt->pt_sizendx); ++i) {
                    /* While there are names at this hash index... */
                    while (pt->pt_hash[i]) {
                        PLValueStruct_t **pvp;
                        int j;

                        /* Find the last name at this hash index */
                        for (pvp = &pt->pt_hash[i]; (*pvp)->pv_next; pvp = &(*pvp)->pv_next);
                        
                        /* Move the name to the new table */
                        j = PListHashName(npt, (*pvp)->pv_name);
                        (*pvp)->pv_next = npt->pt_hash[j];
                        npt->pt_hash[j] = (*pvp);

                        /* Remove the name from the old table */
                        *pvp = NULL;
                    }
                }

                pl->pl_symtab = npt;

                /* Free the old symbol table */
                pool_free(pl->pl_mempool, (void *)pt);
                pt = npt;
            }
        }
    }

    return pl->pl_symtab;
}
NSAPI_PUBLIC const void *
PListDeleteProp(PList_t plist, int pindex, const char *pname_in)
{
    PListStruct_t *pl = (PListStruct_t *)plist;
    PLValueStruct_t **ppval;
    PLValueStruct_t **pvp;
    PLValueStruct_t *pv = NULL;
    int i;
    const void *pvalue = NULL;
    char *pname = (char *)pname_in;

    if (!plist) return NULL;

    ppval = (PLValueStruct_t **)(pl->pl_ppval);

    /* Check for valid property index */
    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {

        /* Get the pointer to the property structure */
        pv = ppval[pindex - 1];
	pname = 0;
	if (pv) {
	    pname = pv->pv_name;
	}
    }

    if (pname && pl->pl_symtab) {

        /* Compute hash of specified property name */
        i = PListHashName(pl->pl_symtab, pname);

        /* Search hash collision list for matching name */
        for (pvp = &pl->pl_symtab->pt_hash[i]; *pvp; pvp = &(*pvp)->pv_next) {

            pv = *pvp;
            if (!strcmp(pname, pv->pv_name)) {

                /* Found it.  Get its index and remove it. */
                pindex = pv->pv_pi;
                *pvp = pv->pv_next;
                pl->pl_symtab->pt_nsyms--;
                break;
            }
            pv = NULL;
        }
    }

    /* Found the indicated property by index or name? */
    if (pv) {

        /* Yes, remove it from the property list */
        ppval[pindex - 1] = NULL;

        /* Free the property name, if any */
        if (pv->pv_name) {
            pool_free(pv->pv_mempool, (void *)(pv->pv_name));
        }
        pvalue = pv->pv_value;

        /* Free the property */
        pool_free(pv->pv_mempool, (void *)pv);
    }
    return(pvalue);
}
Пример #5
0
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;
}