Mercurial > pidgin.yaz
annotate libgaim/protocols/jabber/parser.c @ 15147:4035dfc09faa
[gaim-migrate @ 17932]
API Changelog for [17929]
committer: Tailor Script <tailor@pidgin.im>
author | Evan Schoenberg <evan.s@dreskin.net> |
---|---|
date | Sun, 10 Dec 2006 02:58:30 +0000 |
parents | 060594ebbef9 |
children | f814b2df9cce |
rev | line source |
---|---|
14192 | 1 /* |
2 * gaim - Jabber XML parser stuff | |
3 * | |
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 #include "internal.h" | |
22 | |
23 #include <libxml/parser.h> | |
24 | |
25 #include "connection.h" | |
26 #include "debug.h" | |
27 #include "jabber.h" | |
28 #include "parser.h" | |
15098 | 29 #include "util.h" |
14192 | 30 #include "xmlnode.h" |
31 | |
32 static void | |
33 jabber_parser_element_start_libxml(void *user_data, | |
34 const xmlChar *element_name, const xmlChar *prefix, const xmlChar *namespace, | |
35 int nb_namespaces, const xmlChar **namespaces, | |
36 int nb_attributes, int nb_defaulted, const xmlChar **attributes) | |
37 { | |
38 JabberStream *js = user_data; | |
39 xmlnode *node; | |
40 int i; | |
41 | |
42 if(!element_name) { | |
43 return; | |
14628
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
44 } else if(!xmlStrcmp(element_name, (xmlChar*) "stream")) { |
14192 | 45 js->protocol_version = JABBER_PROTO_0_9; |
46 for(i=0; i < nb_attributes * 5; i += 5) { | |
47 int attrib_len = attributes[i+4] - attributes[i+3]; | |
48 char *attrib = g_malloc(attrib_len + 1); | |
49 memcpy(attrib, attributes[i+3], attrib_len); | |
50 attrib[attrib_len] = '\0'; | |
14436 | 51 |
14628
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
52 if(!xmlStrcmp(attributes[i], (xmlChar*) "version") |
14192 | 53 && !strcmp(attrib, "1.0")) { |
54 js->protocol_version = JABBER_PROTO_1_0; | |
14623
86e1ebd8ee7f
[gaim-migrate @ 17352]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14476
diff
changeset
|
55 g_free(attrib); |
14628
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
56 } else if(!xmlStrcmp(attributes[i], (xmlChar*) "id")) { |
14192 | 57 if(js->stream_id) |
58 g_free(js->stream_id); | |
14623
86e1ebd8ee7f
[gaim-migrate @ 17352]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14476
diff
changeset
|
59 js->stream_id = attrib; |
14192 | 60 } |
61 } | |
62 if(js->protocol_version == JABBER_PROTO_0_9) | |
63 js->auth_type = JABBER_AUTH_IQ_AUTH; | |
64 | |
65 if(js->state == JABBER_STREAM_INITIALIZING) | |
66 jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING); | |
67 } else { | |
68 | |
69 if(js->current) | |
14628
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
70 node = xmlnode_new_child(js->current, (const char*) element_name); |
14192 | 71 else |
14628
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
72 node = xmlnode_new((const char*) element_name); |
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
73 xmlnode_set_namespace(node, (const char*) namespace); |
14192 | 74 |
75 for(i=0; i < nb_attributes * 5; i+=5) { | |
15097 | 76 char *txt; |
14192 | 77 int attrib_len = attributes[i+4] - attributes[i+3]; |
78 char *attrib = g_malloc(attrib_len + 1); | |
79 memcpy(attrib, attributes[i+3], attrib_len); | |
80 attrib[attrib_len] = '\0'; | |
15097 | 81 txt = attrib; |
82 attrib = gaim_unescape_html(txt); | |
83 g_free(txt); | |
14628
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
84 xmlnode_set_attrib(node, (const char*) attributes[i], attrib); |
14192 | 85 g_free(attrib); |
86 } | |
87 | |
88 js->current = node; | |
89 } | |
90 } | |
91 | |
92 static void | |
14436 | 93 jabber_parser_element_end_libxml(void *user_data, const xmlChar *element_name, |
14192 | 94 const xmlChar *prefix, const xmlChar *namespace) |
95 { | |
96 JabberStream *js = user_data; | |
97 | |
98 if(!js->current) | |
99 return; | |
100 | |
101 if(js->current->parent) { | |
14628
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
102 if(!xmlStrcmp((xmlChar*) js->current->name, element_name)) |
14192 | 103 js->current = js->current->parent; |
104 } else { | |
105 xmlnode *packet = js->current; | |
106 js->current = NULL; | |
107 jabber_process_packet(js, packet); | |
108 xmlnode_free(packet); | |
109 } | |
110 } | |
111 | |
112 static void | |
113 jabber_parser_element_text_libxml(void *user_data, const xmlChar *text, int text_len) | |
114 { | |
115 JabberStream *js = user_data; | |
116 | |
117 if(!js->current) | |
118 return; | |
119 | |
120 if(!text || !text_len) | |
121 return; | |
122 | |
14628
58202142e9ad
[gaim-migrate @ 17369]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14623
diff
changeset
|
123 xmlnode_insert_data(js->current, (const char*) text, text_len); |
14192 | 124 } |
125 | |
126 static xmlSAXHandler jabber_parser_libxml = { | |
127 .internalSubset = NULL, | |
128 .isStandalone = NULL, | |
129 .hasInternalSubset = NULL, | |
130 .hasExternalSubset = NULL, | |
131 .resolveEntity = NULL, | |
132 .getEntity = NULL, | |
133 .entityDecl = NULL, | |
134 .notationDecl = NULL, | |
135 .attributeDecl = NULL, | |
136 .elementDecl = NULL, | |
137 .unparsedEntityDecl = NULL, | |
138 .setDocumentLocator = NULL, | |
139 .startDocument = NULL, | |
140 .endDocument = NULL, | |
141 .startElement = NULL, | |
142 .endElement = NULL, | |
143 .reference = NULL, | |
144 .characters = jabber_parser_element_text_libxml, | |
145 .ignorableWhitespace = NULL, | |
146 .processingInstruction = NULL, | |
147 .comment = NULL, | |
148 .warning = NULL, | |
149 .error = NULL, | |
150 .fatalError = NULL, | |
151 .getParameterEntity = NULL, | |
152 .cdataBlock = NULL, | |
153 .externalSubset = NULL, | |
154 .initialized = XML_SAX2_MAGIC, | |
155 ._private = NULL, | |
156 .startElementNs = jabber_parser_element_start_libxml, | |
157 .endElementNs = jabber_parser_element_end_libxml, | |
158 .serror = NULL | |
159 }; | |
160 | |
161 void | |
162 jabber_parser_setup(JabberStream *js) | |
163 { | |
14476
218a36c1c9e2
[gaim-migrate @ 17194]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14436
diff
changeset
|
164 /* This seems backwards, but it makes sense. The libxml code creates |
218a36c1c9e2
[gaim-migrate @ 17194]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14436
diff
changeset
|
165 * the parser context when you try to use it (this way, it can figure |
218a36c1c9e2
[gaim-migrate @ 17194]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14436
diff
changeset
|
166 * out the encoding at creation time. So, setting up the parser is |
218a36c1c9e2
[gaim-migrate @ 17194]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14436
diff
changeset
|
167 * just a matter of destroying any current parser. */ |
14192 | 168 if (js->context) { |
169 xmlParseChunk(js->context, NULL,0,1); | |
170 xmlFreeParserCtxt(js->context); | |
171 js->context = NULL; | |
172 } | |
173 } | |
174 | |
175 | |
176 void jabber_parser_process(JabberStream *js, const char *buf, int len) | |
177 { | |
178 if (js->context == NULL) { | |
14476
218a36c1c9e2
[gaim-migrate @ 17194]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14436
diff
changeset
|
179 /* libxml inconsistently starts parsing on creating the |
218a36c1c9e2
[gaim-migrate @ 17194]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14436
diff
changeset
|
180 * parser, so do a ParseChunk right afterwards to force it. */ |
14192 | 181 js->context = xmlCreatePushParserCtxt(&jabber_parser_libxml, js, buf, len, NULL); |
14638 | 182 xmlParseChunk(js->context, "", 0, 0); |
14192 | 183 } else if (xmlParseChunk(js->context, buf, len, 0) < 0) { |
184 gaim_connection_error(js->gc, _("XML Parse error")); | |
185 } | |
186 } | |
187 |