Only print discovered features if it is a feature
[cascardo/chat.git] / iksemel_extra.c
1 /*
2  * Copyright (C) 2006,2008 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3  *  
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *  
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *  
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *  
18 */
19
20 #include "iksemel_extra.h"
21
22 #ifndef FALSE
23 #define FALSE 0
24 #endif
25 #ifndef TRUE
26 #define TRUE 1
27 #endif
28
29 struct _iks_extra_stream_t
30 {
31   iksStreamHook* hook;
32   void* data;
33   iks* node;
34   int top;
35 };
36
37 static void
38 iks_extra_insert_attrib (iks* node, char** atts)
39 {
40   if (atts == NULL)
41     return;
42   while (*atts)
43     {
44       iks_insert_attrib (node, atts[0], atts[1]);
45       atts += 2;
46     }
47 }
48
49 static int
50 tagHook (void* user_data, char* name, char** atts, int type)
51 {
52   struct _iks_extra_stream_t* pdata;
53   pdata = (struct _iks_extra_stream_t*) user_data;
54   switch (type)
55     {
56     case IKS_OPEN:
57       if (pdata->top == FALSE || !iks_strcmp (name, "stream:stream"))
58         {
59           pdata->top = TRUE;
60           pdata->node = iks_new (name);
61           iks_extra_insert_attrib (pdata->node, atts);
62           if (pdata->hook)
63             pdata->hook (pdata->data, IKS_NODE_START, pdata->node);
64           pdata->node = NULL;
65         }
66       else if (pdata->node == NULL)
67         {
68           pdata->node = iks_new (name);
69           iks_extra_insert_attrib (pdata->node, atts);
70         }
71       else
72         {
73           pdata->node = iks_insert (pdata->node, name);
74           iks_extra_insert_attrib (pdata->node, atts);
75         }
76       break;
77     case IKS_CLOSE:
78       if (pdata->node == NULL)
79         {
80           pdata->node = iks_new (name);
81           if (pdata->hook)
82             pdata->hook (pdata->data, IKS_NODE_STOP, pdata->node);
83           pdata->node = NULL;
84           pdata->top = FALSE;
85         }
86       else if (iks_parent (pdata->node) == NULL)
87         {
88           if (pdata->hook)
89             pdata->hook (pdata->data, IKS_NODE_NORMAL, pdata->node);
90           pdata->node = NULL;
91         }
92       else
93         {
94           pdata->node = iks_parent (pdata->node);
95         }
96       break;
97     case IKS_SINGLE:
98       if (pdata->top == FALSE)
99         {
100           return -IKS_OK;
101         }
102       else if (pdata->node == NULL)
103         {
104           pdata->node = iks_new (name);
105           iks_extra_insert_attrib (pdata->node, atts);
106           if (pdata->hook)
107             pdata->hook (pdata->data, IKS_NODE_NORMAL, pdata->node);
108           pdata->node = NULL;
109         }
110       else
111         {
112           pdata->node = iks_insert (pdata->node, name);
113           iks_extra_insert_attrib (pdata->node, atts);
114           pdata->node = iks_parent (pdata->node);
115         }
116       break;
117     default:
118       break;
119     }
120   return IKS_OK;
121 }
122
123 static int
124 dataHook (void* user_data, char* data, size_t len)
125 {
126   struct _iks_extra_stream_t* pdata;
127   pdata = (struct _iks_extra_stream_t*) user_data;
128   iks_insert_cdata (pdata->node, data, len);
129   return IKS_OK;
130 }
131
132 static void
133 deleteHook (void* user_data)
134 {
135   iks_free (user_data);
136 }
137
138 iksparser*
139 iks_extra_stream_new (void* data, iksStreamHook* hook)
140 {
141   iksparser* parser;
142   struct _iks_extra_stream_t* pdata;
143   pdata = iks_malloc (sizeof (struct _iks_extra_stream_t));
144   pdata->hook = hook;
145   pdata->data = data;
146   pdata->node = NULL;
147   pdata->top = FALSE;
148   parser = iks_sax_extend (iks_stack_new (256, 0),
149                            pdata, tagHook, dataHook, deleteHook);
150   return parser;
151 }