#include "XMPPThread/internal.h" #include #include #include #include #include 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); }