Added extra iksemel stream parser
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Sun, 2 Nov 2008 01:37:01 +0000 (23:37 -0200)
committerThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Sun, 2 Nov 2008 01:37:01 +0000 (23:37 -0200)
This stream parser allows hooks to get xmpp stanzas without requiring
the use of iksemel transport, giving it a little more flexibility.

iksemel_extra.c [new file with mode: 0644]
iksemel_extra.h [new file with mode: 0644]

diff --git a/iksemel_extra.c b/iksemel_extra.c
new file mode 100644 (file)
index 0000000..b4c1091
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2006,2008 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *  
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *  
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *  
+*/
+
+#include "iksemel_extra.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+struct _iks_extra_stream_t
+{
+  iksStreamHook* hook;
+  void* data;
+  iks* node;
+  int top;
+};
+
+static void
+iks_extra_insert_attrib (iks* node, char** atts)
+{
+  if (atts == NULL)
+    return;
+  while (*atts)
+    {
+      iks_insert_attrib (node, atts[0], atts[1]);
+      atts += 2;
+    }
+}
+
+static int
+tagHook (void* user_data, char* name, char** atts, int type)
+{
+  struct _iks_extra_stream_t* pdata;
+  pdata = (struct _iks_extra_stream_t*) user_data;
+  switch (type)
+    {
+    case IKS_OPEN:
+      if (pdata->top == FALSE || !iks_strcmp (name, "stream:stream"))
+       {
+         pdata->top = TRUE;
+         pdata->node = iks_new (name);
+         iks_extra_insert_attrib (pdata->node, atts);
+          if (pdata->hook)
+           pdata->hook (pdata->data, IKS_NODE_START, pdata->node);
+         pdata->node = NULL;
+       }
+      else if (pdata->node == NULL)
+       {
+         pdata->node = iks_new (name);
+         iks_extra_insert_attrib (pdata->node, atts);
+       }
+      else
+       {
+         pdata->node = iks_insert (pdata->node, name);
+         iks_extra_insert_attrib (pdata->node, atts);
+       }
+      break;
+    case IKS_CLOSE:
+      if (pdata->node == NULL)
+       {
+         pdata->node = iks_new (name);
+          if (pdata->hook)
+           pdata->hook (pdata->data, IKS_NODE_STOP, pdata->node);
+         pdata->node = NULL;
+         pdata->top = FALSE;
+       }
+      else if (iks_parent (pdata->node) == NULL)
+       {
+          if (pdata->hook)
+           pdata->hook (pdata->data, IKS_NODE_NORMAL, pdata->node);
+         pdata->node = NULL;
+       }
+      else
+       {
+         pdata->node = iks_parent (pdata->node);
+       }
+      break;
+    case IKS_SINGLE:
+      if (pdata->top == FALSE)
+       {
+         return -IKS_OK;
+       }
+      else if (pdata->node == NULL)
+       {
+         pdata->node = iks_new (name);
+         iks_extra_insert_attrib (pdata->node, atts);
+          if (pdata->hook)
+           pdata->hook (pdata->data, IKS_NODE_NORMAL, pdata->node);
+         pdata->node = NULL;
+       }
+      else
+       {
+         pdata->node = iks_insert (pdata->node, name);
+         iks_extra_insert_attrib (pdata->node, atts);
+         pdata->node = iks_parent (pdata->node);
+       }
+      break;
+    default:
+      break;
+    }
+  return IKS_OK;
+}
+
+static int
+dataHook (void* user_data, char* data, size_t len)
+{
+  struct _iks_extra_stream_t* pdata;
+  pdata = (struct _iks_extra_stream_t*) user_data;
+  iks_insert_cdata (pdata->node, data, len);
+  return IKS_OK;
+}
+
+static void
+deleteHook (void* user_data)
+{
+  iks_free (user_data);
+}
+
+iksparser*
+iks_extra_stream_new (void* data, iksStreamHook* hook)
+{
+  iksparser* parser;
+  struct _iks_extra_stream_t* pdata;
+  pdata = iks_malloc (sizeof (struct _iks_extra_stream_t));
+  pdata->hook = hook;
+  pdata->data = data;
+  pdata->node = NULL;
+  pdata->top = FALSE;
+  parser = iks_sax_extend (iks_stack_new (256, 0),
+                          pdata, tagHook, dataHook, deleteHook);
+  return parser;
+}
diff --git a/iksemel_extra.h b/iksemel_extra.h
new file mode 100644 (file)
index 0000000..7d0c6dc
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2006,2008 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *  
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *  
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *  
+*/
+
+#ifndef IKSEMEL_EXTRA_H
+#define IKSEMEL_EXTRA_H
+
+#include <iksemel.h>
+
+iksparser* iks_extra_stream_new (void*, iksStreamHook*);
+
+#endif