Mercurial > pidgin
comparison libgaim/protocols/jabber/parser.c @ 14436:289490ee84d1
[gaim-migrate @ 17150]
libxml2 is now required for XML parsing
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 04 Sep 2006 03:55:12 +0000 |
parents | e52d5626824a |
children | 218a36c1c9e2 |
comparison
equal
deleted
inserted
replaced
14435:9c6533500fff | 14436:289490ee84d1 |
---|---|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 * | 19 * |
20 */ | 20 */ |
21 #include "internal.h" | 21 #include "internal.h" |
22 | 22 |
23 #ifdef HAVE_LIBXML | |
24 #include <libxml/parser.h> | 23 #include <libxml/parser.h> |
25 #endif | |
26 | 24 |
27 #include "connection.h" | 25 #include "connection.h" |
28 #include "debug.h" | 26 #include "debug.h" |
29 #include "jabber.h" | 27 #include "jabber.h" |
30 #include "parser.h" | 28 #include "parser.h" |
31 #include "xmlnode.h" | 29 #include "xmlnode.h" |
32 | |
33 #ifndef HAVE_LIBXML | |
34 static void | |
35 jabber_parser_element_start(GMarkupParseContext *context, | |
36 const char *element_name, const char **attrib_names, | |
37 const char **attrib_values, gpointer user_data, GError **error) | |
38 { | |
39 JabberStream *js = user_data; | |
40 xmlnode *node; | |
41 int i; | |
42 | |
43 if(!element_name) { | |
44 return; | |
45 } else if(!strcmp(element_name, "stream:stream")) { | |
46 js->protocol_version = JABBER_PROTO_0_9; | |
47 for(i=0; attrib_names[i]; i++) { | |
48 if(!strcmp(attrib_names[i], "version") | |
49 && !strcmp(attrib_values[i], "1.0")) { | |
50 js->protocol_version = JABBER_PROTO_1_0; | |
51 } else if(!strcmp(attrib_names[i], "id")) { | |
52 if(js->stream_id) | |
53 g_free(js->stream_id); | |
54 js->stream_id = g_strdup(attrib_values[i]); | |
55 } | |
56 } | |
57 if(js->protocol_version == JABBER_PROTO_0_9) | |
58 js->auth_type = JABBER_AUTH_IQ_AUTH; | |
59 | |
60 if(js->state == JABBER_STREAM_INITIALIZING) | |
61 jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING); | |
62 } else { | |
63 | |
64 if(js->current) | |
65 node = xmlnode_new_child(js->current, element_name); | |
66 else | |
67 node = xmlnode_new(element_name); | |
68 | |
69 for(i=0; attrib_names[i]; i++) { | |
70 xmlnode_set_attrib(node, attrib_names[i], attrib_values[i]); | |
71 } | |
72 | |
73 js->current = node; | |
74 } | |
75 } | |
76 | |
77 static void | |
78 jabber_parser_element_end(GMarkupParseContext *context, | |
79 const char *element_name, gpointer user_data, GError **error) | |
80 { | |
81 JabberStream *js = user_data; | |
82 | |
83 if(!js->current) | |
84 return; | |
85 | |
86 if(js->current->parent) { | |
87 if(!strcmp(js->current->name, element_name)) | |
88 js->current = js->current->parent; | |
89 } else { | |
90 xmlnode *packet = js->current; | |
91 js->current = NULL; | |
92 jabber_process_packet(js, packet); | |
93 xmlnode_free(packet); | |
94 } | |
95 } | |
96 | |
97 static void | |
98 jabber_parser_element_text(GMarkupParseContext *context, const char *text, | |
99 gsize text_len, gpointer user_data, GError **error) | |
100 { | |
101 JabberStream *js = user_data; | |
102 | |
103 if(!js->current) | |
104 return; | |
105 | |
106 if(!text || !text_len) | |
107 return; | |
108 | |
109 xmlnode_insert_data(js->current, text, text_len); | |
110 } | |
111 | |
112 #else /* HAVE_LIBXML */ | |
113 | 30 |
114 static void | 31 static void |
115 jabber_parser_element_start_libxml(void *user_data, | 32 jabber_parser_element_start_libxml(void *user_data, |
116 const xmlChar *element_name, const xmlChar *prefix, const xmlChar *namespace, | 33 const xmlChar *element_name, const xmlChar *prefix, const xmlChar *namespace, |
117 int nb_namespaces, const xmlChar **namespaces, | 34 int nb_namespaces, const xmlChar **namespaces, |
128 for(i=0; i < nb_attributes * 5; i += 5) { | 45 for(i=0; i < nb_attributes * 5; i += 5) { |
129 int attrib_len = attributes[i+4] - attributes[i+3]; | 46 int attrib_len = attributes[i+4] - attributes[i+3]; |
130 char *attrib = g_malloc(attrib_len + 1); | 47 char *attrib = g_malloc(attrib_len + 1); |
131 memcpy(attrib, attributes[i+3], attrib_len); | 48 memcpy(attrib, attributes[i+3], attrib_len); |
132 attrib[attrib_len] = '\0'; | 49 attrib[attrib_len] = '\0'; |
133 | 50 |
134 if(!strcmp(attributes[i], "version") | 51 if(!strcmp(attributes[i], "version") |
135 && !strcmp(attrib, "1.0")) { | 52 && !strcmp(attrib, "1.0")) { |
136 js->protocol_version = JABBER_PROTO_1_0; | 53 js->protocol_version = JABBER_PROTO_1_0; |
137 } else if(!strcmp(attributes[i], "id")) { | 54 } else if(!strcmp(attributes[i], "id")) { |
138 if(js->stream_id) | 55 if(js->stream_id) |
166 js->current = node; | 83 js->current = node; |
167 } | 84 } |
168 } | 85 } |
169 | 86 |
170 static void | 87 static void |
171 jabber_parser_element_end_libxml(void *user_data, const xmlChar *element_name, | 88 jabber_parser_element_end_libxml(void *user_data, const xmlChar *element_name, |
172 const xmlChar *prefix, const xmlChar *namespace) | 89 const xmlChar *prefix, const xmlChar *namespace) |
173 { | 90 { |
174 JabberStream *js = user_data; | 91 JabberStream *js = user_data; |
175 | 92 |
176 if(!js->current) | 93 if(!js->current) |
198 if(!text || !text_len) | 115 if(!text || !text_len) |
199 return; | 116 return; |
200 | 117 |
201 xmlnode_insert_data(js->current, text, text_len); | 118 xmlnode_insert_data(js->current, text, text_len); |
202 } | 119 } |
203 #endif /* HAVE_LIBXML */ | |
204 | 120 |
205 | |
206 #ifdef HAVE_LIBXML | |
207 static xmlSAXHandler jabber_parser_libxml = { | 121 static xmlSAXHandler jabber_parser_libxml = { |
208 .internalSubset = NULL, | 122 .internalSubset = NULL, |
209 .isStandalone = NULL, | 123 .isStandalone = NULL, |
210 .hasInternalSubset = NULL, | 124 .hasInternalSubset = NULL, |
211 .hasExternalSubset = NULL, | 125 .hasExternalSubset = NULL, |
236 ._private = NULL, | 150 ._private = NULL, |
237 .startElementNs = jabber_parser_element_start_libxml, | 151 .startElementNs = jabber_parser_element_start_libxml, |
238 .endElementNs = jabber_parser_element_end_libxml, | 152 .endElementNs = jabber_parser_element_end_libxml, |
239 .serror = NULL | 153 .serror = NULL |
240 }; | 154 }; |
241 #else | |
242 static GMarkupParser jabber_parser = { | |
243 jabber_parser_element_start, | |
244 jabber_parser_element_end, | |
245 jabber_parser_element_text, | |
246 NULL, | |
247 NULL | |
248 }; | |
249 #endif | |
250 | 155 |
251 void | 156 void |
252 jabber_parser_setup(JabberStream *js) | 157 jabber_parser_setup(JabberStream *js) |
253 { | 158 { |
254 #ifdef HAVE_LIBXML | |
255 /* This seems backwards, but it makes sense. The libxml code creates the parser | 159 /* This seems backwards, but it makes sense. The libxml code creates the parser |
256 * context when you try to use it (this way, it can figure out the encoding at | 160 * context when you try to use it (this way, it can figure out the encoding at |
257 * creation time. So, setting up the parser is just a matter of destroying any | 161 * creation time. So, setting up the parser is just a matter of destroying any |
258 * current parser. */ | 162 * current parser. */ |
259 if (js->context) { | 163 if (js->context) { |
260 xmlParseChunk(js->context, NULL,0,1); | 164 xmlParseChunk(js->context, NULL,0,1); |
261 xmlFreeParserCtxt(js->context); | 165 xmlFreeParserCtxt(js->context); |
262 js->context = NULL; | 166 js->context = NULL; |
263 } | 167 } |
264 #else | |
265 if(!js->context) | |
266 js->context = g_markup_parse_context_new(&jabber_parser, 0, js, NULL); | |
267 #endif | |
268 } | 168 } |
269 | 169 |
270 | 170 |
271 void jabber_parser_process(JabberStream *js, const char *buf, int len) | 171 void jabber_parser_process(JabberStream *js, const char *buf, int len) |
272 { | 172 { |
273 | |
274 #ifndef HAVE_LIBXML | |
275 /* May need to check for other encodings and do the conversion here */ | |
276 if(!g_markup_parse_context_parse(js->context, buf, len, NULL)) { | |
277 g_markup_parse_context_free(js->context); | |
278 js->context = NULL; | |
279 gaim_connection_error(js->gc, _("XML Parse error")); | |
280 } | |
281 #else | |
282 if (js->context == NULL) { | 173 if (js->context == NULL) { |
283 /* libxml inconsistently starts parsing on creating the parser, so so a ParseChunk | 174 /* libxml inconsistently starts parsing on creating the parser, so so a ParseChunk |
284 * right afterwards to force it. */ | 175 * right afterwards to force it. */ |
285 js->context = xmlCreatePushParserCtxt(&jabber_parser_libxml, js, buf, len, NULL); | 176 js->context = xmlCreatePushParserCtxt(&jabber_parser_libxml, js, buf, len, NULL); |
286 } else if (xmlParseChunk(js->context, buf, len, 0) < 0) { | 177 } else if (xmlParseChunk(js->context, buf, len, 0) < 0) { |
287 gaim_connection_error(js->gc, _("XML Parse error")); | 178 gaim_connection_error(js->gc, _("XML Parse error")); |
288 } | 179 } |
289 #endif | |
290 } | 180 } |
291 | 181 |