tizen 2.3.1 release
[external/gupnp.git] / libgupnp / xml-util.c
1 /*
2  * Copyright (C) 2006, 2007 OpenedHand Ltd.
3  *
4  * Author: Jorn Baayen <jorn@openedhand.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library 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 GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <string.h>
23
24 #include "gvalue-util.h"
25 #include "xml-util.h"
26
27 /* libxml DOM interface helpers */
28 xmlNode *
29 xml_util_get_element (xmlNode *node,
30                       ...)
31 {
32         va_list var_args;
33
34         va_start (var_args, node);
35
36         while (TRUE) {
37                 const char *arg;
38
39                 arg = va_arg (var_args, const char *);
40                 if (!arg)
41                         break;
42
43                 for (node = node->children; node; node = node->next)
44                         if (!g_strcmp0 (arg, (char *) node->name))
45                                 break;
46
47                 if (!node)
48                         break;
49         }
50
51         va_end (var_args);
52
53         return node;
54 }
55
56 xmlChar *
57 xml_util_get_child_element_content (xmlNode    *node,
58                                     const char *child_name)
59 {
60         xmlNode *child_node;
61
62         child_node = xml_util_get_element (node,
63                                            child_name,
64                                            NULL);
65         if (!child_node)
66                 return NULL;
67
68         return xmlNodeGetContent (child_node);
69 }
70
71 int
72 xml_util_get_child_element_content_int (xmlNode    *node,
73                                         const char *child_name)
74 {
75         xmlChar *content;
76         int i;
77
78         content = xml_util_get_child_element_content (node, child_name);
79         if (!content)
80                 return -1;
81
82         i = atoi ((char *) content);
83
84         xmlFree (content);
85
86         return i;
87 }
88
89 char *
90 xml_util_get_child_element_content_glib (xmlNode    *node,
91                                          const char *child_name)
92 {
93         xmlChar *content;
94         char *copy;
95
96         content = xml_util_get_child_element_content (node, child_name);
97         if (!content)
98                 return NULL;
99
100         copy = g_strdup ((char *) content);
101
102         xmlFree (content);
103
104         return copy;
105 }
106
107 SoupURI *
108 xml_util_get_child_element_content_uri (xmlNode    *node,
109                                         const char *child_name,
110                                         SoupURI    *base)
111 {
112         xmlChar *content;
113         SoupURI *uri;
114
115         content = xml_util_get_child_element_content (node, child_name);
116         if (!content)
117                 return NULL;
118
119         if (base != NULL)
120                 uri = soup_uri_new_with_base (base, (const char *) content);
121         else
122                 uri = soup_uri_new ((const char *) content);
123
124         xmlFree (content);
125
126         return uri;
127 }
128
129 char *
130 xml_util_get_child_element_content_url (xmlNode    *node,
131                                         const char *child_name,
132                                         SoupURI    *base)
133 {
134         SoupURI *uri;
135         char *url;
136
137         uri = xml_util_get_child_element_content_uri (node, child_name, base);
138         if (!uri)
139                 return NULL;
140
141         url = soup_uri_to_string (uri, FALSE);
142
143         soup_uri_free (uri);
144
145         return url;
146 }
147
148 xmlChar *
149 xml_util_get_attribute_contents (xmlNode    *node,
150                                  const char *attribute_name)
151 {
152         xmlAttr *attribute;
153
154         for (attribute = node->properties;
155              attribute;
156              attribute = attribute->next) {
157                 if (strcmp (attribute_name, (char *) attribute->name) == 0)
158                         break;
159         }
160
161         if (attribute)
162                 return xmlNodeGetContent (attribute->children);
163         else
164                 return NULL;
165 }
166
167 /**
168  * xml_util_real_node:
169  * @node: an %xmlNodePtr
170  *
171  * Finds the first "real" node (ie, not a comment or whitespace) at or
172  * after @node at its level in the tree.
173  *
174  * Return: a node, or %NULL
175  *
176  * (Taken from libsoup)
177  **/
178 xmlNode *
179 xml_util_real_node (xmlNode *node)
180 {
181         while (node &&
182                (node->type == XML_COMMENT_NODE || xmlIsBlankNode (node)))
183                 node = node->next;
184         return node;
185 }
186
187 /* XML string creation helpers */
188
189 #define INITIAL_XML_STR_SIZE 100 /* Initial xml string size in bytes */
190
191 GString *
192 xml_util_new_string (void)
193 {
194         return g_string_sized_new (INITIAL_XML_STR_SIZE);
195 }
196
197 void
198 xml_util_start_element (GString    *xml_str,
199                         const char *element_name)
200 {
201         g_string_append_c (xml_str, '<');
202         g_string_append (xml_str, element_name);
203         g_string_append_c (xml_str, '>');
204 }
205
206 void
207 xml_util_end_element (GString    *xml_str,
208                       const char *element_name)
209 {
210         g_string_append (xml_str, "</");
211         g_string_append (xml_str, element_name);
212         g_string_append_c (xml_str, '>');
213 }
214
215 void
216 xml_util_add_content (GString    *xml_str,
217                       const char *content)
218 {
219         /* Modified from GLib gmarkup.c */
220         const gchar *p;
221
222         p = content;
223
224         while (*p) {
225                 const gchar *next;
226                 next = g_utf8_next_char (p);
227
228                 switch (*p) {
229                 case '&':
230                         g_string_append (xml_str, "&amp;");
231                         break;
232
233                 case '<':
234                         g_string_append (xml_str, "&lt;");
235                         break;
236
237                 case '>':
238                         g_string_append (xml_str, "&gt;");
239                         break;
240
241                 case '"':
242                         g_string_append (xml_str, "&quot;");
243                         break;
244
245                 default:
246                         g_string_append_len (xml_str, p, next - p);
247                         break;
248                 }
249
250                 p = next;
251         }
252 }