1 /*
2  * libwbxml, the WBXML Library.
3  * Copyright (C) 2002-2008 Aymerick Jehanne <aymerick@jehanne.org>
4  * Copyright (C) 2011 Michael Bell <michael.bell@opensync.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 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  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt
21  *
22  * Contact: aymerick@jehanne.org
23  * Home: http://libwbxml.aymerick.com
24  */
25 
26 /**
27  * @file wbxml_elt.c
28  * @ingroup wbxml_elt
29  *
30  * @author Aymerick Jehanne <aymerick@jehanne.org>
31  * @date 03/02/22
32  *
33  * @brief WBXML Elements
34  */
35 
36 #include "wbxml_elt.h"
37 
38 
39 /** For an unknown XML Name */
40 #define WBXML_ELT_UNKNOWN_NAME ((WB_UTINY *)"unknown")
41 
42 
43 
44 /***************************************************
45  *    Public Functions
46  */
47 
48 /* WBXMLTag */
49 
wbxml_tag_create(WBXMLValueType type)50 WBXML_DECLARE(WBXMLTag *) wbxml_tag_create(WBXMLValueType type)
51 {
52     WBXMLTag *result = NULL;
53 
54     if ((result = wbxml_malloc(sizeof(WBXMLTag))) == NULL)
55         return NULL;
56 
57     result->type = type;
58     result->u.token = NULL;
59     result->u.literal = NULL;
60 
61     return result;
62 }
63 
64 
wbxml_tag_create_token(const WBXMLTagEntry * value)65 WBXML_DECLARE(WBXMLTag *) wbxml_tag_create_token(const WBXMLTagEntry *value)
66 {
67     WBXMLTag *result = NULL;
68 
69     if ((result = wbxml_tag_create(WBXML_VALUE_TOKEN)) == NULL)
70         return NULL;
71 
72     result->u.token = value;
73 
74     return result;
75 }
76 
77 
wbxml_tag_create_literal(WB_UTINY * value)78 WBXML_DECLARE(WBXMLTag *) wbxml_tag_create_literal(WB_UTINY *value)
79 {
80     WBXMLTag *result = NULL;
81 
82     if ((result = wbxml_tag_create(WBXML_VALUE_LITERAL)) == NULL)
83         return NULL;
84 
85     if (value == NULL)
86         result->u.literal = NULL;
87     else {
88         result->u.literal = wbxml_buffer_create(value, WBXML_STRLEN(value), WBXML_STRLEN(value));
89         if (result->u.literal == NULL) {
90             wbxml_tag_destroy(result);
91             return NULL;
92         }
93     }
94 
95     return result;
96 }
97 
98 
wbxml_tag_destroy(WBXMLTag * tag)99 WBXML_DECLARE(void) wbxml_tag_destroy(WBXMLTag *tag)
100 {
101     if (tag == NULL)
102         return;
103 
104     if (tag->type == WBXML_VALUE_LITERAL)
105         wbxml_buffer_destroy(tag->u.literal);
106 
107     wbxml_free(tag);
108 }
109 
110 
wbxml_tag_duplicate(WBXMLTag * tag)111 WBXML_DECLARE(WBXMLTag *) wbxml_tag_duplicate(WBXMLTag *tag)
112 {
113     WBXMLTag *result = NULL;
114 
115     if (tag == NULL)
116         return NULL;
117 
118     if ((result = wbxml_malloc(sizeof(WBXMLTag))) == NULL)
119         return NULL;
120 
121     result->type = tag->type;
122 
123     switch (result->type) {
124     case WBXML_VALUE_TOKEN:
125         result->u.token = tag->u.token;
126         break;
127     case WBXML_VALUE_LITERAL:
128         result->u.literal = wbxml_buffer_duplicate(tag->u.literal);
129         break;
130     default:
131         /* Must Never Happen ! */
132         wbxml_free(result);
133         return NULL;
134     }
135 
136     return result;
137 }
138 
139 
wbxml_tag_get_xml_name(WBXMLTag * tag)140 WBXML_DECLARE(const WB_UTINY *) wbxml_tag_get_xml_name(WBXMLTag *tag)
141 {
142     if (tag == NULL)
143         return WBXML_ELT_UNKNOWN_NAME;
144 
145     switch (tag->type) {
146     case WBXML_VALUE_TOKEN:
147         return (const WB_UTINY *) tag->u.token->xmlName;
148         break;
149     case WBXML_VALUE_LITERAL:
150         return (const WB_UTINY *) wbxml_buffer_get_cstr(tag->u.literal);
151     default:
152         return WBXML_ELT_UNKNOWN_NAME;
153     }
154 }
155 
156 
157 /* WBXMLAttributeName */
158 
wbxml_attribute_name_create(WBXMLValueType type)159 WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create(WBXMLValueType type)
160 {
161     WBXMLAttributeName *result = NULL;
162 
163     if ((result = wbxml_malloc(sizeof(WBXMLAttributeName))) == NULL)
164         return NULL;
165 
166     result->type = type;
167     result->u.token = NULL;
168     result->u.literal = NULL;
169 
170     return result;
171 }
172 
173 
wbxml_attribute_name_create_token(const WBXMLAttrEntry * value)174 WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create_token(const WBXMLAttrEntry *value)
175 {
176     WBXMLAttributeName *result = NULL;
177 
178     if ((result = wbxml_attribute_name_create(WBXML_VALUE_TOKEN)) == NULL)
179         return NULL;
180 
181     result->u.token = value;
182 
183     return result;
184 }
185 
186 
wbxml_attribute_name_create_literal(WB_UTINY * value)187 WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create_literal(WB_UTINY *value)
188 {
189     WBXMLAttributeName *result = NULL;
190 
191     if ((result = wbxml_attribute_name_create(WBXML_VALUE_LITERAL)) == NULL)
192         return NULL;
193 
194     if (value == NULL)
195         result->u.literal = NULL;
196     else {
197         result->u.literal = wbxml_buffer_create(value, WBXML_STRLEN(value), WBXML_STRLEN(value));
198         if (result->u.literal == NULL) {
199             wbxml_attribute_name_destroy(result);
200             return NULL;
201         }
202     }
203 
204     return result;
205 }
206 
207 
wbxml_attribute_name_destroy(WBXMLAttributeName * name)208 WBXML_DECLARE(void) wbxml_attribute_name_destroy(WBXMLAttributeName *name)
209 {
210     if (name == NULL)
211         return;
212 
213     if (name->type == WBXML_VALUE_LITERAL)
214         wbxml_buffer_destroy(name->u.literal);
215 
216     wbxml_free(name);
217 }
218 
219 
wbxml_attribute_name_duplicate(WBXMLAttributeName * name)220 WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_duplicate(WBXMLAttributeName *name)
221 {
222     WBXMLAttributeName *result = NULL;
223 
224     if (name == NULL)
225         return NULL;
226 
227     if ((result = wbxml_malloc(sizeof(WBXMLAttributeName))) == NULL)
228         return NULL;
229 
230     result->type = name->type;
231 
232     switch (result->type) {
233     case WBXML_VALUE_TOKEN:
234         result->u.token = name->u.token;
235         break;
236     case WBXML_VALUE_LITERAL:
237         result->u.literal = wbxml_buffer_duplicate(name->u.literal);
238         break;
239     default:
240         /* Must Never Happen ! */
241         wbxml_free(result);
242         return NULL;
243     }
244 
245     return result;
246 }
247 
248 
wbxml_attribute_name_get_xml_name(WBXMLAttributeName * name)249 WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_name_get_xml_name(WBXMLAttributeName *name)
250 {
251     if (name == NULL)
252         return WBXML_ELT_UNKNOWN_NAME;
253 
254     switch (name->type) {
255     case WBXML_VALUE_TOKEN:
256         return (const WB_UTINY *) name->u.token->xmlName;
257         break;
258     case WBXML_VALUE_LITERAL:
259         return (const WB_UTINY *) wbxml_buffer_get_cstr(name->u.literal);
260     default:
261         return WBXML_ELT_UNKNOWN_NAME;
262     }
263 }
264 
265 
266 /* WBXMLAttribute */
267 
wbxml_attribute_create(void)268 WBXML_DECLARE(WBXMLAttribute *) wbxml_attribute_create(void)
269 {
270     WBXMLAttribute *result = NULL;
271 
272     if ((result = wbxml_malloc(sizeof(WBXMLAttribute))) == NULL)
273         return NULL;
274 
275     result->name = NULL;
276     result->value = NULL;
277 
278     return result;
279 }
280 
281 
wbxml_attribute_destroy(WBXMLAttribute * attr)282 WBXML_DECLARE(void) wbxml_attribute_destroy(WBXMLAttribute *attr)
283 {
284     if (attr == NULL)
285         return;
286 
287     wbxml_attribute_name_destroy(attr->name);
288     wbxml_buffer_destroy(attr->value);
289 
290     wbxml_free(attr);
291 }
292 
293 
wbxml_attribute_destroy_item(void * attr)294 WBXML_DECLARE_NONSTD(void) wbxml_attribute_destroy_item(void *attr)
295 {
296     wbxml_attribute_destroy((WBXMLAttribute *) attr);
297 }
298 
299 
wbxml_attribute_duplicate(WBXMLAttribute * attr)300 WBXML_DECLARE(WBXMLAttribute *) wbxml_attribute_duplicate(WBXMLAttribute *attr)
301 {
302     WBXMLAttribute *result = NULL;
303 
304     if (attr == NULL)
305         return NULL;
306 
307     if ((result = wbxml_malloc(sizeof(WBXMLAttribute))) == NULL)
308         return NULL;
309 
310     result->name = wbxml_attribute_name_duplicate(attr->name);
311     result->value = wbxml_buffer_duplicate(attr->value);
312 
313     return result;
314 }
315 
316 
wbxml_attribute_get_xml_name(WBXMLAttribute * attr)317 WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_get_xml_name(WBXMLAttribute *attr)
318 {
319     if (attr == NULL)
320         return WBXML_ELT_UNKNOWN_NAME;
321 
322     return wbxml_attribute_name_get_xml_name(attr->name);
323 }
324 
325 
wbxml_attribute_get_xml_value(WBXMLAttribute * attr)326 WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_get_xml_value(WBXMLAttribute *attr)
327 {
328     if ((attr == NULL) || (attr->value == NULL))
329         return WBXML_UTINY_NULL_STRING;
330 
331     return wbxml_buffer_get_cstr(attr->value);
332 }
333