Created extensible hooks
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Mon, 3 Nov 2008 12:19:48 +0000 (10:19 -0200)
committerThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Mon, 3 Nov 2008 12:19:48 +0000 (10:19 -0200)
hook.c
xmpp.c
xmpp.h
xmpp_internal.h

diff --git a/hook.c b/hook.c
index 766d6a1..43eeef2 100644 (file)
--- a/hook.c
+++ b/hook.c
 #include "sasl.h"
 #include "bind.h"
 #include "disco.h"
+#include "xmpp_internal.h"
+
+void
+hc_xmpp_hook_bind (hc_xmpp_t *xmpp, iks *stanza)
+{
+  hc_xmpp_bind_result (xmpp, stanza);
+  if (hc_xmpp_status (xmpp) == HC_XMPP_BOUND &&
+      hc_xmpp_is_session_supported (xmpp))
+    hc_xmpp_session (xmpp);
+}
+
+void
+hc_xmpp_hook_session (hc_xmpp_t *xmpp, iks *stanza)
+{
+  hc_xmpp_session_result (xmpp, stanza);
+  if (hc_xmpp_status (xmpp) == HC_XMPP_SESSION)
+    hc_xmpp_send_disco_info (xmpp, hc_xmpp_server (xmpp));
+}
+
+void
+hc_xmpp_hook_disco (hc_xmpp_t *xmpp, iks *stanza)
+{
+  hc_xmpp_recv_disco (xmpp, stanza);
+}
 
 int
 hc_xmpp_hook (void *data, int type, iks *stanza)
 {
+  hc_xmpp_t *xmpp = (hc_xmpp_t *) data;
   if (!iks_strcmp (iks_name (stanza), "iq"))
     {
       char *ns = iks_find_attrib (iks_child (stanza), "xmlns");
-      if (!iks_strcmp (ns, HC_XMPP_NS_BIND))
-        {
-          hc_xmpp_bind_result (data, stanza);
-          if (hc_xmpp_status (data) == HC_XMPP_BOUND &&
-              hc_xmpp_is_session_supported (data))
-            hc_xmpp_session (data);
-        }
-      else if (!iks_strcmp (ns, HC_XMPP_NS_SESSION))
-        {
-          hc_xmpp_session_result (data, stanza);
-          if (hc_xmpp_status (data) == HC_XMPP_SESSION)
-            hc_xmpp_send_disco_info (data, hc_xmpp_server (data));
-        }
-      else if (!iks_strcmp (ns, HC_XMPP_NS_DISCO_INFO))
-        {
-          hc_xmpp_recv_disco (data, stanza);
-        }
+      hc_xmpp_hook_t hook;
+      if (g_hash_table_lookup_extended (xmpp->nshooks, ns,
+                                        NULL, (gpointer *) &hook))
+        hook (xmpp, stanza);
     }
   else if (!iks_strcmp (iks_name (stanza), "stream:features"))
     {
diff --git a/xmpp.c b/xmpp.c
index 283c68a..dc59c17 100644 (file)
--- a/xmpp.c
+++ b/xmpp.c
@@ -38,6 +38,11 @@ hc_xmpp_new (iksStreamHook *hook, char *server, char *user, char *pass)
   xmpp->tls = NONE;
   xmpp->sasl = NONE;
   xmpp->status = HC_XMPP_NONE;
+  xmpp->nshooks = g_hash_table_new (g_str_hash, g_str_equal);
+  g_hash_table_insert (xmpp->nshooks, HC_XMPP_NS_BIND, hc_xmpp_hook_bind);
+  g_hash_table_insert (xmpp->nshooks, HC_XMPP_NS_SESSION, hc_xmpp_hook_session);
+  g_hash_table_insert (xmpp->nshooks, HC_XMPP_NS_DISCO_INFO,
+                       hc_xmpp_hook_disco);
   return xmpp;
 }
 
diff --git a/xmpp.h b/xmpp.h
index b33ad25..c0780b7 100644 (file)
--- a/xmpp.h
+++ b/xmpp.h
@@ -31,6 +31,7 @@ enum
 };
 
 typedef struct _hc_xmpp_t hc_xmpp_t;
+typedef void (*hc_xmpp_hook_t) (hc_xmpp_t *, iks *);
 
 #define HC_XMPP_NS_TLS "urn:ietf:params:xml:ns:xmpp-tls"
 #define HC_XMPP_NS_SASL "urn:ietf:params:xml:ns:xmpp-sasl"
index d46fcf9..2a120e0 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef HC_XMPP_INTERNAL_H
 #define HC_XMPP_INTERNAL_H
 
+#include <glib.h>
 #include <gsasl.h>
 #include <iksemel.h>
 #include "xmpp.h"
@@ -41,6 +42,7 @@ struct _hc_xmpp_t
   iksparser *parser;
   Gsasl *sasl_ctx;
   Gsasl_session *sasl_session;
+  GHashTable *nshooks;
   int fd;
   int tls;
   int sasl;
@@ -49,4 +51,8 @@ struct _hc_xmpp_t
   int status;
 };
 
+void hc_xmpp_hook_bind (hc_xmpp_t *, iks *);
+void hc_xmpp_hook_session (hc_xmpp_t *, iks *);
+void hc_xmpp_hook_disco (hc_xmpp_t *, iks *);
+
 #endif