PSI UPDATE
r2720 | ffr | 2008-10-13 15:40:07 +1100 (Mon, 13 Oct 2008) | 2 lines
This commit is contained in:
716
hipadaba.c
716
hipadaba.c
@@ -14,11 +14,64 @@
|
||||
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
#define HDBMAGICK 77119900
|
||||
/*================== Message Stuff ========================================*/
|
||||
static char set[] = {"set"};
|
||||
static char get[] = {"get"};
|
||||
static char update[] = {"update"};
|
||||
static char treeChange[] = {"treeChange"};
|
||||
static char dataSearch[] = {"dataSearch"};
|
||||
static char killNode[] = {"killNode"};
|
||||
/*------------------------------------------------------------------------*/
|
||||
pHdbDataMessage GetHdbSetMessage(pHdbMessage toTest){
|
||||
if(toTest->type == set){
|
||||
return (pHdbDataMessage)toTest;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
pHdbDataMessage GetHdbGetMessage(pHdbMessage toTest){
|
||||
if(toTest->type == get){
|
||||
return (pHdbDataMessage)toTest;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
pHdbDataMessage GetHdbUpdateMessage(pHdbMessage toTest){
|
||||
if(toTest->type == update){
|
||||
return (pHdbDataMessage)toTest;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
pHdbTreeChangeMessage GetHdbTreeChangeMessage(pHdbMessage toTest){
|
||||
if(toTest->type == treeChange){
|
||||
return (pHdbTreeChangeMessage)toTest;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
pHdbDataSearch GetHdbDataSearchMessage(pHdbMessage toTest){
|
||||
if(toTest->type == dataSearch){
|
||||
return (pHdbDataSearch)toTest;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
pHdbMessage GetHdbKillNodeMessage(pHdbMessage toTest){
|
||||
if(toTest->type == killNode){
|
||||
return toTest;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*================== internal functions ===================================*/
|
||||
void DeleteCallbackChain(pHdbCallback root){
|
||||
void DeleteCallbackChain(pHdb node){
|
||||
pHdbCallback current = NULL, thisEntry;
|
||||
hdbMessage killNodeMsg;
|
||||
|
||||
current = root;
|
||||
killNodeMsg.type = killNode;
|
||||
InvokeCallbackChain(node, &killNodeMsg);
|
||||
|
||||
current = node->callBackChain;
|
||||
while(current != NULL){
|
||||
if(current->killFunc != NULL){
|
||||
current->killFunc(current->userData);
|
||||
@@ -28,17 +81,26 @@ void DeleteCallbackChain(pHdbCallback root){
|
||||
free(thisEntry);
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
void RecurseCallbackChains(pHdb node, pHdbMessage message){
|
||||
pHdb current = NULL;
|
||||
|
||||
InvokeCallbackChain(node,message);
|
||||
current = node->child;
|
||||
while(current != NULL){
|
||||
RecurseCallbackChains(current,message);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void DeleteNodeData(pHdb node){
|
||||
void DeleteNodeData(pHdb node){
|
||||
pHdb tmp = NULL;
|
||||
|
||||
if(node == NULL){
|
||||
return;
|
||||
}
|
||||
DeleteCallbackChain(node->writeCallbacks);
|
||||
DeleteCallbackChain(node->updateCallbacks);
|
||||
DeleteCallbackChain(node->readCallbacks);
|
||||
DeleteCallbackChain(node->treeChangeCallbacks);
|
||||
|
||||
DeleteCallbackChain(node);
|
||||
if(node->properties != NULL){
|
||||
DeleteStringDict(node->properties);
|
||||
}
|
||||
@@ -59,145 +121,102 @@ static void DeleteNodeData(pHdb node){
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static pHdbCallback CleanCallbackChain(pHdbCallback head){
|
||||
pHdbCallback current = head;
|
||||
pHdbCallback next;
|
||||
pHdbCallback *ptr2last = &head;
|
||||
|
||||
while(current != NULL){
|
||||
if(current->killFlag == 1){
|
||||
next = current->next;
|
||||
/*
|
||||
* unlink
|
||||
*/
|
||||
*ptr2last = next;
|
||||
/*
|
||||
* delete
|
||||
*/
|
||||
if(current->killFunc != NULL){
|
||||
current->killFunc(current->userData);
|
||||
}
|
||||
free(current);
|
||||
/*
|
||||
* move on
|
||||
*/
|
||||
current = next;
|
||||
} else {
|
||||
ptr2last = ¤t->next;
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int InvokeCallbackChain(pHdbCallback root, pHdb node,
|
||||
void *callData, hdbValue v){
|
||||
pHdbCallback current = root;
|
||||
int status;
|
||||
int InvokeCallbackChain(pHdb node, pHdbMessage message){
|
||||
pHdbCallback current = node->callBackChain;
|
||||
hdbCallbackReturn status;
|
||||
int killFlag = 0;
|
||||
|
||||
while(current != NULL){
|
||||
status = current->userCallback(current->userData,callData,
|
||||
node,v);
|
||||
if(status != 1){
|
||||
return status;
|
||||
status = current->userCallback(node, current->userData,message);
|
||||
switch(status){
|
||||
case hdbAbort:
|
||||
return 0;
|
||||
break;
|
||||
case hdbKill:
|
||||
current->killFlag = 1;
|
||||
killFlag = 1;
|
||||
break;
|
||||
case hdbContinue:
|
||||
break;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
if(killFlag == 1){
|
||||
node->callBackChain = CleanCallbackChain(node->callBackChain);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void SendTreeChangeMessage(pHdb node, void *callData){
|
||||
hdbTreeChangeMessage treeChangeMes;
|
||||
treeChangeMes.type = treeChange;
|
||||
treeChangeMes.callData = callData;
|
||||
InvokeCallbackChain(node, (pHdbMessage)&treeChangeMes);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
void RemoveHdbNodeFromParent(pHdb node, void *callData){
|
||||
pHdb parent = NULL;
|
||||
pHdb current = NULL;
|
||||
hdbTreeChangeMessage treeChangeMes;
|
||||
|
||||
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;
|
||||
InvokeCallbackChain(parent->treeChangeCallbacks,
|
||||
parent,callData,parent->value);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
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;
|
||||
} else {
|
||||
current = parent->child;
|
||||
while(current->next != node){
|
||||
current = current->next;
|
||||
}
|
||||
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;
|
||||
}
|
||||
current->next = current->next->next;
|
||||
}
|
||||
SendTreeChangeMessage(parent,callData);
|
||||
node->mama = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int CountHdbChildren(pHdb node){
|
||||
int count = 0;
|
||||
pHdb current = NULL;
|
||||
current = node->child;
|
||||
while(current != NULL){
|
||||
current = current->next;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
char *hdbTrim(char *str)
|
||||
@@ -274,6 +293,7 @@ hdbValue makeHdbValue(int datatype, int length){
|
||||
|
||||
memset(&val,0,sizeof(hdbValue));
|
||||
val.dataType = datatype;
|
||||
val.doNotFree = 0;
|
||||
|
||||
switch(datatype){
|
||||
case HIPINTAR:
|
||||
@@ -299,60 +319,6 @@ hdbValue makeHdbValue(int datatype, int length){
|
||||
}
|
||||
return val;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
hdbValue makeHdbData(int datatype, int length, void *data){
|
||||
hdbValue val;
|
||||
|
||||
memset(&val,0,sizeof(hdbValue));
|
||||
val.dataType = datatype;
|
||||
|
||||
switch(datatype){
|
||||
case HIPINT:
|
||||
if(data != NULL){
|
||||
memcpy(&val.v.intValue,data,sizeof(int));
|
||||
}
|
||||
break;
|
||||
case HIPFLOAT:
|
||||
if(data != NULL){
|
||||
memcpy(&val.v.doubleValue,data,sizeof(double));
|
||||
}
|
||||
break;
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
val.arrayLength = length;
|
||||
val.v.intArray = malloc(length*sizeof(int));
|
||||
if(val.v.intArray != NULL){
|
||||
memset(val.v.intArray,0,length*sizeof(int));
|
||||
}
|
||||
if(data != NULL){
|
||||
memcpy(val.v.intArray,data,length*sizeof(int));
|
||||
}
|
||||
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));
|
||||
}
|
||||
if(data != NULL){
|
||||
memcpy(val.v.floatArray,data,length*sizeof(double));
|
||||
}
|
||||
break;
|
||||
case HIPTEXT:
|
||||
if(data != NULL){
|
||||
val.v.text = strdup((char *)data);
|
||||
} else {
|
||||
val.v.text = strdup("UNKNOWN");
|
||||
}
|
||||
val.arrayLength = strlen(val.v.text);
|
||||
break;
|
||||
case HIPOBJ:
|
||||
val.v.obj = data;
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbInt(int initValue){
|
||||
hdbValue result;
|
||||
@@ -376,7 +342,7 @@ hdbValue MakeHdbText(char *initText){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPTEXT;
|
||||
result.v.text = initText;
|
||||
result.v.text = initText; /* no strdup here ! */
|
||||
result.arrayLength = strlen(initText);
|
||||
return result;
|
||||
}
|
||||
@@ -390,7 +356,7 @@ hdbValue MakeHdbIntArray(int length, int *data){
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbFloatArrray(int length, double *data){
|
||||
hdbValue MakeHdbFloatArray(int length, double *data){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPFLOATAR;
|
||||
@@ -399,7 +365,27 @@ hdbValue MakeHdbFloatArrray(int length, double *data){
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbFunc(voidFunc *func){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPFUNC;
|
||||
result.v.func = func;
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
hdbValue MakeHdbObj(void *obj){
|
||||
hdbValue result;
|
||||
|
||||
result.dataType = HIPOBJ;
|
||||
result.v.obj = obj;
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void ReleaseHdbValue(hdbValue *v){
|
||||
|
||||
if(v->doNotFree == 1){
|
||||
return;
|
||||
}
|
||||
switch(v->dataType){
|
||||
case HIPTEXT:
|
||||
if(v->v.text != NULL){
|
||||
@@ -447,6 +433,9 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
||||
}
|
||||
break;
|
||||
case HIPTEXT:
|
||||
if(v1.v.text == NULL || v2.v.text == NULL){
|
||||
return 0;
|
||||
}
|
||||
if(strcmp(v1.v.text,v2.v.text) == 0){
|
||||
return 1;
|
||||
} else {
|
||||
@@ -458,6 +447,9 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
||||
if(v1.arrayLength != v2.arrayLength){
|
||||
return 0;
|
||||
}
|
||||
if(v1.v.intArray == NULL || v2.v.intArray == NULL){
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < v1.arrayLength; i++){
|
||||
if(v1.v.intArray[i] != v2.v.intArray[i]){
|
||||
return 0;
|
||||
@@ -470,6 +462,9 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
||||
if(v1.arrayLength != v2.arrayLength){
|
||||
return 0;
|
||||
}
|
||||
if(v1.v.floatArray == NULL || v2.v.floatArray == NULL){
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < v1.arrayLength; i++){
|
||||
if(ABS(v1.v.floatArray[i] - v2.v.floatArray[i]) > .01){
|
||||
return 0;
|
||||
@@ -484,6 +479,13 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case HIPFUNC:
|
||||
if(v2.v.func == v1.v.func) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
@@ -494,6 +496,7 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
||||
int cloneHdbValue(hdbValue *source, hdbValue *clone){
|
||||
|
||||
memset(clone,0,sizeof(hdbValue));
|
||||
clone->v.text = NULL; /* this sets all pointers in the union to NULL */
|
||||
clone->dataType = source->dataType;
|
||||
return copyHdbValue(source, clone);
|
||||
}
|
||||
@@ -523,6 +526,9 @@ int getHdbValueLength(hdbValue v){
|
||||
case HIPOBJ:
|
||||
length = sizeof(void *);
|
||||
break;
|
||||
case HIPFUNC:
|
||||
length = sizeof(voidFunc *);
|
||||
break;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
@@ -594,8 +600,7 @@ void AddHipadabaChild(pHdb parent, pHdb child, void *callData){
|
||||
child->next = NULL;
|
||||
prev->next = child;
|
||||
}
|
||||
InvokeCallbackChain(parent->treeChangeCallbacks,
|
||||
parent,callData,parent->value);
|
||||
SendTreeChangeMessage(parent,callData);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void DeleteHipadabaNode(pHdb node, void *callData){
|
||||
@@ -705,8 +710,7 @@ char *GetHipadabaPath(pHdb node){
|
||||
}
|
||||
/*==================== Callback Functions ==================================*/
|
||||
pHdbCallback MakeHipadabaCallback(hdbCallbackFunction func,
|
||||
void *userData, killUserData killFunc,
|
||||
int id, int internalID){
|
||||
void *userData, killUserData killFunc){
|
||||
pHdbCallback pNew = NULL;
|
||||
|
||||
assert(func != NULL);
|
||||
@@ -720,142 +724,68 @@ pHdbCallback MakeHipadabaCallback(hdbCallbackFunction func,
|
||||
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){
|
||||
void AppendHipadabaCallback(pHdb node, 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;
|
||||
case HCBTREE:
|
||||
if(node->treeChangeCallbacks == NULL){
|
||||
node->treeChangeCallbacks = newCB;
|
||||
return;
|
||||
} else {
|
||||
current = node->treeChangeCallbacks;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
assert(node);
|
||||
current = node->callBackChain;
|
||||
newCB->next = NULL;
|
||||
if(current == NULL){
|
||||
node->callBackChain = newCB;
|
||||
return;
|
||||
}
|
||||
if(current != NULL){
|
||||
while(current->next != NULL){
|
||||
current = (pHdbCallback)current->next;
|
||||
}
|
||||
current->next= newCB;
|
||||
newCB->previous = current;
|
||||
while(current->next != NULL){
|
||||
current = (pHdbCallback)current->next;
|
||||
}
|
||||
current->next = newCB;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
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;
|
||||
case HCBTREE:
|
||||
if(node->treeChangeCallbacks == NULL){
|
||||
node->treeChangeCallbacks = newCB;
|
||||
return;
|
||||
} else {
|
||||
newCB->next = node->treeChangeCallbacks;
|
||||
node->treeChangeCallbacks->previous = newCB;
|
||||
node->treeChangeCallbacks = newCB;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
void PrependHipadabaCallback(pHdb node,pHdbCallback newCB){
|
||||
assert(node != NULL);
|
||||
|
||||
newCB->next = node->callBackChain;
|
||||
node->callBackChain = newCB;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
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);
|
||||
root->treeChangeCallbacks = DeleteForID(root->treeChangeCallbacks,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);
|
||||
root->treeChangeCallbacks = DeleteForInternalID(root->treeChangeCallbacks,internalID);
|
||||
|
||||
current = root->child;
|
||||
while(current != NULL){
|
||||
InternalRemoveHipadabaCallback(current,internalID);
|
||||
current = current->next;
|
||||
}
|
||||
void *FindHdbCallbackData(pHdb node, void *userPtr){
|
||||
hdbDataSearch dsm;
|
||||
|
||||
dsm.type = dataSearch;
|
||||
dsm.testPtr = userPtr;
|
||||
dsm.result = NULL;
|
||||
|
||||
InvokeCallbackChain(node, (pHdbMessage)&dsm);
|
||||
return dsm.result;
|
||||
|
||||
}
|
||||
/*=================== parameter interface ====================================*/
|
||||
static int canCopy(hdbValue *source, hdbValue *target){
|
||||
if(target->dataType == HIPINTVARAR) {
|
||||
if(source->dataType == HIPINTAR ||
|
||||
source->dataType == HIPINTVARAR){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(target->dataType == HIPFLOATVARAR) {
|
||||
if(source->dataType == HIPFLOATAR ||
|
||||
source->dataType == HIPFLOATVARAR){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(source->dataType != target->dataType){
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int copyHdbValue(hdbValue *source, hdbValue *target){
|
||||
int i;
|
||||
|
||||
if(source->dataType != target->dataType){
|
||||
if(!canCopy(source,target)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -884,7 +814,8 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
|
||||
if(target->v.intArray == NULL){
|
||||
return 0;
|
||||
}
|
||||
memset(target->v.intArray,0,source->arrayLength * sizeof(int));
|
||||
memset(target->v.intArray,0,source->arrayLength
|
||||
* sizeof(int));
|
||||
target->arrayLength = source->arrayLength;
|
||||
}
|
||||
if(source->v.intArray != NULL){
|
||||
@@ -895,15 +826,18 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
case HIPFLOATVARAR:
|
||||
if(target->arrayLength != source->arrayLength || target->v.floatArray == NULL){
|
||||
if(target->arrayLength != source->arrayLength
|
||||
|| target->v.floatArray == NULL){
|
||||
if(target->v.floatArray != NULL){
|
||||
free(target->v.floatArray);
|
||||
}
|
||||
target->v.floatArray = malloc(source->arrayLength * sizeof(double));
|
||||
target->v.floatArray =
|
||||
malloc(source->arrayLength * sizeof(double));
|
||||
if(target->v.floatArray == NULL){
|
||||
return 0;
|
||||
}
|
||||
memset(target->v.floatArray,0,source->arrayLength * sizeof(double));
|
||||
memset(target->v.floatArray,0,source->arrayLength *
|
||||
sizeof(double));
|
||||
target->arrayLength = source->arrayLength;
|
||||
}
|
||||
if(source->v.floatArray != NULL){
|
||||
@@ -915,6 +849,9 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
|
||||
case HIPOBJ:
|
||||
target->v.obj = source->v.obj;
|
||||
break;
|
||||
case HIPFUNC:
|
||||
target->v.func = source->v.func;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* unknown data type
|
||||
@@ -924,33 +861,48 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int SendDataMessage(pHdb node, char *type,
|
||||
hdbValue v, void *callData){
|
||||
hdbDataMessage dataMes;
|
||||
|
||||
assert(type == set || type == get || type == update);
|
||||
dataMes.type = type;
|
||||
dataMes.v = &v;
|
||||
dataMes.callData = callData;
|
||||
return InvokeCallbackChain(node, (pHdbMessage)&dataMes);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int SetHipadabaPar(pHdb node, hdbValue v, void *callData){
|
||||
int status;
|
||||
|
||||
status = InvokeCallbackChain(node->writeCallbacks, node, callData, v);
|
||||
return status;
|
||||
return SendDataMessage(node, set, v,callData);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
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);
|
||||
int status;
|
||||
|
||||
status = SendDataMessage(node, update, v,callData);
|
||||
if(status == 1){
|
||||
copyHdbValue(&v,&node->value);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
int NotifyHipadabaPar(pHdb node,void *callData){
|
||||
SendDataMessage(node, update, node->value,callData);
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
int GetHipadabaPar(pHdb node, hdbValue *v, void *callData){
|
||||
int status;
|
||||
|
||||
status = InvokeCallbackChain(node->readCallbacks, node, callData, *v);
|
||||
v->dataType = node->value.dataType;
|
||||
v->doNotFree = 0;
|
||||
v->v.text = NULL; /* this sets all pointers in the union to NULL */
|
||||
|
||||
status = SendDataMessage(node, get, *v,callData);
|
||||
if(status != 1 ){
|
||||
return status;
|
||||
}
|
||||
v->dataType = node->value.dataType;
|
||||
copyHdbValue(&node->value,v);
|
||||
return 1;
|
||||
}
|
||||
@@ -966,112 +918,12 @@ static int calcDataLength(pHdb node, int testLength){
|
||||
}
|
||||
return length;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int SetHdbPar(pHdb node, int dataType, void *data, int length,
|
||||
void *callData){
|
||||
int status;
|
||||
hdbValue v;
|
||||
|
||||
if(node->value.dataType == HIPNONE){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(dataType != node->value.dataType){
|
||||
return HDBTYPEMISMATCH;
|
||||
}
|
||||
if(length != calcDataLength(node,length)){
|
||||
return HDBLENGTHMISMATCH;
|
||||
}
|
||||
|
||||
v = makeHdbData(dataType, length, data);
|
||||
status = InvokeCallbackChain(node->writeCallbacks, node, callData, v);
|
||||
if(status == 1) {
|
||||
copyHdbValue(&v,&node->value);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int UpdateHdbPar(pHdb node, int dataType, void *data, int length,
|
||||
void *callData){
|
||||
int status;
|
||||
hdbValue v;
|
||||
|
||||
if(node->value.dataType == HIPNONE){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(dataType != node->value.dataType){
|
||||
return HDBTYPEMISMATCH;
|
||||
}
|
||||
if(length != calcDataLength(node,length)){
|
||||
return HDBLENGTHMISMATCH;
|
||||
}
|
||||
|
||||
v = makeHdbData(dataType,length,data);
|
||||
|
||||
status = InvokeCallbackChain(node->updateCallbacks, node, callData, v);
|
||||
if(status == 1) {
|
||||
copyHdbValue(&v,&node->value);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
int GetHdbPar(pHdb node, int dataType, void *data, int length,
|
||||
void *callData){
|
||||
int status, toCopy;
|
||||
hdbValue v;
|
||||
|
||||
if(dataType != node->value.dataType){
|
||||
return HDBTYPEMISMATCH;
|
||||
}
|
||||
|
||||
if(length != calcDataLength(node,length)){
|
||||
return HDBLENGTHMISMATCH;
|
||||
}
|
||||
|
||||
status = InvokeCallbackChain(node->readCallbacks, node, callData, v);
|
||||
if(status != 1 ){
|
||||
return status;
|
||||
}
|
||||
switch(dataType){
|
||||
case HIPNONE:
|
||||
break;
|
||||
case HIPINT:
|
||||
memcpy(data,&node->value.v.intValue,sizeof(int));
|
||||
break;
|
||||
case HIPFLOAT:
|
||||
memcpy(data,&node->value.v.doubleValue,sizeof(double));
|
||||
break;
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
memcpy(data,node->value.v.intArray,
|
||||
node->value.arrayLength*sizeof(int));
|
||||
break;
|
||||
case HIPTEXT:
|
||||
toCopy = strlen(node->value.v.text);
|
||||
if(toCopy > length){
|
||||
toCopy = length;
|
||||
}
|
||||
memcpy(data,&node->value.v.text, toCopy);
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
case HIPFLOATVARAR:
|
||||
memcpy(data,node->value.v.floatArray,
|
||||
node->value.arrayLength*sizeof(double));
|
||||
break;
|
||||
case HIPOBJ:
|
||||
memcpy(data,&node->value.v.obj,sizeof(void *));
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*============================= Property Functions ==========================*/
|
||||
void SetHdbProperty(pHdb node, char *key, char *value){
|
||||
if(node != NULL && key != NULL && node->properties != NULL){
|
||||
if(StringDictExists(node->properties, key)){
|
||||
if (value == NULL) {
|
||||
StringDictDelete(node->properties, key);
|
||||
} else if(StringDictExists(node->properties, key)){
|
||||
StringDictUpdate(node->properties,key,value);
|
||||
} else {
|
||||
StringDictAddPair(node->properties,key,value);
|
||||
@@ -1087,6 +939,14 @@ int GetHdbProperty(pHdb node, char *key, char *value, int len){
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
char *GetHdbProp(pHdb node, char *key){
|
||||
if(node != NULL && node->properties != NULL){
|
||||
return StringDictGetShort(node->properties,key);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void InitHdbPropertySearch(pHdb node){
|
||||
if(node != NULL && node->properties != NULL){
|
||||
StringDictKillScan(node->properties);
|
||||
|
||||
Reference in New Issue
Block a user