Obsolete
/
libipc-old
Archived
3
0
Fork 0
This repository has been archived on 2024-06-18. You can view files and clone it, but cannot push or open issues/pull-requests.
libipc-old/pubsub/lib/channels.c

196 lines
4.6 KiB
C
Raw Normal View History

2017-01-19 22:07:52 +01:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../core/error.h"
#include "../../core/process.h"
#include "channels.h"
void pubsubd_channel_print (const struct channel *chan)
{
if (chan->chan == NULL) {
handle_err ("pubsubd_channel_print", "chan->chan == NULL");
}
printf ( "\033[32mchan %s\033[00m\n", chan->chan);
if (chan->subs == NULL) {
handle_err ("pubsubd_channel_print", "chan->subs == NULL");
}
else {
array_proc_print (chan->subs);
}
}
void pubsubd_channels_print (const struct channels *chans)
{
printf ("\033[36mmchannels\033[00m\n");
if (chans == NULL) {
handle_err ("pubsubd_channels_print", "chans == NULL");
return ;
}
struct channel *chan = NULL;
LIST_FOREACH(chan, chans, entries) {
pubsubd_channel_print (chan);
}
}
void pubsubd_channels_init (struct channels *chans) { LIST_INIT(chans); }
struct channel * pubsubd_channels_add (struct channels *chans, const char *chan)
{
if(chans == NULL || chan == NULL) {
handle_err ("pubsubd_channels_add", "chans == NULL or chan == NULL");
return NULL;
}
struct channel *n = malloc (sizeof (struct channel));
memset (n, 0, sizeof (struct channel));
pubsubd_channel_new (n, chan);
LIST_INSERT_HEAD(chans, n, entries);
return n;
}
void pubsubd_channels_del (struct channels *chans, struct channel *c)
{
struct channel *todel = pubsubd_channel_get (chans, c);
if(todel != NULL) {
pubsubd_channel_free (todel);
LIST_REMOVE(todel, entries);
free (todel);
todel = NULL;
}
}
void pubsubd_channels_del_all (struct channels *chans)
{
if (!chans)
return;
struct channel *c = NULL;
while (!LIST_EMPTY(chans)) {
c = LIST_FIRST(chans);
LIST_REMOVE(c, entries);
pubsubd_channel_free (c);
free (c);
c = NULL;
}
}
int pubsubd_channel_new (struct channel *c, const char * name)
{
if (c == NULL) {
return 1;
}
size_t nlen = (strlen (name) > BUFSIZ) ? BUFSIZ : strlen (name);
if (c->chan == NULL)
c->chan = malloc (nlen +1);
memset (c->chan, 0, nlen +1);
memcpy (c->chan, name, nlen);
c->chanlen = nlen;
c->subs = malloc (sizeof (struct array_proc));
memset (c->subs, 0, sizeof (struct array_proc));
return 0;
}
void pubsubd_channel_free (struct channel * c)
{
if (c == NULL)
return;
if (c->chan != NULL) {
free (c->chan);
c->chan = NULL;
}
if (c->subs != NULL) {
array_proc_free (c->subs);
free (c->subs);
}
}
struct channel * pubsubd_channel_search (struct channels *chans, char *chan)
{
struct channel * np = NULL;
LIST_FOREACH(np, chans, entries) {
// TODO debug
// printf ("pubsubd_channel_search: %s (%ld) vs %s (%ld)\n"
// , np->chan, np->chanlen, chan, strlen(chan));
if (np->chanlen == strlen (chan)
&& strncmp (np->chan, chan, np->chanlen) == 0) {
// printf ("pubsubd_channel_search: FOUND\n");
return np;
}
}
return NULL;
}
struct channel * pubsubd_channel_get (struct channels *chans, struct channel *c)
{
struct channel * np = NULL;
LIST_FOREACH(np, chans, entries) {
if (pubsubd_channel_eq (np, c))
return np;
}
return NULL;
}
int pubsubd_channel_eq (const struct channel *c1, const struct channel *c2)
{
return c1->chanlen == c2->chanlen &&
strncmp (c1->chan, c2->chan, c1->chanlen) == 0;
}
void pubsubd_channel_subscribe (const struct channel *c, struct process *p)
{
add_proc (c->subs, p);
}
void pubsubd_channel_unsubscribe (const struct channel *c, struct process *p)
{
del_proc (c->subs, p);
}
void pubsubd_channels_subscribe (struct channels *chans
, char *chname, struct process *p)
{
struct channel *chan = pubsubd_channel_search (chans, chname);
if (chan == NULL) {
printf ("chan %s non existent : creation\n", chname);
chan = pubsubd_channels_add (chans, chname);
}
pubsubd_channel_subscribe (chan, p);
}
void pubsubd_channels_unsubscribe (struct channels *chans
, char *chname, struct process *p)
{
struct channel *chan = pubsubd_channel_search (chans, chname);
if (chan == NULL) {
return;
}
pubsubd_channel_unsubscribe (chan, p);
}
void pubsubd_channels_unsubscribe_everywhere (struct channels *chans
, struct process *p)
{
struct channel * chan = NULL;
LIST_FOREACH(chan, chans, entries) {
pubsubd_channel_unsubscribe (chan, p);
}
}