| 102 return; |
107 return; |
| 103 |
108 |
| 104 xmlnode_insert_data(js->current, text, text_len); |
109 xmlnode_insert_data(js->current, text, text_len); |
| 105 } |
110 } |
| 106 |
111 |
| |
112 #else /* HAVE_LIBXML */ |
| |
113 |
| |
114 static void |
| |
115 jabber_parser_element_start_libxml(void *user_data, |
| |
116 const xmlChar *element_name, const xmlChar *prefix, const xmlChar *namespace, |
| |
117 int nb_namespaces, const xmlChar **namespaces, |
| |
118 int nb_attributes, int nb_defaulted, const xmlChar **attributes) |
| |
119 { |
| |
120 JabberStream *js = user_data; |
| |
121 xmlnode *node; |
| |
122 int i; |
| |
123 |
| |
124 if(!element_name) { |
| |
125 return; |
| |
126 } else if(!strcmp(element_name, "stream")) { |
| |
127 js->protocol_version = JABBER_PROTO_0_9; |
| |
128 for(i=0; i < nb_attributes * 5; i += 5) { |
| |
129 int attrib_len = attributes[i+4] - attributes[i+3]; |
| |
130 char *attrib = g_malloc(attrib_len + 1); |
| |
131 memcpy(attrib, attributes[i+3], attrib_len); |
| |
132 attrib[attrib_len] = '\0'; |
| |
133 |
| |
134 if(!strcmp(attributes[i], "version") |
| |
135 && !strcmp(attrib, "1.0")) { |
| |
136 js->protocol_version = JABBER_PROTO_1_0; |
| |
137 } else if(!strcmp(attributes[i], "id")) { |
| |
138 if(js->stream_id) |
| |
139 g_free(js->stream_id); |
| |
140 js->stream_id = g_strdup(attrib); |
| |
141 } |
| |
142 g_free(attrib); |
| |
143 } |
| |
144 if(js->protocol_version == JABBER_PROTO_0_9) |
| |
145 js->auth_type = JABBER_AUTH_IQ_AUTH; |
| |
146 |
| |
147 if(js->state == JABBER_STREAM_INITIALIZING) |
| |
148 jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING); |
| |
149 } else { |
| |
150 |
| |
151 if(js->current) |
| |
152 node = xmlnode_new_child(js->current, element_name); |
| |
153 else |
| |
154 node = xmlnode_new(element_name); |
| |
155 xmlnode_set_namespace(node, namespace); |
| |
156 |
| |
157 for(i=0; i < nb_attributes * 5; i+=5) { |
| |
158 int attrib_len = attributes[i+4] - attributes[i+3]; |
| |
159 char *attrib = g_malloc(attrib_len + 1); |
| |
160 memcpy(attrib, attributes[i+3], attrib_len); |
| |
161 attrib[attrib_len] = '\0'; |
| |
162 xmlnode_set_attrib(node, attributes[i], attrib); |
| |
163 g_free(attrib); |
| |
164 } |
| |
165 |
| |
166 js->current = node; |
| |
167 } |
| |
168 } |
| |
169 |
| |
170 static void |
| |
171 jabber_parser_element_end_libxml(void *user_data, const xmlChar *element_name, |
| |
172 const xmlChar *prefix, const xmlChar *namespace) |
| |
173 { |
| |
174 JabberStream *js = user_data; |
| |
175 |
| |
176 if(!js->current) |
| |
177 return; |
| |
178 |
| |
179 if(js->current->parent) { |
| |
180 if(!strcmp(js->current->name, element_name)) |
| |
181 js->current = js->current->parent; |
| |
182 } else { |
| |
183 xmlnode *packet = js->current; |
| |
184 js->current = NULL; |
| |
185 jabber_process_packet(js, packet); |
| |
186 xmlnode_free(packet); |
| |
187 } |
| |
188 } |
| |
189 |
| |
190 static void |
| |
191 jabber_parser_element_text_libxml(void *user_data, const xmlChar *text, int text_len) |
| |
192 { |
| |
193 JabberStream *js = user_data; |
| |
194 |
| |
195 if(!js->current) |
| |
196 return; |
| |
197 |
| |
198 if(!text || !text_len) |
| |
199 return; |
| |
200 |
| |
201 xmlnode_insert_data(js->current, text, text_len); |
| |
202 } |
| |
203 #endif /* HAVE_LIBXML */ |
| |
204 |
| |
205 |
| |
206 #ifdef HAVE_LIBXML |
| |
207 static xmlSAXHandler jabber_parser_libxml = { |
| |
208 .internalSubset = NULL, |
| |
209 .isStandalone = NULL, |
| |
210 .hasInternalSubset = NULL, |
| |
211 .hasExternalSubset = NULL, |
| |
212 .resolveEntity = NULL, |
| |
213 .getEntity = NULL, |
| |
214 .entityDecl = NULL, |
| |
215 .notationDecl = NULL, |
| |
216 .attributeDecl = NULL, |
| |
217 .elementDecl = NULL, |
| |
218 .unparsedEntityDecl = NULL, |
| |
219 .setDocumentLocator = NULL, |
| |
220 .startDocument = NULL, |
| |
221 .endDocument = NULL, |
| |
222 .startElement = NULL, |
| |
223 .endElement = NULL, |
| |
224 .reference = NULL, |
| |
225 .characters = jabber_parser_element_text_libxml, |
| |
226 .ignorableWhitespace = NULL, |
| |
227 .processingInstruction = NULL, |
| |
228 .comment = NULL, |
| |
229 .warning = NULL, |
| |
230 .error = NULL, |
| |
231 .fatalError = NULL, |
| |
232 .getParameterEntity = NULL, |
| |
233 .cdataBlock = NULL, |
| |
234 .externalSubset = NULL, |
| |
235 .initialized = XML_SAX2_MAGIC, |
| |
236 ._private = NULL, |
| |
237 .startElementNs = jabber_parser_element_start_libxml, |
| |
238 .endElementNs = jabber_parser_element_end_libxml, |
| |
239 .serror = NULL |
| |
240 }; |
| |
241 #else |
| 107 static GMarkupParser jabber_parser = { |
242 static GMarkupParser jabber_parser = { |
| 108 jabber_parser_element_start, |
243 jabber_parser_element_start, |
| 109 jabber_parser_element_end, |
244 jabber_parser_element_end, |
| 110 jabber_parser_element_text, |
245 jabber_parser_element_text, |
| 111 NULL, |
246 NULL, |
| 112 NULL |
247 NULL |
| 113 }; |
248 }; |
| |
249 #endif |
| 114 |
250 |
| 115 void |
251 void |
| 116 jabber_parser_setup(JabberStream *js) |
252 jabber_parser_setup(JabberStream *js) |
| 117 { |
253 { |
| |
254 #ifdef HAVE_LIBXML |
| |
255 /* 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 |
| |
257 * creation time. So, setting up the parser is just a matter of destroying any |
| |
258 * current parser. */ |
| |
259 if (js->context) { |
| |
260 xmlParseChunk(js->context, NULL,0,1); |
| |
261 xmlFreeParserCtxt(js->context); |
| |
262 js->context = NULL; |
| |
263 } |
| |
264 #else |
| 118 if(!js->context) |
265 if(!js->context) |
| 119 js->context = g_markup_parse_context_new(&jabber_parser, 0, js, NULL); |
266 js->context = g_markup_parse_context_new(&jabber_parser, 0, js, NULL); |
| |
267 #endif |
| 120 } |
268 } |
| 121 |
269 |
| 122 |
270 |
| 123 void jabber_parser_process(JabberStream *js, const char *buf, int len) |
271 void jabber_parser_process(JabberStream *js, const char *buf, int len) |
| 124 { |
272 { |
| 125 |
273 |
| |
274 #ifndef HAVE_LIBXML |
| 126 /* May need to check for other encodings and do the conversion here */ |
275 /* May need to check for other encodings and do the conversion here */ |
| 127 |
|
| 128 if(!g_markup_parse_context_parse(js->context, buf, len, NULL)) { |
276 if(!g_markup_parse_context_parse(js->context, buf, len, NULL)) { |
| 129 g_markup_parse_context_free(js->context); |
277 g_markup_parse_context_free(js->context); |
| 130 js->context = NULL; |
278 js->context = NULL; |
| 131 gaim_connection_error(js->gc, _("XML Parse error")); |
279 gaim_connection_error(js->gc, _("XML Parse error")); |
| 132 } |
280 } |
| 133 } |
281 #else |
| 134 |
282 if (js->context == NULL) { |
| |
283 /* libxml inconsistently starts parsing on creating the parser, so so a ParseChunk |
| |
284 * right afterwards to force it. */ |
| |
285 js->context = xmlCreatePushParserCtxt(&jabber_parser_libxml, js, buf, len, NULL); |
| |
286 xmlParseChunk(js->context, NULL, 0, 0); |
| |
287 } else if (xmlParseChunk(js->context, buf, len, 0) < 0) { |
| |
288 gaim_connection_error(js->gc, _("XML Parse error")); |
| |
289 } |
| |
290 #endif |
| |
291 } |
| |
292 |