Parsee/src/XMPPThread/PEP.c

126 lines
2.6 KiB
C

#include "XMPPThread/internal.h"
#include <Cytoplasm/HashMap.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Log.h>
#include <pthread.h>
struct PEPManager {
pthread_mutex_t lock;
ParseeData *data;
HashMap *node_table;
void *cookie;
};
PEPManager *
CreatePEPManager(ParseeData *data, void *cookie)
{
PEPManager *ret;
if (!data)
{
return NULL;
}
ret = Malloc(sizeof(*ret));
ret->cookie = cookie;
ret->data = data;
ret->node_table = HashMapCreate();
pthread_mutex_init(&ret->lock, NULL);
return ret;
}
void *
PEPManagerCookie(PEPManager *manager)
{
return manager ? manager->cookie : NULL;
}
void
PEPManagerAddEvent(PEPManager *manager, char *node, PEPEvent event)
{
if (!manager || !node || !event)
{
return;
}
pthread_mutex_lock(&manager->lock);
HashMapSet(manager->node_table, node, event);
pthread_mutex_unlock(&manager->lock);
}
static bool
PEPManagerHandleEvent(PEPManager *manager, XMLElement *stanza)
{
PEPEvent call = NULL;
XMLElement *event, *ps, *ev;
size_t i;
if (!manager || !stanza)
{
return false;
}
#define PEP_NS "http://jabber.org/protocol/pubsub"
if (!(ps = XMLookForTKV(stanza, "pubsub", "xmlns", PEP_NS)) &&
!(ev = XMLookForTKV(stanza, "event", "xmlns", PEP_NS "#event")))
{
return false;
}
event = ps ? ps : ev;
for (i = 0; i < ArraySize(event->children); i++)
{
XMLElement *items = ArrayGet(event->children, i);
char *node = HashMapGet(items->attrs, "node");
if ((call = HashMapGet(manager->node_table, node)))
{
size_t j;
/* Use the callback over all items */
if (ev)
{
for (j = 0; j < ArraySize(items->children); j++)
{
call(manager, stanza, ArrayGet(items->children, j));
}
return true;
}
/* ... or over "items" specifically. */
call(manager, stanza, items);
return true;
}
}
return false;
}
bool
PEPManagerHandle(PEPManager *manager, XMLElement *stanza)
{
if (!manager || !stanza)
{
return false;
}
/* Check if it is a PEP stanza */
if (PEPManagerHandleEvent(manager, stanza))
{
return true;
}
return false;
}
void
DestroyPEPManager(PEPManager *manager)
{
if (!manager)
{
return;
}
pthread_mutex_destroy(&manager->lock);
HashMapFree(manager->node_table);
Free(manager);
}