
- Added initial version of sicsget. This is a more generalised way of reading and writing SICS data wherever it is. The thing is extendable if reading something the current way is to slow. This has both a C interface and an interpreter interface.
119 lines
3.0 KiB
C
119 lines
3.0 KiB
C
/**
|
|
* An implementation for a message pipe system as described in
|
|
*
|
|
* http://eventuallyconsistent.net/2013/08/14/messaging-as-a-programming-model-part-2/
|
|
*
|
|
* A message is passed through a series of filter routines which do things.
|
|
*
|
|
* Rather then loops I try using recursion here.
|
|
*
|
|
* copyright: GPL Copyleft
|
|
*
|
|
* Mark Koennecke, November 2013
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <messagepipe.h>
|
|
|
|
/*--------------------------------------------------------------------------------*/
|
|
typedef struct __MessagePipe {
|
|
void *userData;
|
|
mpUserKill killFunc;
|
|
mpFilterFunc filterFunc;
|
|
struct __MessagePipe *next;
|
|
struct __MessagePipe *previous;
|
|
} MessagePipe;
|
|
/*--------------------------------------------------------------------------------*/
|
|
static int EmptyFunc(void *message, void *userData)
|
|
{
|
|
return MPCONTINUE;
|
|
}
|
|
/*---------------------------------------------------------------------------------*/
|
|
pMP MakeMP()
|
|
{
|
|
pMP result = NULL;
|
|
|
|
result = malloc(sizeof(MessagePipe));
|
|
if(result != NULL){
|
|
memset(result,0,sizeof(MessagePipe));
|
|
result->filterFunc = EmptyFunc;
|
|
}
|
|
return result;
|
|
}
|
|
/*---------------------------------------------------------------------------------*/
|
|
void KillMP(pMP self)
|
|
{
|
|
if(self == NULL){
|
|
return;
|
|
}
|
|
|
|
pMP next = self->next;
|
|
if(self->userData != NULL && self->killFunc != NULL){
|
|
self->killFunc(self->userData);
|
|
}
|
|
free(self);
|
|
KillMP(next);
|
|
}
|
|
/*-----------------------------------------------------------------------------------*/
|
|
int AppendMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill)
|
|
{
|
|
assert(self != NULL);
|
|
assert(func != NULL);
|
|
|
|
if(self->next == NULL){
|
|
self->next = malloc(sizeof(MessagePipe));
|
|
if(self->next != NULL){
|
|
self->next->previous = self;
|
|
self->next->next = NULL;
|
|
self->next->userData = userData;
|
|
self->next->killFunc = usKill;
|
|
self->next->filterFunc = func;
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
} else {
|
|
return AppendMPFilter(self->next, func, userData, usKill);
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------------------------------*/
|
|
pMP PrependMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill)
|
|
{
|
|
pMP result = NULL;
|
|
|
|
assert(func != NULL);
|
|
|
|
result = malloc(sizeof(MessagePipe));
|
|
if(result != NULL){
|
|
result->userData = userData;
|
|
result->killFunc = usKill;
|
|
result->filterFunc = func;
|
|
result->next = self;
|
|
result->previous = NULL;
|
|
return result;
|
|
} else {
|
|
/*
|
|
we are ignoring an error here.........
|
|
*/
|
|
return self;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------------*/
|
|
int MPprocess(pMP self, void *message)
|
|
{
|
|
int status;
|
|
|
|
if(self == NULL || self->filterFunc == NULL){
|
|
return MPCONTINUE;
|
|
} else {
|
|
status = self->filterFunc(message, self->userData);
|
|
if(status == MPSTOP){
|
|
return status;
|
|
} else {
|
|
return MPprocess(self->next, message);
|
|
}
|
|
}
|
|
}
|