Files
sics/messagepipe.c
koennecke 57b6dce6bf - Added messagepipe.c
- 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.
2013-11-07 08:42:32 +00:00

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);
}
}
}