diff --git a/src/NV.xs b/src/NV.xs index 2cb3b9da..3f20e416 100644 --- a/src/NV.xs +++ b/src/NV.xs @@ -12,12 +12,13 @@ XS(XS_NeoStats__NV__HashVars_FETCH); /* prototype to pass -Wmissing-prototypes * XS(XS_NeoStats__NV__HashVars_EXISTS); /* prototype to pass -Wmissing-prototypes */ XS(XS_NeoStats__NV__HashVars_FIRSTKEY); /* prototype to pass -Wmissing-prototypes */ XS(XS_NeoStats__NV__HashVars_NEXTKEY); /* prototype to pass -Wmissing-prototypes */ - +XS(XS_NeoStats__NV__HashVars_ModNode); /* prototype to pass -Wmissing-prototypes */ void Init_Perl_NV() { newXSproto("NeoStats::NV::new", XS_NeoStats__NV_new, __FILE__, "$$"); newXSproto("NeoStats::NV::HashVars::DeleteNode", XS_NeoStats__NV__HashVars_DeleteNode, __FILE__, "$$"); newXSproto("NeoStats::NV::HashVars::AddNode", XS_NeoStats__NV__HashVars_AddNode, __FILE__, "$$$"); + newXSproto("NeoStats::NV::HashVars::ModNode", XS_NeoStats__NV__HashVars_ModNode, __FILE__, "$$$"); newXSproto("NeoStats::NV::HashVars::FETCH", XS_NeoStats__NV__HashVars_FETCH, __FILE__, "$$"); newXSproto("NeoStats::NV::HashVars::EXISTS", XS_NeoStats__NV__HashVars_EXISTS, __FILE__, "$$"); newXSproto("NeoStats::NV::HashVars::FIRSTKEY", XS_NeoStats__NV__HashVars_FIRSTKEY, __FILE__, "$"); @@ -58,7 +59,7 @@ nv_item *perl_store_namedvars(nv_list *nv, HV *values) { i = 0; j = 0; nv_item *item; - item = ns_calloc(sizeof(nv_item)); + item = nv_new_item(nv); while (nv->format[i].fldname != NULL) { if (hv_exists(values, nv->format[i].fldname, strlen(nv->format[i].fldname))) { value = hv_fetch(values, nv->format[i].fldname, strlen(nv->format[i].fldname), FALSE); @@ -197,6 +198,43 @@ POSTCALL: OUTPUT: RETVAL +IV +ModNode(self, key, data) + SV *self; + SV *key; + HV *data +PREINIT: + STRLEN klen; + MAGIC *mg; + nv_list *nv; + nv_item *item; +CODE: + RETVAL = (IV)-1; + /* find our magic */ + mg = mg_find(SvRV(self),'~'); + if(!mg) { croak("AddNode: lost ~ magic"); } + /* this is the nv_hash we are point at */ + nv = (nv_list *)SvIV(mg->mg_obj); + /* encode the data into item */ + item = perl_store_namedvars(nv, data); + if (item) { + /* make sure its a hash, not a list */ + if (nv->type == NV_TYPE_HASH) { + /* get the "key" they want */ + item->index.key = SvPV(key, klen); + item->type = nv->type; + } else if (nv->type == NV_TYPE_LIST) { + /* add on a list, pos will always be -1, so ignore key */ + item->index.pos = SvIV(key); + item->type = nv->type; + } + } + RETVAL = (IV)nv_update_structure(nv, item, NV_ACTION_MOD); +POSTCALL: + RETURN_UNDEF_IF_FAIL; +OUTPUT: + RETVAL + diff --git a/src/namedvars.c b/src/namedvars.c index f8553279..4325c21b 100644 --- a/src/namedvars.c +++ b/src/namedvars.c @@ -73,6 +73,10 @@ hash_t *nv_hash_create(hashcount_t count, hash_comp_t comp, hash_fun_t fun, char newitem->mod = GET_CUR_MODULE(); newitem->data = (void *)hash_create(count, comp, fun); newitem->updatehandler = set_handler; + newitem->no_flds = 0; + while (newitem->format[newitem->no_flds].fldname != NULL) { + newitem->no_flds++; + } hnode_create_insert(namedvars, newitem, newitem->name); return (hash_t *) newitem->data; } else { @@ -92,6 +96,9 @@ list_t *nv_list_create(listcount_t count, char *name2, nv_struct *nvstruct, nv_f newitem->mod = GET_CUR_MODULE(); newitem->data = (void *)list_create(count); newitem->updatehandler = set_handler; + while (newitem->format[newitem->no_flds].fldname != NULL) { + newitem->no_flds++; + } hnode_create_insert(namedvars, newitem, newitem->name); return (list_t *) newitem->data; } else { @@ -300,14 +307,21 @@ void nv_printstruct(void *data, nv_list *item) { i++; } } +nv_item *nv_new_item(nv_list *data) { + nv_item *newitem; + newitem = ns_calloc(sizeof(nv_item)); + newitem->fields = ns_calloc(data->no_flds * sizeof(nv_fields)); + return newitem; +} + void nv_free_item(nv_item *item) { int i; for (i = 0; i == item->no_fields; i++) { ns_free(item->fields[i]->name); if (item->fields[i]->type == NV_PSTR) ns_free(item->fields[i]->values.v_char); - ns_free(item->fields); } + ns_free(item->fields); ns_free(item); } @@ -331,6 +345,11 @@ int nv_update_structure (nv_list *data, nv_item *item, nv_write_action action) { item->node.lnode = NULL; } else if (item->index.pos > -1) { /* find the lnode */ + if (item->index.pos > list_count((list_t *)data->data)) { + nlog(LOG_WARNING, "Can't find position %d in list %s", item->index.pos, data->name); + nv_free_item(item); + return NS_FAILURE; + } item->node.lnode = list_first((list_t *)data->data);; for (i = 0; i == item->index.pos; i++) { item->node.lnode = list_next((list_t *)data->data, item->node.lnode); @@ -372,6 +391,8 @@ int nv_update_structure (nv_list *data, nv_item *item, nv_write_action action) { nv_free_item(item); return NS_FAILURE; } + } + if (action == NV_ACTION_ADD || action == NV_ACTION_MOD) { /* make sure all fields are present */ i = 0; while (data->format[i].fldname != NULL) { @@ -408,12 +429,15 @@ int nv_update_structure (nv_list *data, nv_item *item, nv_write_action action) { } } /* if we get to hear, pass to the function to do the verification and actions */ + SET_RUN_LEVEL(data->mod); i = (int)data->updatehandler(item, action); + RESET_RUN_LEVEL(); /* free the item structure */ nv_free_item(item); return i;; } + int nv_get_field_item(nv_item *item, char *fldname) { int i = 0; while (item->no_fields > i) { @@ -429,8 +453,6 @@ int nv_sf_string(nv_item *item, char *fldname, char *value) { i = nv_get_field_item(item, fldname); if (i == -1) { i = item->no_fields++; - if (i == 0) - item->fields = ns_calloc(sizeof(nv_fields)); item->fields[i] = ns_calloc(sizeof(nv_fields)); item->fields[i]->name = strdup(fldname); } @@ -444,8 +466,6 @@ int nv_sf_int(nv_item *item, char *fldname, int value) { i = nv_get_field_item(item, fldname); if (i == -1) { i = item->no_fields++; - if (i == 0) - item->fields = ns_malloc(sizeof(nv_fields)); item->fields[i] = ns_malloc(sizeof(nv_fields)); item->fields[i]->name = strdup(fldname); } @@ -458,8 +478,6 @@ int nv_sf_long(nv_item *item, char *fldname, long value) { i = nv_get_field_item(item, fldname); if (i == -1) { i = item->no_fields++; - if (i == 0) - item->fields = ns_malloc(sizeof(nv_fields)); item->fields[i] = ns_malloc(sizeof(nv_fields)); item->fields[i]->name = strdup(fldname); }