Update from PSI
r1040 | ffr | 2006-08-03 10:05:34 +1000 (Thu, 03 Aug 2006) | 2 lines
This commit is contained in:
committed by
Douglas Clowes
parent
074f1cb3cd
commit
dbc07ee639
815
hipadaba.c
Normal file
815
hipadaba.c
Normal file
@@ -0,0 +1,815 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
The hierarchical parameter database code. For more information, see
|
||||
hipadaba.h
|
||||
|
||||
copyright: GPL
|
||||
|
||||
Mark Koennecke, June 2006
|
||||
---------------------------------------------------------------------------*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include "hipadaba.h"
|
||||
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
#define HDBMAGICK 77119900
|
||||
/*================== internal functions ===================================*/
|
||||
void DeleteCallbackChain(pHdbCallback root){
|
||||
pHdbCallback current = NULL, thisEntry;
|
||||
|
||||
current = root;
|
||||
while(current != NULL){
|
||||
if(current->killFunc != NULL){
|
||||
current->killFunc(current->userData);
|
||||
}
|
||||
thisEntry = current;
|
||||
current = (pHdbCallback)current->next;
|
||||
free(thisEntry);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void DeleteNodeData(pHdb node){
|
||||
pHdb tmp = NULL;
|
||||
|
||||
if(node == NULL){
|
||||
return;
|
||||
}
|
||||
DeleteCallbackChain(node->writeCallbacks);
|
||||
DeleteCallbackChain(node->updateCallbacks);
|
||||
DeleteCallbackChain(node->readCallbacks);
|
||||
|
||||
if(node->name != NULL){
|
||||
free(node->name);
|
||||
}
|
||||
ReleaseHdbValue(&node->value);
|
||||
node->magic = 000000;
|
||||
|
||||
while(node->child != NULL){
|
||||
tmp = node->child;
|
||||
node->child = node->child->next;
|
||||
DeleteNodeData(tmp);
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
void RemoveHdbNodeFromParent(pHdb node){
|
||||
pHdb parent = NULL;
|
||||
pHdb current = NULL;
|
||||
|
||||
parent = node->mama;
|
||||
if(parent != NULL){
|
||||
if(parent->child == node){
|
||||
parent->child = node->next;
|
||||
return;
|
||||
}
|
||||
current = parent->child;
|
||||
while(current->next != node){
|
||||
current = current->next;
|
||||
}
|
||||
current->next = current->next->next;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void RemoveCallbackNode(pHdbCallback victim){
|
||||
if(victim->previous != NULL) {
|
||||
victim->previous->next = victim->next;
|
||||
}
|
||||
if(victim->next != NULL){
|
||||
victim->next->previous = victim->previous;
|
||||
}
|
||||
if(victim->killFunc != NULL){
|
||||
victim->killFunc(victim->userData);
|
||||
}
|
||||
free(victim);
|
||||
}
|
||||
/*-----------------------------------------------------------------------
|
||||
* This code is ugly: the problem is fixing up the start of the chain.
|
||||
* Think about it and improve
|
||||
* ----------------------------------------------------------------------*/
|
||||
static pHdbCallback DeleteForID(pHdbCallback root, int id){
|
||||
pHdbCallback current = root;
|
||||
pHdbCallback tmp = NULL;
|
||||
pHdbCallback result = NULL;
|
||||
|
||||
if(root == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* delete at the start of the chain
|
||||
*/
|
||||
result = root;
|
||||
while(result->id == id){
|
||||
tmp = result;
|
||||
result = result->next;
|
||||
RemoveCallbackNode(tmp);
|
||||
if(result == NULL){
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* delete nodes in the middle of the chain
|
||||
*/
|
||||
current = result;
|
||||
while(current != NULL){
|
||||
if(current->id == id){
|
||||
tmp = current;
|
||||
current = (pHdbCallback)current->next;
|
||||
RemoveCallbackNode(tmp);
|
||||
} else {
|
||||
current = (pHdbCallback)current->next;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static pHdbCallback DeleteForInternalID(pHdbCallback root, int id){
|
||||
pHdbCallback current = root;
|
||||
pHdbCallback tmp = NULL;
|
||||
pHdbCallback result = NULL;
|
||||
|
||||
if(root == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* delete at the start of the chain
|
||||
*/
|
||||
result = root;
|
||||
while(result->internalID == id){
|
||||
tmp = result;
|
||||
result = result->next;
|
||||
if(tmp->killFunc != NULL){
|
||||
tmp->killFunc(tmp->userData);
|
||||
}
|
||||
free(tmp);
|
||||
if(result == NULL){
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* delete nodes in the middle of the chain
|
||||
*/
|
||||
current = result;
|
||||
while(current != NULL){
|
||||
if(current->internalID == id){
|
||||
if(current->next != NULL){
|
||||
current->next->previous = current->previous;
|
||||
}
|
||||
if(current->previous != NULL){
|
||||
current->previous->next = current->next;
|
||||
}
|
||||
tmp = current;
|
||||
current = (pHdbCallback)current->next;
|
||||
if(tmp->killFunc != NULL){
|
||||
tmp->killFunc(tmp->userData);
|
||||
}
|
||||
free(tmp);
|
||||
} else {
|
||||
current = (pHdbCallback)current->next;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int InvokeCallbackChain(pHdbCallback root, pHdb node,
|
||||
void *callData, hdbValue v){
|
||||
pHdbCallback current = root;
|
||||
int status;
|
||||
|
||||
while(current != NULL){
|
||||
status = current->userCallback(current->userData,callData,
|
||||
node,v);
|
||||
if(status != 1){
|
||||
return status;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
char *hdbTrim(char *str)
|
||||
{
|
||||
char *ibuf = str, *obuf = str;
|
||||
int i = 0, cnt = 0;
|
||||
|
||||
/*
|
||||
** Trap NULL
|
||||
*/
|
||||
|
||||
if (str)
|
||||
{
|
||||
/*
|
||||
** Remove leading spaces (from RMLEAD.C)
|
||||
*/
|
||||
|
||||
for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf)
|
||||
;
|
||||
if (str != ibuf)
|
||||
memmove(str, ibuf, ibuf - str);
|
||||
|
||||
/*
|
||||
** Collapse embedded spaces (from LV1WS.C)
|
||||
*/
|
||||
|
||||
while (*ibuf)
|
||||
{
|
||||
if (isspace(*ibuf) && cnt)
|
||||
ibuf++;
|
||||
else
|
||||
{
|
||||
if (!isspace(*ibuf))
|
||||
cnt = 0;
|
||||
else
|
||||
{
|
||||
*ibuf = ' ';
|
||||
cnt = 1;
|
||||
}
|
||||
obuf[i++] = *ibuf++;
|
||||
}
|
||||
}
|
||||
obuf[i] = '\0';
|
||||
|
||||
/*
|
||||
** Remove trailing spaces (from RMTRAIL.C)
|
||||
*/
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (!isspace(obuf[i]))
|
||||
break;
|
||||
}
|
||||
obuf[++i] = '\0';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static pHdb locateChild(pHdb root, char *name){
|
||||
pHdb current = NULL;
|
||||
|
||||
current = root->child;
|
||||
while(current != NULL){
|
||||
if(strcmp(current->name,name) == 0){
|
||||
return current;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*================= data functions ========================================*/
|
||||
hdbValue makeHdbValue(int datatype, int length){
|
||||
hdbValue val;
|
||||
|
||||
memset(&val,0,sizeof(hdbValue));
|
||||
val.dataType = datatype;
|
||||
|
||||
switch(datatype){
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
val.arrayLength = length;
|
||||
val.v.intArray = malloc(length*sizeof(long));
|
||||
if(val.v.intArray != NULL){
|
||||
memset(val.v.intArray,0,length*sizeof(long));
|
||||
}
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
case HIPFLOATVARAR:
|
||||
val.arrayLength = length;
|
||||
val.v.floatArray = malloc(length*sizeof(double));
|
||||
if(val.v.floatArray != NULL){
|
||||
memset(val.v.floatArray,0,length*sizeof(double));
|
||||
}
|
||||
break;
|
||||
case HIPTEXT:
|
||||
val.v.text = strdup("UNKNOWN");
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbInt(int initValue){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPINT;
|
||||
result.v.intValue = initValue;
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbFloat(double initValue){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPFLOAT;
|
||||
result.v.doubleValue = initValue;
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbText(char *initText){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPTEXT;
|
||||
result.v.text = initText;
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbIntArray(int length, long *data){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPINTAR;
|
||||
result.arrayLength = length;
|
||||
result.v.intArray = data;
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbFloatArrray(int length, double *data){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPFLOATAR;
|
||||
result.arrayLength = length;
|
||||
result.v.floatArray = data;
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void ReleaseHdbValue(hdbValue *v){
|
||||
switch(v->dataType){
|
||||
case HIPTEXT:
|
||||
if(v->v.text != NULL){
|
||||
free(v->v.text);
|
||||
}
|
||||
break;
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
if(v->v.intArray != NULL){
|
||||
free(v->v.intArray);
|
||||
}
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
case HIPFLOATVARAR:
|
||||
if(v->v.floatArray != NULL){
|
||||
free(v->v.floatArray);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
int compareHdbValue(hdbValue v1, hdbValue v2){
|
||||
int i;
|
||||
|
||||
if(v1.dataType != v2.dataType){
|
||||
return 0;
|
||||
}
|
||||
switch(v1.dataType){
|
||||
case HIPNONE:
|
||||
return 0;
|
||||
break;
|
||||
case HIPINT:
|
||||
if(v1.v.intValue == v2.v.intValue){
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case HIPFLOAT:
|
||||
if(ABS(v1.v.doubleValue - v2.v.doubleValue) < .01){
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case HIPTEXT:
|
||||
if(strcmp(v1.v.text,v2.v.text) == 0){
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
if(v1.arrayLength != v2.arrayLength){
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < v1.arrayLength; i++){
|
||||
if(v1.v.intArray[i] != v2.v.intArray[i]){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
case HIPFLOATVARAR:
|
||||
if(v1.arrayLength != v2.arrayLength){
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < v1.arrayLength; i++){
|
||||
if(ABS(v1.v.floatArray[i] - v2.v.floatArray[i]) > .01){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int cloneHdbValue(hdbValue *source, hdbValue *clone){
|
||||
|
||||
memset(clone,0,sizeof(hdbValue));
|
||||
clone->dataType = source->dataType;
|
||||
return copyHdbValue(source, clone);
|
||||
}
|
||||
/*================= node functions ========================================*/
|
||||
pHdb MakeHipadabaNode(char *name, int datatype, int length){
|
||||
pHdb pNew = NULL;
|
||||
|
||||
pNew = malloc(sizeof(Hdb));
|
||||
if(pNew == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memset(pNew,0,sizeof(Hdb));
|
||||
pNew->magic = HDBMAGICK;
|
||||
pNew->name = strdup(name);
|
||||
pNew->value.dataType = datatype;
|
||||
switch(datatype){
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
pNew->value.arrayLength = length;
|
||||
pNew->value.v.intArray = malloc(length*sizeof(long));
|
||||
if(pNew->value.v.intArray == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memset(pNew->value.v.intArray,0,length*sizeof(long));
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
case HIPFLOATVARAR:
|
||||
pNew->value.arrayLength = length;
|
||||
pNew->value.v.floatArray = malloc(length*sizeof(double));
|
||||
if(pNew->value.v.floatArray == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memset(pNew->value.v.floatArray,0,length*sizeof(double));
|
||||
break;
|
||||
case HIPTEXT:
|
||||
pNew->value.v.text = strdup("UNKNOWN");
|
||||
break;
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void AddHipadabaChild(pHdb parent, pHdb child){
|
||||
pHdb current = NULL, prev = NULL;
|
||||
|
||||
assert(parent != NULL && child != NULL);
|
||||
|
||||
current = parent->child;
|
||||
child->mama = parent;
|
||||
if(current == NULL){
|
||||
parent->child = child;
|
||||
child->next = NULL;
|
||||
} else {
|
||||
/*
|
||||
* step to end of child chain
|
||||
*/
|
||||
while(current != NULL){
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
child->next = NULL;
|
||||
prev->next = child;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void DeleteHipadabaNode(pHdb node){
|
||||
pHdb current = NULL, tmp = NULL;
|
||||
|
||||
if(node == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveHdbNodeFromParent(node);
|
||||
|
||||
DeleteNodeData(node);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int isHdbNodeValid(pHdb node){
|
||||
if(node == NULL){
|
||||
return 0;
|
||||
}
|
||||
if(node->magic == HDBMAGICK){
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pHdb GetHipadabaNode(pHdb root, char *puth){
|
||||
pHdb resultNode = NULL;
|
||||
char *separator = NULL;
|
||||
char *path = NULL, *pathData;
|
||||
|
||||
/*
|
||||
* I need to make a copy in order to get the path in writable memory.
|
||||
* Otherwise we SEGFAULT in hdbTrim when this function is called with
|
||||
* a string constant in puth
|
||||
*/
|
||||
pathData = strdup(puth);
|
||||
path = pathData;
|
||||
if(path == NULL){
|
||||
return NULL;
|
||||
}
|
||||
path = hdbTrim(path);
|
||||
|
||||
if(strcmp(path,"/") == 0 || strlen(path) == 0){
|
||||
free(pathData);
|
||||
return root;
|
||||
}
|
||||
|
||||
if(path[0] == '/'){
|
||||
path++;
|
||||
}
|
||||
|
||||
separator = strchr(path,'/');
|
||||
if(separator == NULL){
|
||||
resultNode = locateChild(root,path);
|
||||
free(pathData);
|
||||
return resultNode;
|
||||
} else {
|
||||
*separator = '\0';
|
||||
resultNode = locateChild(root, path);
|
||||
if(resultNode == NULL){
|
||||
free(pathData);
|
||||
return NULL;
|
||||
} else {
|
||||
separator++;
|
||||
resultNode = GetHipadabaNode(resultNode,separator);
|
||||
free(pathData);
|
||||
return resultNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char *GetHipadabaPath(pHdb node){
|
||||
pHdb nodeStack[64];
|
||||
int depth = 0, length = 0, i;
|
||||
pHdb current = NULL;
|
||||
char *pPtr = NULL;
|
||||
|
||||
/**
|
||||
* build a nodestack and find out required string length for path
|
||||
*/
|
||||
current = node;
|
||||
while(current != NULL){
|
||||
length += strlen(current->name) + 1;
|
||||
nodeStack[depth] = current;
|
||||
depth++;
|
||||
assert(depth < 64);
|
||||
current = current->mama;
|
||||
}
|
||||
|
||||
pPtr = malloc(length*sizeof(char));
|
||||
if(pPtr == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memset(pPtr,0,length*sizeof(char));
|
||||
|
||||
/*
|
||||
* we wish to decremement by one because above loop
|
||||
* increments one to many and we wish to ignore the
|
||||
* root node
|
||||
*/
|
||||
for(i = depth - 2; i >= 0; i--){
|
||||
strcat(pPtr,"/");
|
||||
strcat(pPtr,nodeStack[i]->name);
|
||||
}
|
||||
return pPtr;
|
||||
}
|
||||
/*==================== Callback Functions ==================================*/
|
||||
pHdbCallback MakeHipadabaCallback(hdbCallbackFunction func,
|
||||
void *userData, killUserData killFunc,
|
||||
int id, int internalID){
|
||||
pHdbCallback pNew = NULL;
|
||||
|
||||
assert(func != NULL);
|
||||
|
||||
pNew = malloc(sizeof(hdbCallback));
|
||||
if(pNew == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memset(pNew,0,sizeof(hdbCallback));
|
||||
|
||||
pNew->userCallback = func;
|
||||
pNew->userData = userData;
|
||||
pNew->killFunc = killFunc;
|
||||
pNew->id = id;
|
||||
pNew->internalID = internalID;
|
||||
return pNew;
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
void AppendHipadabaCallback(pHdb node, int type, pHdbCallback newCB){
|
||||
pHdbCallback current = NULL;
|
||||
|
||||
switch(type){
|
||||
case HCBSET:
|
||||
if(node->writeCallbacks == NULL){
|
||||
node->writeCallbacks = newCB;
|
||||
return;
|
||||
} else {
|
||||
current = node->writeCallbacks;
|
||||
}
|
||||
break;
|
||||
case HCBUPDATE:
|
||||
if(node->updateCallbacks == NULL){
|
||||
node->updateCallbacks = newCB;
|
||||
return;
|
||||
} else {
|
||||
current = node->updateCallbacks;
|
||||
}
|
||||
break;
|
||||
case HCBREAD:
|
||||
if(node->readCallbacks == NULL){
|
||||
node->readCallbacks = newCB;
|
||||
return;
|
||||
} else {
|
||||
current = node->readCallbacks;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
if(current != NULL){
|
||||
while(current->next != NULL){
|
||||
current = (pHdbCallback)current->next;
|
||||
}
|
||||
current->next= newCB;
|
||||
newCB->previous = current;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void PrependHipadabaCallback(pHdb node, int type, pHdbCallback newCB){
|
||||
switch(type){
|
||||
case HCBSET:
|
||||
if(node->writeCallbacks == NULL){
|
||||
node->writeCallbacks = newCB;
|
||||
return;
|
||||
} else {
|
||||
newCB->next = node->writeCallbacks;
|
||||
node->writeCallbacks->previous = newCB;
|
||||
node->writeCallbacks = newCB;
|
||||
}
|
||||
break;
|
||||
case HCBUPDATE:
|
||||
if(node->updateCallbacks == NULL){
|
||||
node->updateCallbacks = newCB;
|
||||
return;
|
||||
} else {
|
||||
newCB->next = node->updateCallbacks;
|
||||
node->updateCallbacks->previous = newCB;
|
||||
node->updateCallbacks = newCB;
|
||||
}
|
||||
break;
|
||||
case HCBREAD:
|
||||
if(node->readCallbacks == NULL){
|
||||
node->readCallbacks = newCB;
|
||||
return;
|
||||
} else {
|
||||
newCB->next = node->readCallbacks;
|
||||
node->readCallbacks->previous = newCB;
|
||||
node->readCallbacks = newCB;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void RemoveHipadabaCallback(pHdb root, int id){
|
||||
pHdb current = NULL;
|
||||
|
||||
root->writeCallbacks = DeleteForID(root->writeCallbacks,id);
|
||||
root->updateCallbacks = DeleteForID(root->updateCallbacks,id);
|
||||
root->readCallbacks = DeleteForID(root->readCallbacks,id);
|
||||
|
||||
current = root->child;
|
||||
while(current != NULL){
|
||||
RemoveHipadabaCallback(current,id);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void InternalRemoveHipadabaCallback(pHdb root, int internalID){
|
||||
pHdb current = NULL;
|
||||
|
||||
root->writeCallbacks = DeleteForInternalID(root->writeCallbacks,internalID);
|
||||
root->updateCallbacks = DeleteForInternalID(root->updateCallbacks,internalID);
|
||||
root->readCallbacks = DeleteForInternalID(root->readCallbacks,internalID);
|
||||
|
||||
current = root->child;
|
||||
while(current != NULL){
|
||||
InternalRemoveHipadabaCallback(current,internalID);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
/*=================== parameter interface ====================================*/
|
||||
int copyHdbValue(hdbValue *source, hdbValue *target){
|
||||
int i;
|
||||
|
||||
if(source->dataType != target->dataType){
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(source->dataType){
|
||||
case HIPNONE:
|
||||
break;
|
||||
case HIPINT:
|
||||
target->v.intValue = source->v.intValue;
|
||||
break;
|
||||
case HIPFLOAT:
|
||||
target->v.doubleValue = source->v.doubleValue;
|
||||
break;
|
||||
case HIPTEXT:
|
||||
if(target->v.text != NULL){
|
||||
free(target->v.text);
|
||||
}
|
||||
target->v.text = strdup(source->v.text);
|
||||
break;
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
if(target->arrayLength != source->arrayLength){
|
||||
if(target->v.intArray != NULL){
|
||||
free(target->v.intArray);
|
||||
}
|
||||
target->v.intArray = malloc(source->arrayLength * sizeof(long));
|
||||
if(target->v.intArray == NULL){
|
||||
return 0;
|
||||
}
|
||||
memset(target->v.intArray,0,source->arrayLength * sizeof(long));
|
||||
target->arrayLength = source->arrayLength;
|
||||
}
|
||||
for(i = 0; i < source->arrayLength; i++){
|
||||
target->v.intArray[i] = source->v.intArray[i];
|
||||
}
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
case HIPFLOATVARAR:
|
||||
if(target->arrayLength != source->arrayLength){
|
||||
if(target->v.floatArray != NULL){
|
||||
free(target->v.floatArray);
|
||||
}
|
||||
target->v.floatArray = malloc(source->arrayLength * sizeof(double));
|
||||
if(target->v.floatArray == NULL){
|
||||
return 0;
|
||||
}
|
||||
memset(target->v.floatArray,0,source->arrayLength * sizeof(double));
|
||||
target->arrayLength = source->arrayLength;
|
||||
}
|
||||
for(i = 0; i < source->arrayLength; i++){
|
||||
target->v.floatArray[i] = source->v.floatArray[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* unknown data type
|
||||
*/
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int SetHipadabaPar(pHdb node, hdbValue v, void *callData){
|
||||
int status;
|
||||
|
||||
status = InvokeCallbackChain(node->writeCallbacks, node, callData, v);
|
||||
return status;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData){
|
||||
int status;
|
||||
|
||||
status = InvokeCallbackChain(node->updateCallbacks, node, callData, v);
|
||||
if(status != 1 ){
|
||||
return status;
|
||||
}
|
||||
copyHdbValue(&v,&node->value);
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
int GetHipadabaPar(pHdb node, hdbValue *v, void *callData){
|
||||
int status;
|
||||
|
||||
status = InvokeCallbackChain(node->readCallbacks, node, callData, *v);
|
||||
if(status != 1 ){
|
||||
return status;
|
||||
}
|
||||
v->dataType = node->value.dataType;
|
||||
copyHdbValue(&node->value,v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user