#include "../daemon/netsite.h"
#include "plist.h"
#include "plist_pvt.h"
int plistHashSizes[] =
PLSTSIZES;
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;
if (pl->pl_symtab) {
i = PListHashName(pl->pl_symtab, pname);
for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
if (!strcmp(pname, pv->pv_name)) {
pindex = pv->pv_pi;
pv->pv_value = (
char *)pvalue;
if (ptype) pv->pv_type = (
PListStruct_t *)ptype;
return pindex;
}
}
}
return ERRPLUNDEF;
}
NSAPI_PUBLIC PList_t
PListCreate(
pool_handle_t *mempool,
int resvprop,
int maxprop,
int flags)
{
PListStruct_t *plist;
int i;
plist = (
PListStruct_t *)pool_malloc(mempool,
sizeof(
PListStruct_t));
if (plist) {
if (maxprop <
0) maxprop =
0;
if (resvprop >
0) {
if (maxprop && (resvprop > maxprop)) resvprop = maxprop;
}
else resvprop =
0;
plist->pl_mempool = mempool;
plist->pl_symtab =
NULL;
plist->pl_maxprop = maxprop;
plist->pl_resvpi = resvprop;
plist->pl_initpi = resvprop;
plist->pl_lastpi = resvprop;
plist->pl_cursize = (resvprop) ? resvprop :
PLIST_DEFSIZE;
plist->pl_ppval = (pb_entry **)pool_malloc(mempool,
(plist->pl_cursize *
sizeof(
PLValueStruct_t *)));
if (!plist->pl_ppval) {
pool_free(mempool, (
void *)plist);
plist =
NULL;
}
else {
for (i =
0; i < plist->pl_lastpi; ++i) {
plist->pl_ppval[i] =
0;
}
}
}
return (
PList_t)plist;
}
NSAPI_PUBLIC int
PListDefProp(
PList_t plist,
int pindex,
const char *pname,
const int flags)
{
PListStruct_t *pl = (
PListStruct_t *)plist;
PLValueStruct_t *pv;
if (!plist)
return ERRPLUNDEF;
if (pindex >
0) {
if (flags !=
PLFLG_IGN_RES && pindex > pl->pl_resvpi) {
return ERRPLINVPI;
}
PLValueStruct_t **ppval = (
PLValueStruct_t **)(pl->pl_ppval);
if (ppval[pindex -
1]) {
return ERRPLEXIST;
}
}
else {
pindex = PListGetFreeIndex(pl);
if (pindex <
1) {
return pindex;
}
}
pv = (
PLValueStruct_t *)pool_calloc(pl->pl_mempool,
1,
sizeof(
PLValueStruct_t));
if (!pv) {
return ERRPLNOMEM;
}
PLValueStruct_t **ppval = (
PLValueStruct_t **)(pl->pl_ppval);
pv->pv_pbentry.param = &pv->pv_pbparam;
pv->pv_pi = pindex;
pv->pv_mempool = pl->pl_mempool;
ppval[pindex -
1] = pv;
if (pname) {
return PListNameProp(plist, pindex, pname);
}
return pindex;
}
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);
if ((pindex >
0) && (pindex <= pl->pl_initpi)) {
pv = ppval[pindex -
1];
pname =
0;
if (pv) {
pname = pv->pv_name;
}
}
if (pname && pl->pl_symtab) {
i = PListHashName(pl->pl_symtab, pname);
for (pvp = &pl->pl_symtab->pt_hash[i]; *pvp; pvp = &(*pvp)->pv_next) {
pv = *pvp;
if (!strcmp(pname, pv->pv_name)) {
pindex = pv->pv_pi;
*pvp = pv->pv_next;
pl->pl_symtab->pt_nsyms--;
break;
}
pv =
NULL;
}
}
if (pv) {
ppval[pindex -
1] =
NULL;
if (pv->pv_name) {
pool_free(pv->pv_mempool, (
void *)(pv->pv_name));
}
pvalue = pv->pv_value;
pool_free(pv->pv_mempool, (
void *)pv);
}
return(pvalue);
}
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;
if (pl->pl_symtab) {
i = PListHashName(pl->pl_symtab, pname);
for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
if (!strcmp(pname, pv->pv_name)) {
pindex = pv->pv_pi;
if (pvalue) *pvalue = (
void *)(pv->pv_value);
if (ptype) *ptype = (
PList_t)(pv->pv_type);
return pindex;
}
}
}
return ERRPLUNDEF;
}
NSAPI_PUBLIC int
PListInitProp(
PList_t plist,
int pindex,
const char *pname,
const void *pvalue,
PList_t ptype)
{
int rv;
if (!plist)
return ERRPLUNDEF;
rv = PListDefProp(plist, pindex, pname,
PLFLG_USE_RES);
if (rv >
0) {
rv = PListSetValue(plist, rv, pvalue, ptype);
}
return rv;
}
NSAPI_PUBLIC PList_t
PListNew(
pool_handle_t *mempool)
{
return PListCreate(mempool,
0,
0,
0);
}
void
PListDestroy(
PList_t plist)
{
PListStruct_t *pl = (
PListStruct_t *)plist;
PLValueStruct_t **ppval;
PLValueStruct_t *pv;
int i;
if (!plist)
return;
if (pl->pl_symtab) {
pool_free(pl->pl_mempool, (
void *)(pl->pl_symtab));
}
ppval = (
PLValueStruct_t **)(pl->pl_ppval);
for (i =
0; i < pl->pl_initpi; ++i) {
pv = ppval[i];
if (pv) {
if (pv->pv_name) {
pool_free(pv->pv_mempool, (
void *)(pv->pv_name));
}
pool_free(pv->pv_mempool, (
void *)pv);
}
}
pool_free(pl->pl_mempool, (
void *)ppval);
pool_free(pl->pl_mempool, (
void *)pl);
}
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);
if ((pindex >
0) && (pindex <= pl->pl_initpi)) {
pv = ppval[pindex -
1];
if (pv) {
if (pvalue) *pvalue = (
void *)(pv->pv_value);
if (ptype) *ptype = (
PList_t)(pv->pv_type);
return pindex;
}
}
return ERRPLINVPI;
}
unsigned int
PListHash(
const char *string)
{
unsigned int hashval =
0;
while (*string) {
hashval = (hashval<<
5) ^ (*string++ & 0x7f);
}
return hashval;
}
int
PListHashName(
PLSymbolTable_t *symtab,
const char *pname)
{
return PListHash(pname) %
PLSIZENDX(symtab->pt_sizendx);
}
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;
if ((pindex >
0) && (pindex <= pl->pl_initpi)) {
pv = ((
PLValueStruct_t **)(pl->pl_ppval))[pindex -
1];
if (pv) {
if (pv->pv_name) {
PLValueStruct_t **pvp;
i = PListHashName(pt, pv->pv_name);
for (pvp = &pt->pt_hash[i];
*pvp; pvp = &(*pvp)->pv_next) {
if (*pvp == pv) {
*pvp = pv->pv_next;
pt->pt_nsyms--;
break;
}
}
pool_free(pv->pv_mempool, (
void *)(pv->pv_name));
}
if (pname) {
pt = PListSymbolTable(pl);
if (!pt) {
return ERRPLNOMEM;
}
pv->pv_name = pool_strdup(pv->pv_mempool, (
char *)pname);
i = PListHashName(pt, pname);
pv->pv_next = pt->pt_hash[i];
pt->pt_hash[i] = pv;
pt->pt_nsyms++;
}
return pindex;
}
}
return ERRPLINVPI;
}
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);
if ((pindex >
0) && (pindex <= pl->pl_initpi)) {
pv = ppval[pindex -
1];
if (pv) {
pv->pv_type = ptype;
return pindex;
}
}
return ERRPLINVPI;
}
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);
if ((pindex >
0) && (pindex <= pl->pl_initpi)) {
pv = ppval[pindex -
1];
if (pv) {
pv->pv_value = (
char *)pvalue;
if (ptype) pv->pv_type = (
PListStruct_t *)ptype;
return pindex;
}
}
return ERRPLINVPI;
}
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);
for (i =
0; i < pl->pl_initpi; ++i) {
pv = ppval[i];
if (pv) {
(*user_func)(pv->pv_name, pv->pv_value, user_data);
}
}
}
static PList_t
PListCreateDuplicate(
PList_t src_plist,
pool_handle_t *new_mempool,
int flags)
{
PListStruct_t *plist;
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) {
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;
plist->pl_cursize = src_plist->pl_cursize;
plist->pl_ppval = (pb_entry **)pool_malloc(mempool,
(plist->pl_cursize *
sizeof(
PLValueStruct_t *)));
if (!plist->pl_ppval) {
pool_free(mempool, (
void *)plist);
plist =
NULL;
}
else {
for (i =
0; i < plist->pl_lastpi; ++i) {
plist->pl_ppval[i] =
0;
}
}
}
return (
PList_t)plist;
}
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);
for (i =
0; i < pl->pl_initpi; ++i) {
pv = ppval[i];
if (pv) {
rv = PListDefProp(new_plist, i +
1, pv->pv_name,
PLFLG_IGN_RES);
if (rv >
0) {
rv = PListSetValue(new_plist, rv, pv->pv_value, pv->pv_type);
}
if ( rv <=
0 ) {
PListDestroy(new_plist);
return(
NULL);
}
}
}
return(new_plist);
}
NSAPI_PUBLIC pool_handle_t *
PListGetPool(
PList_t plist)
{
if (!plist)
return NULL;
return(plist->pl_mempool);
}
int
PListGetFreeIndex(
PListStruct_t *pl)
{
PLValueStruct_t **ppval = (
PLValueStruct_t **)(pl->pl_ppval);
int wrapped;
int i;
for (wrapped =
0, i = pl->pl_lastpi; ;) {
if (i < pl->pl_initpi) {
if (ppval[i] ==
0)
break;
++i;
}
else {
if (i < pl->pl_cursize) {
ppval[i] =
0;
}
else {
if (!wrapped) {
i = pl->pl_resvpi;
wrapped =
1;
continue;
}
i = pl->pl_cursize;
if (pl->pl_maxprop && (i > pl->pl_maxprop)) {
return ERRPLFULL;
}
int cursize = i +
PLIST_DEFGROW;
ppval = (
PLValueStruct_t **)pool_realloc(pl->pl_mempool,
(
void *)ppval,
(cursize *
sizeof(
PLValueStruct_t *)));
if (!ppval) {
return ERRPLNOMEM;
}
ppval[i] =
NULL;
pl->pl_ppval = (pb_entry **)ppval;
pl->pl_cursize = cursize;
}
pl->pl_initpi = i +
1;
break;
}
}
pl->pl_lastpi = i +
1;
return i +
1;
}
PLSymbolTable_t *
PListSymbolTable(
PListStruct_t *pl)
{
PLSymbolTable_t *pt;
int i;
pt = pl->pl_symtab;
if (!pl->pl_symtab) {
pt = (
PLSymbolTable_t *)pool_calloc(pl->pl_mempool,
1,
PLHASHSIZE(
0));
pl->pl_symtab = pt;
}
else {
i =
PLSIZENDX(pt->pt_sizendx);
if ((pt->pt_sizendx <
PLMAXSIZENDX) && pt->pt_nsyms >= (i + i)) {
PLSymbolTable_t *npt;
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;
for (i =
0; i <
PLSIZENDX(pt->pt_sizendx); ++i) {
while (pt->pt_hash[i]) {
PLValueStruct_t **pvp;
int j;
for (pvp = &pt->pt_hash[i]; (*pvp)->pv_next; pvp = &(*pvp)->pv_next);
j = PListHashName(npt, (*pvp)->pv_name);
(*pvp)->pv_next = npt->pt_hash[j];
npt->pt_hash[j] = (*pvp);
*pvp =
NULL;
}
}
pl->pl_symtab = npt;
pool_free(pl->pl_mempool, (
void *)pt);
pt = npt;
}
}
}
return pl->pl_symtab;
}