- Refactored hdb callbacks

SKIPPED:
	psi/julcho.c
This commit is contained in:
koennecke
2008-03-10 11:06:07 +00:00
parent 6b10e0a4e9
commit f512f47b02
14 changed files with 1440 additions and 829 deletions

View File

@@ -14,6 +14,47 @@
#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"};
/*------------------------------------------------------------------------*/
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;
}
/*================== internal functions ===================================*/
void DeleteCallbackChain(pHdbCallback root){
pHdbCallback current = NULL, thisEntry;
@@ -28,6 +69,17 @@ 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;
}
}
/*-----------------------------------------------------------------------*/
void DeleteNodeData(pHdb node){
pHdb tmp = NULL;
@@ -35,10 +87,7 @@ void DeleteNodeData(pHdb node){
if(node == NULL){
return;
}
DeleteCallbackChain(node->writeCallbacks);
DeleteCallbackChain(node->updateCallbacks);
DeleteCallbackChain(node->readCallbacks);
DeleteCallbackChain(node->treeChangeCallbacks);
DeleteCallbackChain(node->callBackChain);
if(node->properties != NULL){
DeleteStringDict(node->properties);
}
@@ -56,26 +105,83 @@ void DeleteNodeData(pHdb node){
}
free(node);
}
/*------------------------------------------------------------------------*/
static pHdbCallback CleanCallbackChain(pHdbCallback chain){
pHdbCallback head = chain;
pHdbCallback current = chain;
pHdbCallback next;
while(current != NULL){
if(current->killFlag == 1){
next = current->next;
if(current == head){
head = next;
}
/*
* unlink
*/
if(next != NULL){
next->previous = current->previous;
}
if(current->previous != NULL){
current->previous->next = next;
}
/*
* delete
*/
if(current->killFunc != NULL){
current->killFunc(current->userData);
}
free(current);
/*
* move on
*/
current = next;
} else {
current = current->next;
}
}
return head;
}
/*-------------------------------------------------------------------------*/
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){
@@ -88,8 +194,7 @@ void RemoveHdbNodeFromParent(pHdb node, void *callData){
}
current->next = current->next->next;
}
InvokeCallbackChain(parent->treeChangeCallbacks,
parent,callData,parent->value);
SendTreeChangeMessage(parent,callData);
node->mama = NULL;
}
}
@@ -117,97 +222,6 @@ static void RemoveCallbackNode(pHdbCallback victim){
}
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, void *id){
pHdbCallback current = root;
pHdbCallback tmp = NULL;
pHdbCallback result = NULL;
if(root == NULL || id == 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;
}
/*----------------------------------------------------------------------*/
char *hdbTrim(char *str)
{
@@ -620,8 +634,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){
@@ -730,8 +743,7 @@ char *GetHipadabaPath(pHdb node){
}
/*==================== Callback Functions ==================================*/
pHdbCallback MakeHipadabaCallback(hdbCallbackFunction func,
void *userData, killUserData killFunc,
int id, void *internalID){
void *userData, killUserData killFunc){
pHdbCallback pNew = NULL;
assert(func != NULL);
@@ -745,51 +757,17 @@ 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;
assert(node);
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;
current = node->callBackChain;
if(current == NULL){
node->callBackChain = newCB;
return;
}
if(current != NULL){
while(current->next != NULL){
@@ -800,101 +778,28 @@ void AppendHipadabaCallback(pHdb node, int type, pHdbCallback 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;
if(node->callBackChain != NULL){
node->callBackChain->previous = newCB;
}
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, void *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, int type, hdbCallbackFunction func
, void *internalID) {
pHdbCallback cb;
void *FindHdbCallbackData(pHdb node, hdbCallbackFunction func,
void *userPtr){
hdbDataSearch dsm;
switch (type) {
case HCBSET: cb = node->writeCallbacks; break;
case HCBUPDATE: cb = node->updateCallbacks; break;
case HCBREAD: cb = node->readCallbacks; break;
case HCBTREE: cb = node->treeChangeCallbacks; break;
}
while (cb != NULL) {
if (cb->internalID == internalID && cb->userCallback == func) {
return cb->userData;
}
cb = cb->next;
}
return NULL;
dsm.type = dataSearch;
dsm.testFunc = func;
dsm.testPtr = userPtr;
dsm.result = NULL;
InvokeCallbackChain(node, (pHdbMessage)&dsm);
return dsm.result;
}
/*=================== parameter interface ====================================*/
static int canCopy(hdbValue *source, hdbValue *target){
@@ -990,32 +895,39 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
}
return 1;
}
/*---------------------------------------------------------------------------*/
static int SendDataMessage(pHdb node, char *type,
hdbValue v, void *callData){
hdbDataMessage dataMes;
if(strstr(type,"set") != NULL){
dataMes.type = set;
} else if(strstr(type,"get") != NULL){
dataMes.type = get;
} else if(strstr(type,"update") != NULL){
dataMes.type = update;
}
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);
return 1;
int status;
status = SendDataMessage(node, update, v,callData);
if(status == 1){
copyHdbValue(&v,&node->value);
}
return status;
}
/*-----------------------------------------------------------------------------*/
int NotifyHipadabaPar(pHdb node,void *callData){
int status;
status = InvokeCallbackChain(node->updateCallbacks, node, callData, node->value);
if(status != 1 ){
return status;
}
SendDataMessage(node, update, node->value,callData);
return 1;
}
/*-----------------------------------------------------------------------------*/
@@ -1024,7 +936,8 @@ int GetHipadabaPar(pHdb node, hdbValue *v, void *callData){
v->dataType = node->value.dataType;
v->v.text = NULL; /* this sets all pointers in the union to NULL */
status = InvokeCallbackChain(node->readCallbacks, node, callData, *v);
status = SendDataMessage(node, get, *v,callData);
if(status != 1 ){
return status;
}
@@ -1061,10 +974,8 @@ int SetHdbPar(pHdb node, int dataType, void *data, int length,
}
v = makeHdbData(dataType, length, data);
status = InvokeCallbackChain(node->writeCallbacks, node, callData, v);
if(status == 1) {
copyHdbValue(&v,&node->value);
}
status = SetHipadabaPar(node, v, callData);
ReleaseHdbValue(&v);
return status;
}
/*--------------------------------------------------------------------------*/
@@ -1085,11 +996,8 @@ int UpdateHdbPar(pHdb node, int dataType, void *data, int length,
}
v = makeHdbData(dataType,length,data);
status = InvokeCallbackChain(node->updateCallbacks, node, callData, v);
if(status == 1) {
copyHdbValue(&v,&node->value);
}
status = UpdateHipadabaPar(node,v,callData);
ReleaseHdbValue(&v);
return status;
}
/*-----------------------------------------------------------------------------*/
@@ -1106,7 +1014,7 @@ int GetHdbPar(pHdb node, int dataType, void *data, int length,
return HDBLENGTHMISMATCH;
}
status = InvokeCallbackChain(node->readCallbacks, node, callData, v);
status = GetHipadabaPar(node, &v, callData);
if(status != 1 ){
return status;
}