- First implementation of Hdbqueue

- First implementation of new object model for SICS
This commit is contained in:
koennecke
2007-08-03 15:12:10 +00:00
parent 3170314457
commit 31a48d2155
21 changed files with 1035 additions and 101 deletions

View File

@ -68,7 +68,7 @@
#include "commandlog.h" #include "commandlog.h"
#include "stptok.h" #include "stptok.h"
#include "sicshipadaba.h" #include "sicshipadaba.h"
#include "protocol.h"
/* /*
#define UUDEB 1 #define UUDEB 1
define UUDEB , for buffer writing for checking encoding */ define UUDEB , for buffer writing for checking encoding */
@ -79,7 +79,7 @@ extern pServer pServ;
/*------ Max Size of Command Stack */ /*------ Max Size of Command Stack */
#define MAXSTACK 100 #define MAXSTACK 1024
/*---------- Magic ID Header */ /*---------- Magic ID Header */
#define CONMAGIC 26051958 #define CONMAGIC 26051958
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1149,8 +1149,9 @@ pDynString SCEndBuffering(SConnection *pCon)
int SCWriteZipped(SConnection *self, char *pName, void *pData, int iDataLen) int SCWriteZipped(SConnection *self, char *pName, void *pData, int iDataLen)
{ {
char outBuf[65546], *pBuf = NULL, noutBuf[ZIPBUF], *pHeader = NULL; char outBuf[65546], *pBuf = NULL, noutBuf[ZIPBUF], *pHeader = NULL;
int compressedLength, iRet, iRet2, iCount; int compressedLength, iRet, iRet2, iCount, protocolID;
z_stream compStream; z_stream compStream;
commandContext cc;
/* check for a valid connection */ /* check for a valid connection */
if(!VerifyConnection(self)) if(!VerifyConnection(self))
@ -1225,7 +1226,15 @@ pDynString SCEndBuffering(SConnection *pCon)
/* write header line */ /* write header line */
memset(outBuf,0,65536); memset(outBuf,0,65536);
sprintf(outBuf,"SICSBIN ZIP %s %d\r\n",pName,compressedLength);
protocolID = GetProtocolID(self);
if(protocolID == 5){
cc = SCGetContext(self);
sprintf(outBuf,"SICSBIN ZIP %s %d %d\r\n",pName,
compressedLength, cc.transID);
} else {
sprintf(outBuf,"SICSBIN ZIP %s %d \r\n",pName,compressedLength);
}
pHeader = strdup(outBuf); pHeader = strdup(outBuf);
if(pHeader == NULL) if(pHeader == NULL)
{ {

5
danu.c
View File

@ -363,8 +363,9 @@ int NewThousand(pDataNumber self)
if(SCMatchRights(pCon,usMugger)) if(SCMatchRights(pCon,usMugger))
{ {
DecrementDataNumber(self); iNum = DecrementDataNumber(self);
SCWrite(pCon,"Data file killed",eWarning); snprintf(pBueffel,511,"Data file %d killed", iNum);
SCWrite(pCon,pBueffel,eWarning);
return 1; return 1;
} }
else else

3
exe.w
View File

@ -174,6 +174,9 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics, int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics,
char *name); char *name);
pDynString findBatchFile(SicsInterp *pSics, char *name); pDynString findBatchFile(SicsInterp *pSics, char *name);
int exeHdbBuffer(SConnection *pCon,
SicsInterp *pSics, char *name);
int exeHdbNode(pHdb exeNode, SConnection *pCon);
@} @}
@o exeman.i -d @{ @o exeman.i -d @{

View File

@ -166,13 +166,17 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
self->lineno = 0; self->lineno = 0;
pTcl = InterpGetTcl(pSics); pTcl = InterpGetTcl(pSics);
InvokeCallBack(pCall,BATCHSTART,self->name); if(pCall != NULL){
InvokeCallBack(pCall,BATCHSTART,self->name);
}
if (echo) { if (echo) {
SCsetMacro(pCon,0); SCsetMacro(pCon,0);
} }
while((command = findBlockEnd(self)) != NULL){ while((command = findBlockEnd(self)) != NULL){
InvokeCallBack(pCall,BATCHAREA,NULL); if(pCall != NULL){
InvokeCallBack(pCall,BATCHAREA,NULL);
}
cmd = GetCharArray(command); cmd = GetCharArray(command);
if (echo) { if (echo) {
@ -223,7 +227,9 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
SCSetInterrupt(pCon,eContinue); SCSetInterrupt(pCon,eContinue);
} }
} }
InvokeCallBack(pCall,BATCHEND,self->name); if(pCall != NULL){
InvokeCallBack(pCall,BATCHEND,self->name);
}
return 1; return 1;
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/

View File

@ -1,5 +1,5 @@
#line 210 "exe.w" #line 213 "exe.w"
/** /**
* Buffer handling code for the Exe Buffer batch file processing * Buffer handling code for the Exe Buffer batch file processing
@ -89,7 +89,7 @@
*/ */
char *exeBufName(pExeBuf self); char *exeBufName(pExeBuf self);
#line 223 "exe.w" #line 226 "exe.w"
#endif #endif

View File

@ -1,5 +1,5 @@
#line 201 "exe.w" #line 204 "exe.w"
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
Internal header file for the exe buffer module. Do not edit. This is Internal header file for the exe buffer module. Do not edit. This is
@ -16,6 +16,6 @@ typedef struct __EXEBUF{
int lineno; int lineno;
} ExeBuf; } ExeBuf;
#line 206 "exe.w" #line 209 "exe.w"

View File

@ -297,12 +297,12 @@ static int SCHdbWrite(SConnection *self, char *message, int outCode){
} }
if(v.v.text != NULL){ if(v.v.text != NULL){
DynStringConcat(val,v.v.text); DynStringConcat(val,v.v.text);
if(strrchr(v.v.text,(int)'\n') == NULL && strlen(v.v.text) > 2){ if(strrchr(v.v.text,(int)'\n') == NULL && strlen(v.v.text) > 1){
DynStringConcatChar(val,'\n'); DynStringConcatChar(val,'\n');
} }
} }
DynStringConcat(val,message); DynStringConcat(val,message);
if(strrchr(message,(int)'\n') == NULL && strlen(message) > 2){ if(strrchr(message,(int)'\n') == NULL && strlen(message) > 1){
DynStringConcatChar(val,'\n'); DynStringConcatChar(val,'\n');
} }
if(v.v.text != NULL){ if(v.v.text != NULL){
@ -314,6 +314,66 @@ static int SCHdbWrite(SConnection *self, char *message, int outCode){
return 1; return 1;
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
int exeHdbNode(pHdb exeNode, SConnection *pCon){
char pBueffel[512], *name = NULL;
pHdb node = NULL;
pExeBuf buffer = NULL;
hdbValue v;
int status;
commandContext cc;
writeFunc oldWrite;
/*
* clear log buffer
*/
node = GetHipadabaNode(exeNode,"log");
if(node == NULL){
SCWrite(pCon,"ERROR: Hdb node not found or in wrong format",eError);
return 0;
}
v = MakeHdbText(strdup(""));
UpdateHipadabaPar(node,v,pCon);
/*
* prepare context
*/
name = GetHipadabaPath(node);
cc = SCGetContext(pCon);
strncpy(cc.deviceID, name,255);
strncpy(bufferNode,name,511);
/*
* load commands into buffer
*/
node = GetHipadabaNode(exeNode,"commands");
if(node == NULL){
SCWrite(pCon,"ERROR: Hdb node not found or in wrong format",eError);
return 0;
}
GetHipadabaPar(node,&v,pCon);
if(v.dataType != HIPTEXT || v.v.text == NULL){
SCWrite(pCon,"ERROR: Hdb node is of wrong type or contains no data",eError);
return 0;
}
buffer = exeBufCreate(name);
if(!buffer){
SCWrite(pCon,"ERROR: out of memory creating batch buffer",eError);
return 0;
}
exeBufAppend(buffer,v.v.text);
strncpy(bufferNode,name,511);
oldWrite = SCGetWriteFunc(pCon);
SCSetWriteFunc(pCon,SCHdbWrite);
SCPushContext2(pCon,cc);
status = exeBufProcess(buffer,pServ->pSics,pCon,NULL,0);
SCSetWriteFunc(pCon,oldWrite);
SCPopContext(pCon);
return status;
}
/*--------------------------------------------------------------------*/
static int runHdbBuffer(pExeMan self, SConnection *pCon, static int runHdbBuffer(pExeMan self, SConnection *pCon,
SicsInterp *pSics, char *name){ SicsInterp *pSics, char *name){
char pBueffel[512]; char pBueffel[512];
@ -381,6 +441,15 @@ static int runHdbBuffer(pExeMan self, SConnection *pCon,
SCPopContext(pCon); SCPopContext(pCon);
return status; return status;
} }
/*--------------------------------------------------------------------*/
int exeHdbBuffer(SConnection *pCon,
SicsInterp *pSics, char *name){
pExeMan self = (pExeMan)FindCommandData(pSics,"exe","ExeManager");
if(self != NULL){
return runHdbBuffer(self,pCon,pSics,name);
}
return 0;
}
/*-------------------------------------------------------------------*/ /*-------------------------------------------------------------------*/
int runExeBatchBuffer(void *pData, SConnection *pCon, int runExeBatchBuffer(void *pData, SConnection *pCon,
SicsInterp *pSics, char *name){ SicsInterp *pSics, char *name){

View File

@ -16,5 +16,8 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics, int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics,
char *name); char *name);
pDynString findBatchFile(SicsInterp *pSics, char *name); pDynString findBatchFile(SicsInterp *pSics, char *name);
int exeHdbBuffer(SConnection *pCon,
SicsInterp *pSics, char *name);
int exeHdbNode(pHdb exeNode, SConnection *pCon);
#endif #endif

View File

@ -1,5 +1,5 @@
#line 179 "exe.w" #line 182 "exe.w"
/*------------------------------------------------------------------- /*-------------------------------------------------------------------
Internal header file for the exe manager module. Do not edit. This Internal header file for the exe manager module. Do not edit. This
@ -20,5 +20,5 @@ typedef struct __EXEMAN{
int echo; int echo;
}ExeMan, *pExeMan; }ExeMan, *pExeMan;
#line 184 "exe.w" #line 187 "exe.w"

View File

@ -647,22 +647,12 @@ static int putElastic(SicsInterp *pSics, SConnection *pCon,
} }
status = CalculateFitFromData(fitter,(float *)fTimeBin,lSum,iTime); status = CalculateFitFromData(fitter,(float *)fTimeBin,lSum,iTime);
free(lSum); free(lSum);
if(status != 1)
{
SCWrite(pCon,"WARNING: problem locating elastic peak",eWarning);
}
GetFitResults(fitter,&fCenter,&fStdDev,&fFWHM,&fVal); GetFitResults(fitter,&fCenter,&fStdDev,&fFWHM,&fVal);
fVal = fCenter - fElastic; fVal = fCenter - fElastic;
if(fVal < 0.) if(fVal < 0.)
fVal = - fVal; fVal = - fVal;
/* bad value, leave at theoretical value */ /* bad value, leave at theoretical value */
if(fVal > 10.) if(fVal < 10.)
{
SCWrite(pCon,
"WARNING: bad fit result, using theoretical elastic peak position",
eWarning);
}
else
{ {
fElastic = fCenter; fElastic = fCenter;
} }

412
hdbqueue.c Normal file
View File

@ -0,0 +1,412 @@
/**
* This is the new Hipadaba based queuing system in support of the MountainGum
* user interface.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, July 2007
*/
#include <stdlib.h>
#include <assert.h>
#include <sics.h>
#include "sicsobj.h"
#include "hdbqueue.h"
#include "sicshipadaba.h"
#include "dynstring.h"
#include "exeman.h"
#include "macro.h"
/*--------------------------------------------------------------------------*/
typedef struct {
int iStop;
SConnection *pCon;
}HdbQueue, *pHdbQueue;
/*--------------------------------------------------------------------------*/
static pHdbCallback CopyCallbackChain(pHdbCallback source){
pHdbCallback current = NULL;
pHdbCallback result = NULL;
pHdbCallback head = NULL;
pHdbCallback tail = NULL;
current = source;
while(current != NULL){
result = MakeHipadabaCallback(current->userCallback,
current->userData,
NULL,
current->id,
current->internalID);
if(head == NULL){
head = result;
tail = result;
} else {
tail->next = result;
result->previous = tail;
tail = result;
}
current = current->next;
}
return head;
}
/*---------------------------------------------------------------------------*/
static pHdb MakeNewEntry(char *name, pHdbCallback update){
pHdb entry = NULL, child = NULL;
hdbValue v;
v = MakeHdbText("Undefined");
entry = MakeHipadabaNode(name,HIPNONE, 1);
entry->updateCallbacks = CopyCallbackChain(update);
child = MakeSICSHdbPar("description",usUser,v);
child->updateCallbacks = CopyCallbackChain(update);
AddHipadabaChild(entry,child,NULL);
child = MakeSICSHdbPar("commands",usUser,v);
child->updateCallbacks = CopyCallbackChain(update);
AddHipadabaChild(entry,child,NULL);
child = MakeSICSHdbPar("log",usUser,v);
child->updateCallbacks = CopyCallbackChain(update);
AddHipadabaChild(entry,child,NULL);
return entry;
}
/*---------------------------------------------------------------------------*/
static int EnqueFunc(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
pHdb entry = NULL;
pHdb work = NULL;
char name[80];
hdbValue v;
if(nPar < 1){
SCWrite(pCon,"ERROR: internal: not enough parameters to EnqueFunc",eError);
return 0;
}
/*
* new entry
*/
memset(&v,0,sizeof(hdbValue));
work = GetHipadabaNode(self->objectNode,"control/maxEntry");
assert(work != NULL);
snprintf(name,80,"%3.3d", work->value.v.intValue);
entry = MakeNewEntry(name, work->updateCallbacks);
if(entry == NULL){
SCWrite(pCon,"ERROR: out of memory in EnqueFunc",eError);
return 0;
}
/*
* Update maxEntry
*/
cloneHdbValue(&work->value,&v);
v.v.intValue++;
UpdateHipadabaPar(work,v,pCon);
work = GetHipadabaNode(self->objectNode,"queue");
assert(work != NULL);
AddHipadabaChild(work, entry, pCon);
/*
* save description
*/
work = GetHipadabaNode(entry,"description");
assert(work != NULL);
UpdateHipadabaPar(work,par[0]->value,pCon);
return 1;
}
/*---------------------------------------------------------------------------*/
static int AddCmdData(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
pHdb work = NULL;
pHdb commandNode = NULL;
char name[80];
pDynString txt = NULL;
if(nPar < 1){
SCWrite(pCon,"ERROR: internal: not enough parameters to AddCmdData",eError);
return 0;
}
work = GetHipadabaNode(self->objectNode,"control/maxEntry");
assert(work != NULL);
snprintf(name,80,"queue/%3.3d/commands", work->value.v.intValue-1);
commandNode = GetHipadabaNode(self->objectNode,name);
if(commandNode == NULL){
SCWrite(pCon,"ERROR: Internal error in AddCommand",eError);
return 0;
}
txt = CreateDynString(80,80);
if(strstr(commandNode->value.v.text,"Undefined") == NULL){
DynStringCopy(txt,commandNode->value.v.text);
}
DynStringConcat(txt,par[0]->value.v.text);
DynStringConcat(txt,"\n");
free(commandNode->value.v.text);
commandNode->value.v.text = strdup(GetCharArray(txt));
NotifyHipadabaPar(commandNode,pCon);
DeleteDynString(txt);
return 1;
}
/*--------------------------------------------------------------------------*/
static void sequentialNames(pHdb obj,SConnection *pCon){
pHdb work = NULL;
pHdb current = NULL;
int count = 0;
char name[80];
work = GetHipadabaNode(obj,"queue");
assert(work != NULL);
current = work->child;
while(current != NULL){
snprintf(name,80,"%3.3d",count);
if(current != NULL && current->name != NULL){
free(current->name);
}
current->name = strdup(name);
count++;
current = current->next;
}
InvokeCallbackChain(work->treeChangeCallbacks,work,pCon,work->value);
work = GetHipadabaNode(obj,"control/maxEntry");
assert(work != NULL);
work->value.v.intValue = count;
NotifyHipadabaPar(work,pCon);
}
/*---------------------------------------------------------------------------*/
static int Dequeue(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
pHdb work = NULL;
char name[80];
if(nPar < 1){
SCWrite(pCon,"ERROR: internal: not enough parameters to Dequeue",eError);
return 0;
}
snprintf(name,80,"queue/%3.3d", par[0]->value.v.intValue);
work = GetHipadabaNode(self->objectNode,name);
if(work != NULL){
DeleteHipadabaNode(work,pCon);
sequentialNames(self->objectNode, pCon);
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int Clean(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
int i;
pHdb current = NULL, queue = NULL;
pHdb currentEntry = NULL, tmp;
currentEntry = GetHipadabaNode(self->objectNode,"control/currentEntry");
queue = GetHipadabaNode(self->objectNode,"queue");
current = queue->child;
for(i = 0; i < currentEntry->value.v.intValue; i++){
if(current != NULL){
tmp = current->next;
DeleteNodeData(current);
current = tmp;
}
}
queue->child = tmp;
currentEntry->value.v.intValue = 0;
sequentialNames(self->objectNode, pCon);
NotifyHipadabaPar(currentEntry,pCon);
return 1;
}
/*----------------------------------------------------------------------------*/
static int QueueTask(void *pData){
pSICSOBJ self = (pSICSOBJ)pData;
int status, pos;
pHdb work = NULL;
pHdb exeNode = NULL;
pHdb max = NULL;
char name[80];
pHdbQueue priv = (pHdbQueue)self->pPrivate;
if(priv->iStop == 1){
return 0;
}
work = GetHipadabaNode(self->objectNode,"control/currentEntry");
max = GetHipadabaNode(self->objectNode,"control/maxEntry");
assert(work != NULL && max != NULL);
pos = work->value.v.intValue;
snprintf(name,80,"queue/%3.3d", pos);
exeNode = GetHipadabaNode(self->objectNode,name);
if(exeNode != NULL){
MacroPush(priv->pCon);
exeHdbNode(exeNode, priv->pCon);
MacroPop();
}
if(priv->iStop == 1 || SCGetInterrupt(priv->pCon) != eContinue){
return 0;
}
pos++;
work->value.v.intValue = pos;
NotifyHipadabaPar(work,priv->pCon);
if(pos >= max->value.v.intValue){
return 0;
}
return 1;
}
/*---------------------------------------------------------------------------*/
static int Start(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
pHdbQueue priv = (pHdbQueue)self->pPrivate;
priv->iStop = 0;
priv->pCon = pCon;
TaskRegister(pServ->pTasker,
QueueTask,
NULL,
NULL,
self,
10);
return 1;
}
/*---------------------------------------------------------------------------*/
static int Stop(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
pHdbQueue priv = (pHdbQueue)self->pPrivate;
priv->iStop = 1;
return 1;
}
/*----------------------------------------------------------------------------*/
static int Move(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
pHdb moveNode = NULL;
pHdb insertNode = NULL;
pHdb prevNode = NULL, queueNode = NULL;
pHdb tmp;
char name[80];
if(nPar < 2){
SCWrite(pCon,"ERROR: internal: not enough parameters to Move",eError);
return 1;
}
if(par[1]->value.v.intValue == par[0]->value.v.intValue + 1){
/*
* already in right sequence, nothing to do
*/
return 1;
}
snprintf(name,80,"queue/%3.3d", par[1]->value.v.intValue);
moveNode = GetHipadabaNode(self->objectNode,name);
snprintf(name,80,"queue/%3.3d", par[0]->value.v.intValue);
insertNode = GetHipadabaNode(self->objectNode,name);
if(moveNode == NULL || insertNode == NULL){
SCWrite(pCon,"ERROR: move not possible, participating nodes not found",
eError);
return 0;
}
queueNode = GetHipadabaNode(self->objectNode,"queue");
if(moveNode == queueNode->child){
queueNode->child = queueNode->child->next;
moveNode->next = insertNode->next;
insertNode->next = moveNode;
} else {
prevNode = queueNode->child;
while(prevNode != NULL && prevNode->next != moveNode){
prevNode = prevNode->next;
}
if(insertNode == queueNode->child ){
/*
* insert at top
*/
tmp = queueNode->child;
queueNode->child = moveNode;
prevNode->next = moveNode->next;
moveNode->next = tmp;
} else {
tmp = insertNode->next;
insertNode->next = moveNode;
prevNode->next = moveNode->next;
moveNode->next = tmp;
}
}
sequentialNames(self->objectNode, pCon);
return 1;
}
/*---------------------------------------------------------------------------*/
static void Configure(pSICSOBJ self){
pHdb n = NULL, par = NULL;
hdbValue intValue, textValue, funcValue;
pHdb obj = self->objectNode;
intValue = MakeHdbInt(0);
textValue = MakeHdbText("Undefined");
n = MakeHipadabaNode("control",HIPNONE,1);
AddHipadabaChild(obj,n,NULL);
AddSICSHdbPar(n,"maxEntry",usInternal,intValue);
AddSICSHdbPar(n,"currentEntry",usInternal,intValue);
n = MakeHipadabaNode("queue",HIPNONE,1);
AddHipadabaChild(obj,n, NULL);
funcValue = makeHdbData(HIPFUNC,1,EnqueFunc);
n = MakeSICSHdbPar("enqueue",usUser, funcValue);
AddSICSHdbPar(n,"description",usUser,textValue);
AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,AddCmdData);
n = MakeSICSHdbPar("addcommand",usUser, funcValue);
AddSICSHdbPar(n,"command",usUser,textValue);
AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Dequeue);
n = MakeSICSHdbPar("dequeue",usUser,funcValue);
AddHipadabaChild(obj,n,NULL);
AddSICSHdbPar(n,"index",usUser,intValue);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Clean);
n = MakeSICSHdbPar("clean",usUser, funcValue);
AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Start);
n = MakeSICSHdbPar("start",usUser, funcValue);
AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Stop);
n = MakeSICSHdbPar("stop",usUser, funcValue);
AddHipadabaChild(obj,n,NULL);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
funcValue = makeHdbData(HIPFUNC,1,Move);
n = MakeSICSHdbPar("move",usUser,funcValue);
AddHipadabaChild(obj,n,NULL);
AddSICSHdbPar(n,"moveindex",usUser,intValue);
AddSICSHdbPar(n,"insertindex",usUser,intValue);
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
}
/*---------------------------------------------------------------------------*/
int MakeHDBQueue(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pSICSOBJ self = NULL;
pHdbQueue priv = NULL;
priv = (pHdbQueue)malloc(sizeof(HdbQueue));
self = SetupSICSOBJ(pCon,pSics, pData,argc, argv);
if(self == NULL || priv == NULL){
return 0;
}
Configure(self);
memset(priv,0,sizeof(HdbQueue));
self->pPrivate = priv;
self->KillPrivate = free;
return 1;
}

15
hdbqueue.h Normal file
View File

@ -0,0 +1,15 @@
/**
* This is the new Hipadab based queuing system in support of the MountainGum
* user interface.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, July 2007
*/
#ifndef HDBQUEUE_H_
#define HDBQUEUE_H_
int MakeHDBQueue(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
#endif /*HDBQUEUE_H_*/

View File

@ -29,7 +29,7 @@ void DeleteCallbackChain(pHdbCallback root){
} }
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static void DeleteNodeData(pHdb node){ void DeleteNodeData(pHdb node){
pHdb tmp = NULL; pHdb tmp = NULL;
if(node == NULL){ if(node == NULL){
@ -57,7 +57,7 @@ static void DeleteNodeData(pHdb node){
free(node); free(node);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int InvokeCallbackChain(pHdbCallback root, pHdb node, int InvokeCallbackChain(pHdbCallback root, pHdb node,
void *callData, hdbValue v){ void *callData, hdbValue v){
pHdbCallback current = root; pHdbCallback current = root;
int status; int status;
@ -92,6 +92,17 @@ void RemoveHdbNodeFromParent(pHdb node, void *callData){
parent,callData,parent->value); parent,callData,parent->value);
} }
} }
/*----------------------------------------------------------------------*/
int CountHdbChildren(pHdb node){
int count = 0;
pHdb current = NULL;
current = node->child;
while(current != NULL){
current = current->next;
count++;
}
return count;
}
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static void RemoveCallbackNode(pHdbCallback victim){ static void RemoveCallbackNode(pHdbCallback victim){
if(victim->previous != NULL) { if(victim->previous != NULL) {
@ -347,6 +358,9 @@ hdbValue makeHdbData(int datatype, int length, void *data){
case HIPOBJ: case HIPOBJ:
val.v.obj = data; val.v.obj = data;
break; break;
case HIPFUNC:
val.v.obj = data;
break;
} }
return val; return val;
} }
@ -480,6 +494,7 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
return 1; return 1;
break; break;
case HIPOBJ: case HIPOBJ:
case HIPFUNC:
if(v2.v.obj == v1.v.obj) { if(v2.v.obj == v1.v.obj) {
return 1; return 1;
} else { } else {
@ -523,6 +538,7 @@ int getHdbValueLength(hdbValue v){
length = strlen(v.v.text); length = strlen(v.v.text);
break; break;
case HIPOBJ: case HIPOBJ:
case HIPFUNC:
length = sizeof(void *); length = sizeof(void *);
break; break;
} }
@ -913,6 +929,7 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
} }
break; break;
case HIPOBJ: case HIPOBJ:
case HIPFUNC:
target->v.obj = source->v.obj; target->v.obj = source->v.obj;
break; break;
default: default:
@ -943,6 +960,16 @@ int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData){
return 1; return 1;
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
int NotifyHipadabaPar(pHdb node,void *callData){
int status;
status = InvokeCallbackChain(node->updateCallbacks, node, callData, node->value);
if(status != 1 ){
return status;
}
return 1;
}
/*-----------------------------------------------------------------------------*/
int GetHipadabaPar(pHdb node, hdbValue *v, void *callData){ int GetHipadabaPar(pHdb node, hdbValue *v, void *callData){
int status; int status;

View File

@ -39,6 +39,7 @@
#define HIPINTVARAR 5 #define HIPINTVARAR 5
#define HIPFLOATVARAR 6 #define HIPFLOATVARAR 6
#define HIPOBJ 7 #define HIPOBJ 7
#define HIPFUNC 8
/* -------- callback types */ /* -------- callback types */
#define HCBSET 0 #define HCBSET 0
#define HCBUPDATE 1 #define HCBUPDATE 1
@ -192,7 +193,13 @@ pHdb MakeHipadabaNode(char *name, int datatype, int length);
*/ */
void AddHipadabaChild(pHdb parent, pHdb child, void *callData); void AddHipadabaChild(pHdb parent, pHdb child, void *callData);
/** /**
* delete a hipadaba node and all its children * Delete only the node data, without invoking any callbacks
* @param node The node to delete.
*/
void DeleteNodeData(pHdb node);
/**
* delete a hipadaba node and all its children. Then invoke the tree
* change callback to notify listeners.
* @parma node The node to delete * @parma node The node to delete
* @param callData User data for the tree change callback * @param callData User data for the tree change callback
*/ */
@ -228,6 +235,12 @@ void RemoveHdbNodeFromParent(pHdb node, void *callData);
* @param root The callback chain to delete * @param root The callback chain to delete
*/ */
void DeleteCallbackChain(pHdbCallback root); void DeleteCallbackChain(pHdbCallback root);
/**
* count the numbers of children in thie Hdb node
* @param node The node to count children for
* @return The number of children
*/
int CountHdbChildren(pHdb node);
/*===================== function protoypes: Callbacks ========================*/ /*===================== function protoypes: Callbacks ========================*/
/** /**
* make a new hipdaba callback * make a new hipdaba callback
@ -270,6 +283,16 @@ void RemoveHipadabaCallback(pHdb root, int id);
* @param internalID The internal ID callbacks have to match in order to be removed. * @param internalID The internal ID callbacks have to match in order to be removed.
*/ */
void InternalRemoveHipadabaCallback(pHdb root, int internalID); void InternalRemoveHipadabaCallback(pHdb root, int internalID);
/**
* invoke a callback chain.
* @param root The callback chain to invoke
* @param node The node reposnible for this callback chain
* @param callData Some data belonging to the callback
* @param v The new value for this callback
* @return 1 on success, 0 on failure
*/
int InvokeCallbackChain(pHdbCallback root, pHdb node,
void *callData, hdbValue v);
/*============== Parameter Handling ===============================*/ /*============== Parameter Handling ===============================*/
/** /**
@ -290,6 +313,14 @@ int SetHipadabaPar(pHdb node, hdbValue v, void *callData);
* @return 0 on failure, 1 on success * @return 0 on failure, 1 on success
*/ */
int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData); int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData);
/**
* notify any update listeners that this node has been internally modidifed.
* @param node The node modified
* @param callData Addtional data for the callback
* @return 1 on success, 0 on failure
*/
int NotifyHipadabaPar(pHdb node,void *callData);
/** /**
* Read a hipadaba parameter * Read a hipadaba parameter
* @param node The node for which to read the parameter * @param node The node for which to read the parameter

View File

@ -33,7 +33,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \ sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \
moregress.o hdbcommand.o multicounter.o regresscter.o histregress.o \ moregress.o hdbcommand.o multicounter.o regresscter.o histregress.o \
sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \ sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \
nwatch.o asyncqueue.o asyncprotocol.o nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o hdbqueue.o
MOTOROBJ = motor.o simdriv.o MOTOROBJ = motor.o simdriv.o
COUNTEROBJ = countdriv.o simcter.o counter.o COUNTEROBJ = countdriv.o simcter.o counter.o

6
ofac.c
View File

@ -124,6 +124,8 @@
#include "statemon.h" #include "statemon.h"
#include "asyncqueue.h" #include "asyncqueue.h"
#include "asyncprotocol.h" #include "asyncprotocol.h"
#include "sicsobj.h"
#include "hdbqueue.h"
/*----------------------- Server options creation -------------------------*/ /*----------------------- Server options creation -------------------------*/
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData, static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
@ -341,6 +343,8 @@
StateMonFactory,NULL,NULL); StateMonFactory,NULL,NULL);
AddCommand(pInter,"MakeAsyncProtocol",AsyncProtocolFactory,NULL,NULL); AddCommand(pInter,"MakeAsyncProtocol",AsyncProtocolFactory,NULL,NULL);
AddCommand(pInter,"MakeAsyncQueue",AsyncQueueFactory,NULL,NULL); AddCommand(pInter,"MakeAsyncQueue",AsyncQueueFactory,NULL,NULL);
AddCommand(pInter,"MakeSicsObj",InstallSICSOBJ,NULL,NULL);
AddCommand(pInter,"MakeHdbQueue",MakeHDBQueue,NULL,NULL);
/* /*
install site specific commands install site specific commands
@ -412,6 +416,8 @@
RemoveCommand(pSics,"MakeStateMon"); RemoveCommand(pSics,"MakeStateMon");
RemoveCommand(pSics,"MakeAsyncQueue"); RemoveCommand(pSics,"MakeAsyncQueue");
RemoveCommand(pSics,"MakeAsyncProtocol"); RemoveCommand(pSics,"MakeAsyncProtocol");
RemoveCommand(pSics,"MakeSicsObject");
RemoveCommand(pSics,"MakeHdbQueue");
/* /*
remove site specific installation commands remove site specific installation commands
*/ */

21
scan.c
View File

@ -547,10 +547,6 @@ CountEntry CollectCounterData(pScanData self)
{ {
/*--------- drive */ /*--------- drive */
iRet = self->ScanDrive(self,i); iRet = self->ScanDrive(self,i);
if(!iRet)
{
return 0;
}
/* finished, check for interrupts. Whatever happened, user /* finished, check for interrupts. Whatever happened, user
interrupt or HW interrupt, it will be on our connection interrupt or HW interrupt, it will be on our connection
*/ */
@ -579,13 +575,15 @@ CountEntry CollectCounterData(pScanData self)
return 0; return 0;
break; break;
} }
/*-------------- count */
iRet = self->ScanCount(self, i);
if(!iRet) if(!iRet)
{ {
return 0; SCWrite(self->pCon,"WARNING: skipped scan point after drive failure",
eWarning);
continue;
} }
/*-------------- count */
iRet = self->ScanCount(self, i);
/* finished, check for interrupts. Whatever happened, user /* finished, check for interrupts. Whatever happened, user
interrupt or HW interrupt, it will be on our connection interrupt or HW interrupt, it will be on our connection
*/ */
@ -610,6 +608,13 @@ CountEntry CollectCounterData(pScanData self)
return 0; return 0;
break; break;
} }
if(!iRet)
{
SCWrite(self->pCon,"WARNING: skipped scan point after count failure",
eWarning);
continue;
}
/*-------- scan post processing */ /*-------- scan post processing */
self->CollectScanData(self,i); self->CollectScanData(self,i);
InvokeCallBack(self->pCall,SCANPOINT,self); InvokeCallBack(self->pCall,SCANPOINT,self);

View File

@ -25,6 +25,7 @@
#include <stptok.h> #include <stptok.h>
#include "protocol.h" #include "protocol.h"
#include <splitter.h> #include <splitter.h>
#include "sicsobj.h"
/*== there can be only hipadaba in SICS, some globals to care for that == */ /*== there can be only hipadaba in SICS, some globals to care for that == */
static pHdb root = NULL; static pHdb root = NULL;
@ -102,12 +103,18 @@ static int SICSDriveCallback(void *userData, void *callData, pHdb node,
hdbValue v){ hdbValue v){
SConnection *pCon = NULL; SConnection *pCon = NULL;
pDummy dum = NULL; pDummy dum = NULL;
char pSicsdev[80];
pCon = (SConnection *)callData; pCon = (SConnection *)callData;
dum = (pDummy)userData; dum = (pDummy)userData;
assert(pCon != NULL && dum != NULL); assert(pCon != NULL && dum != NULL);
return StartDevice(pServ->pExecutor,node->name,dum->pDescriptor, if(GetHdbProperty(node,"sicsdev",pSicsdev,79)){
userData, pCon, (float)v.v.doubleValue); return StartDevice(pServ->pExecutor,pSicsdev,dum->pDescriptor,
userData, pCon, (float)v.v.doubleValue);
} else {
return StartDevice(pServ->pExecutor,node->name,dum->pDescriptor,
userData, pCon, (float)v.v.doubleValue);
}
} }
/*---------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------*/
pHdbCallback MakeSICSDriveCallback(void *sicsObject){ pHdbCallback MakeSICSDriveCallback(void *sicsObject){
@ -145,6 +152,37 @@ static int SICSReadDriveCallback(void *userData, void *callData, pHdb node,
} }
return 1; return 1;
} }
/*--------------------------------------------------------------------------*/
static int SICSFuncCallback(void *userData, void *callData, pHdb node,
hdbValue v){
pHdb par[64], current = NULL;
int nPar = 0;
SICSOBJFunc func = NULL;
assert(node->value.dataType == HIPFUNC);
if(userData == NULL || callData == NULL){
printf("Great Badness in calling SICSFuncCallback\n");
return 0;
}
current = node->child;
while(current != NULL){
par[nPar] = current;
nPar++;
current = current->next;
}
func = (SICSOBJFunc)node->value.v.obj;
if(func != NULL){
return func((pSICSOBJ)userData,(SConnection *)callData, par,nPar);
} else {
printf("Great Badness in calling SICSFuncCallback\n");
return 0;
}
}
/*---------------------------------------------------------------------------*/
pHdbCallback MakeSICSFuncCallback(void *obj){
return MakeHipadabaCallback(SICSFuncCallback, obj,NULL,-1,-1);
}
/*--------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------*/
pHdbCallback MakeSICSReadDriveCallback(void *sicsObject){ pHdbCallback MakeSICSReadDriveCallback(void *sicsObject){
return MakeHipadabaCallback(SICSReadDriveCallback, sicsObject,NULL,-1,-1); return MakeHipadabaCallback(SICSReadDriveCallback, sicsObject,NULL,-1,-1);
@ -220,7 +258,50 @@ int formatNameValue(Protocol protocol, char *name, char *value, pDynString resul
} }
return protocol; return protocol;
} }
/*----------------------------------------------------------------------------*/
static int sendZippedNodeData(pHdb node, SConnection *pCon){
hdbValue newValue;
int i, *iData = NULL;
char *path = NULL;
memset(&newValue,0,sizeof(hdbValue));
GetHipadabaPar(node, &newValue, pCon);
path = GetHipadabaPath(node);
switch(newValue.dataType){
case HIPINTAR:
case HIPINTVARAR:
for(i = 0; i < newValue.arrayLength; i++){
newValue.v.intArray[i] = htonl(newValue.v.intArray[i]);
}
SCWriteZipped(pCon,path, newValue.v.intArray,
newValue.arrayLength*sizeof(int));
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
iData = (int *)malloc(newValue.arrayLength*sizeof(int));
if(iData == NULL){
SCWrite(pCon,"ERROR: out of memory in sendZippedData",eError);
free(path);
return 0;
}
memset(iData,0,newValue.arrayLength*sizeof(int));
for(i = 0; i < newValue.arrayLength; i++){
iData[i] = htonl((int)newValue.v.floatArray[i]*65536.);
}
SCWriteZipped(pCon,path, iData,
newValue.arrayLength*sizeof(int));
free(iData);
break;
default:
SCWrite(pCon,"ERROR: zipped writing not supported for this datatype",
eError);
free(path);
return 0;
}
free(path);
ReleaseHdbValue(&newValue);
return 1;
}
/*----------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------*/
static int SICSNotifyCallback(void *userData, void *callData, pHdb node, static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
hdbValue v){ hdbValue v){
@ -229,7 +310,8 @@ static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
pDynString result = NULL; pDynString result = NULL;
char *pPath = NULL; char *pPath = NULL;
Protocol protocol = normal_protocol; Protocol protocol = normal_protocol;
int outCode, macro; int outCode, macro, status;
char value[80];
cbInfo = (HdbCBInfo *)userData; cbInfo = (HdbCBInfo *)userData;
pPath = GetHipadabaPath(node); pPath = GetHipadabaPath(node);
@ -244,6 +326,19 @@ static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
*/ */
macro = SCinMacro(cbInfo->pCon); macro = SCinMacro(cbInfo->pCon);
SCsetMacro(cbInfo->pCon,0); SCsetMacro(cbInfo->pCon,0);
/**
* if transfer = zip always transfer data in zipped form
*/
if(GetHdbProperty(node,"transfer",value,80) == 1){
if(strstr(value,"zip") != NULL){
SCPushContext2(cbInfo->pCon,cbInfo->context);
status = sendZippedNodeData(node, cbInfo->pCon);
SCPopContext(cbInfo->pCon);
SCsetMacro(cbInfo->pCon,macro);
free(pPath);
return status;
}
}
if(v.arrayLength < 100){ if(v.arrayLength < 100){
printedData = formatValue(v); printedData = formatValue(v);
if(pPath == NULL || printedData == NULL || result == NULL){ if(pPath == NULL || printedData == NULL || result == NULL){
@ -1313,6 +1408,7 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
double dValue; double dValue;
char number[80]; char number[80];
char *pPtr = NULL; char *pPtr = NULL;
CommandList *pCom = NULL;
switch(v->dataType){ switch(v->dataType){
case HIPNONE: case HIPNONE:
@ -1385,6 +1481,16 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
v->v.floatArray[i] = dValue; v->v.floatArray[i] = dValue;
} }
break; break;
case HIPOBJ:
pCom = FindCommand(pServ->pSics,data);
if(pCom == NULL && pCom->pData != NULL){
snprintf(error,errlen,"object %s NOT found", data);
return 0;
}
v->v.obj = pCom->pData;
break;
case HIPFUNC:
break;
default: default:
assert(0); assert(0);
break; break;
@ -1404,6 +1510,8 @@ static char *hdbTypes[] = {"none",
"floatar", "floatar",
"intvarar", "intvarar",
"floatvarar", "floatvarar",
"object",
"func",
NULL}; NULL};
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int convertHdbType(char *text){ static int convertHdbType(char *text){
@ -1689,7 +1797,7 @@ static int SetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0; return 0;
} }
if(!cloneHdbValue(&targetNode->value,&newValue)){ if(!cloneHdbValue(&targetNode->value,&newValue)){
SCWrite(pCon,"ERROR: out of mmeory cloning node", SCWrite(pCon,"ERROR: out of memory cloning node",
eError); eError);
return 0; return 0;
} }
@ -1761,6 +1869,7 @@ static int UpdateHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0; return 0;
} }
} else { } else {
memset(&newValue,0,sizeof(hdbValue));
GetHipadabaPar(targetNode,&newValue,pCon); GetHipadabaPar(targetNode,&newValue,pCon);
} }
status = UpdateHipadabaPar(targetNode,newValue,pCon); status = UpdateHipadabaPar(targetNode,newValue,pCon);
@ -1771,6 +1880,25 @@ static int UpdateHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return status; return status;
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static int ZipGetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pHdb targetNode = NULL;
char error[512], oriPath[512];
int status;
if(argc < 2) {
SCWrite(pCon,"ERROR: need path to node",eError);
return 0;
}
strncpy(oriPath,argv[1], 511);
targetNode = locateSICSNode(pSics,pCon,argv[1]);
if(targetNode == NULL){
return 0;
}
return sendZippedNodeData(targetNode,pCon);
}
/*---------------------------------------------------------------------------*/
static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData, static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){ int argc, char *argv[]){
pHdb targetNode = NULL; pHdb targetNode = NULL;
@ -1780,6 +1908,7 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int i, status; int i, status;
Protocol protocol = normal_protocol; Protocol protocol = normal_protocol;
int outCode; int outCode;
char value[80];
if(argc < 2) { if(argc < 2) {
SCWrite(pCon,"ERROR: need path to node to print",eError); SCWrite(pCon,"ERROR: need path to node to print",eError);
@ -1791,6 +1920,14 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
if(targetNode == NULL){ if(targetNode == NULL){
return 0; return 0;
} }
/*
* if transfer = zip, redirect to zip
*/
if(GetHdbProperty(targetNode,"transfer", value,80) == 1){
if(strstr(value,"zip") != NULL){
return ZipGetHdbNode(pCon,pSics,pData,argc,argv);
}
}
memset(&newValue,0,sizeof(hdbValue)); memset(&newValue,0,sizeof(hdbValue));
GetHipadabaPar(targetNode, &newValue, pCon); GetHipadabaPar(targetNode, &newValue, pCon);
parData = formatValue(newValue); parData = formatValue(newValue);
@ -1812,59 +1949,6 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 1; return 1;
} }
/*-----------------------------------------------------------------------------*/
static int ZipGetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pHdb targetNode = NULL;
hdbValue newValue;
char error[512], oriPath[512];
int i, status;
int *iData = NULL;
if(argc < 2) {
SCWrite(pCon,"ERROR: need path to node",eError);
return 0;
}
strncpy(oriPath,argv[1], 511);
targetNode = locateSICSNode(pSics,pCon,argv[1]);
if(targetNode == NULL){
return 0;
}
memset(&newValue,0,sizeof(hdbValue));
GetHipadabaPar(targetNode, &newValue, pCon);
switch(newValue.dataType){
case HIPINTAR:
case HIPINTVARAR:
for(i = 0; i < newValue.arrayLength; i++){
newValue.v.intArray[i] = htonl(newValue.v.intArray[i]);
}
SCWriteZipped(pCon,oriPath, newValue.v.intArray,
newValue.arrayLength*sizeof(int));
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
iData = (int *)malloc(newValue.arrayLength*sizeof(int));
if(iData == NULL){
SCWrite(pCon,"ERROR: out of memory in ZipGetHdbNode",eError);
return 0;
}
memset(iData,0,newValue.arrayLength*sizeof(int));
for(i = 0; i < newValue.arrayLength; i++){
iData[i] = htonl((int)newValue.v.floatArray[i]*65536.);
}
SCWriteZipped(pCon,oriPath, iData,
newValue.arrayLength*sizeof(int));
free(iData);
break;
default:
SCWrite(pCon,"ERROR: zipped writing not supported for this datatype",
eError);
return 0;
}
ReleaseHdbValue(&newValue);
return 1;
}
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int countChildren(pHdb node){ static int countChildren(pHdb node){
pHdb current = NULL; pHdb current = NULL;
@ -2316,6 +2400,63 @@ static int ChainHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
} }
/* --------------------------------------------------------------------------
* This is actually SCInvoke but without advancing the context. I think this
* is only of local use. It makes sure that commands executed as Hipadaba
* commands get logged properly.
*/
static int HDBInvoke(SConnection *self, SicsInterp *pInter, char *pCommand)
{
int iRet;
long lLen;
const char *pResult = NULL;
char *pBuffer = NULL, *pFile = NULL;
char pBueffel[80];
int i, iSpace;
assert(pInter);
/* print command to log files */
for( i = 0; i < self->iFiles; i++)
{
if(self->pFiles[i])
{
fprintf(self->pFiles[i],"SICS>> %s\n",pCommand);
}
}
/* print to command log if user or manager */
if(SCGetRights(self) <= usUser)
{
if(self->pSock != NULL)
{
sprintf(pBueffel,"sock %d>>",self->pSock->sockid);
}
}
/* invoke */
self->inUse++;
self->eInterrupt = eContinue;
self->parameterChange = 0;
/*
get first word of command
*/
iRet = InterpExecute(pInter,self,pCommand);
if(self->parameterChange == 1)
{
/*
automatically save changed parameters
*/
pFile = IFindOption(pSICSOptions,"statusfile");
if(pFile != NULL)
{
WriteSicsStatus(pInter,pFile,0);
self->parameterChange = 0;
}
}
self->inUse--;
return iRet;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int CommandSetCallback(void *userData, void *callData, pHdb node, static int CommandSetCallback(void *userData, void *callData, pHdb node,
hdbValue v){ hdbValue v){
@ -2348,7 +2489,7 @@ static int CommandSetCallback(void *userData, void *callData, pHdb node,
} }
current = current->next; current = current->next;
} }
status = SCInvoke(pCon, pServ->pSics,GetCharArray(cmd)); status = HDBInvoke(pCon,pServ->pSics, GetCharArray(cmd));
DeleteDynString(cmd); DeleteDynString(cmd);
return status; return status;
} else { } else {

View File

@ -119,6 +119,11 @@ pHdbCallback MakeMemSetCallback(float *address);
* @return a suitable callback for notififications about tree changes. * @return a suitable callback for notififications about tree changes.
*/ */
pHdbCallback MakeTreeChangeCallback(SConnection *pCon, int id); pHdbCallback MakeTreeChangeCallback(SConnection *pCon, int id);
/**
* make a clalback to invoke a function node
*/
pHdbCallback MakeSICSFuncCallback(void *obj);
/*======================== parameter creation ===================================*/ /*======================== parameter creation ===================================*/
/** /**
* make a simple SICS hdb parameter. Setting it will call update immediately. Use * make a simple SICS hdb parameter. Setting it will call update immediately. Use

167
sicsobj.c Normal file
View File

@ -0,0 +1,167 @@
/**
* This is the header file for the new (as of 2007) style SICS objects
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, July 2007
*/
#include <sics.h>
#include "assert.h"
#include "ifile.h"
#include "sicsobj.h"
#include "sicshipadaba.h"
/*--------------------------------------------------------------------------*/
static void DefaultKill(void *data){
return;
}
/*---------------------------------------------------------------------------*/
pSICSOBJ MakeSICSOBJ(char *name, char *class){
pSICSOBJ pNew = NULL;
pNew = (pSICSOBJ)malloc(sizeof(SICSOBJ));
if(pNew == NULL){
return NULL;
}
memset(pNew,0,sizeof(SICSOBJ));
pNew->pDes = CreateDescriptor(class);
pNew->objectNode = MakeHipadabaNode(name, HIPNONE, 1);
if(pNew->pDes == NULL || pNew->objectNode == NULL){
free(pNew);
return(NULL);
}
pNew->pDes->parNode = pNew->objectNode;
pNew->KillPrivate = DefaultKill;
return pNew;
}
/*---------------------------------------------------------------------------*/
void KillSICSOBJ(void *data){
pSICSOBJ self = (pSICSOBJ)data;
if(self == NULL){
return;
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->KillPrivate != NULL && self->pPrivate != NULL){
self->KillPrivate(self->pPrivate);
}
free(self);
}
/*===========================================================================*/
static int assignPar(pHdb node, SConnection *pCon, char *data){
char error[132], buffer[256];
int status;
status = readHdbValue(&node->value,data, error, 132);
if(status != 1){
snprintf(buffer,255,"ERROR: error parsing %s: %s",
node->name, error);
SCWrite(pCon,buffer,eError);
return 0;
}
return 1;
}
/*---------------------------------------------------------------------------*/
static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode, SConnection *pCon,
int argc, char *argv[]){
int status, i, count = 0;
pHdb currentPar = NULL;
SICSOBJFunc pFunc = NULL;
pHdb parArray[64];
/*
* assign parameters and fill parameter array for function at the same
* time. Be lenient about missing parameters: Then the old values will
* be used.
*/
for(i = 0, currentPar = commandNode->child;
i < argc && currentPar != NULL;
i++, currentPar = currentPar->next){
if(argv[i] != NULL){
status = assignPar(currentPar,pCon, argv[i]);
}
if(status != 1){
return status;
}
parArray[i] = currentPar;
count++;
}
pFunc = (SICSOBJFunc)commandNode->value.v.obj;
if(pFunc == NULL){
SCWrite(pCon,"ERROR: internal error, function not found",eError);
return 0;
}
status = pFunc(object, pCon, parArray,count);
return status;
}
/*---------------------------------------------------------------------------*/
int InvokeSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pSICSOBJ self = NULL;
int status;
pHdb parNode;
char buffer[132];
self = (pSICSOBJ)pData;
assert(self != NULL);
if(argc < 1){
SCWrite(pCon,"ERROR: Nothing to process",eError);
return -1;
}
parNode = GetHipadabaNode(self->objectNode,argv[1]);
if(parNode != NULL && parNode->value.dataType == HIPFUNC){
status = invokeOBJFunction(self, parNode, pCon, argc-2, &argv[2]);
} else {
status = ProcessSICSHdbPar(self->objectNode,pCon, argv[0],
argc-1,&argv[1]);
}
if(status == -1){
snprintf(buffer,131,"ERROR: no command or parameter found for key: %s",
argv[1]);
SCWrite(pCon,buffer,eError);
status = 0;
}
return status;
}
/*---------------------------------------------------------------------------*/
pSICSOBJ SetupSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pSICSOBJ pNew = NULL;
int status;
if(argc < 3){
SCWrite(pCon,"ERROR: not enough arguments to InstallSICSOBJ",eError);
return NULL;
}
pNew = MakeSICSOBJ(argv[1], argv[2]);
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating new SICS object",eError);
return NULL;
}
status = AddCommand(pSics,
argv[1],
InvokeSICSOBJ,
KillSICSOBJ,
pNew);
if(status != 1){
KillSICSOBJ(pNew);
SCPrintf(pCon,eError,"ERROR: failed create duplicate command %s", argv[1]);
return NULL;
}
return pNew;
}
/*---------------------------------------------------------------------------*/
int InstallSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pSICSOBJ pNew = NULL;
pNew = SetupSICSOBJ(pCon, pSics, pData, argc, argv);
if(pNew == NULL){
return 0;
} else {
return 1;
}
}

44
sicsobj.h Normal file
View File

@ -0,0 +1,44 @@
/**
* This is the header file for the new (as of 2007) style SICS objects
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, July 2007
*/
#ifndef SICSOBJ2_H_
#define SICSOBJ2_H_
#include <stdio.h>
#include <hipadaba.h>
/*======================================================================
* Be careful when changing this data structure. It has to be compatible
* in its first fields with the SICS object descriptor as defined in
* obdes.h in order to achieve backwards compatibility with old style
* SICS objects.
* =====================================================================*/
typedef struct {
pObjectDescriptor pDes;
pHdb objectNode;
void *pPrivate;
void (*KillPrivate)(void *pPrivate);
}SICSOBJ, *pSICSOBJ;
/*-----------------------------------------------------------------------*/
typedef int (*SICSOBJFunc)(pSICSOBJ self, SConnection *pCon,
pHdb par[], int nPar);
/*======================= Live & Death =================================*/
pSICSOBJ MakeSICSOBJ(char *name, char *class);
void KillSICSOBJ(void *data);
/**
* This creates a new SICS object and installs it in the interpreter. It returns
* the newly created SICS object such that the caller can continue
* configuring it.
*/
pSICSOBJ SetupSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*====================== Interpreter Interface ===========================*/
int InvokeSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int InstallSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
#endif /*SICSOBJ2_H_*/