From cab9c870d3581b356c521690582a75cf60017d98 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Sat, 1 Nov 2008 23:37:01 -0200 Subject: [PATCH] Added extra iksemel stream parser 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 | 151 ++++++++++++++++++++++++++++++++++++++++++++++++ iksemel_extra.h | 27 +++++++++ 2 files changed, 178 insertions(+) create mode 100644 iksemel_extra.c create mode 100644 iksemel_extra.h diff --git a/iksemel_extra.c b/iksemel_extra.c new file mode 100644 index 0000000..b4c1091 --- /dev/null +++ b/iksemel_extra.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2006,2008 Thadeu Lima de Souza Cascardo + * + * 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 index 0000000..7d0c6dc --- /dev/null +++ b/iksemel_extra.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006,2008 Thadeu Lima de Souza Cascardo + * + * 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 + +iksparser* iks_extra_stream_new (void*, iksStreamHook*); + +#endif -- 2.20.1