Nyx Node
Loading...
Searching...
No Matches
dom.c
1/* NyxNode
2 * Author: Jérôme ODIER <jerome.odier@lpsc.in2p3.fr>
3 * SPDX-License-Identifier: GPL-2.0-only (Mongoose backend) or GPL-3.0+
4 */
5
6/*--------------------------------------------------------------------------------------------------------------------*/
7#if !defined(ARDUINO)
8/*--------------------------------------------------------------------------------------------------------------------*/
9
10#include <string.h>
11
12#include "nyx_node_internal.h"
13
14/*--------------------------------------------------------------------------------------------------------------------*/
15
16nyx_xmldoc_t *nyx_xmldoc_new(nyx_xml_type_t type)
17{
19
20 memset(result, 0x00, sizeof(nyx_xmldoc_t));
21
22 result->type = type;
23
24 return result;
25}
26
27/*--------------------------------------------------------------------------------------------------------------------*/
28
29static void nyx_xmldoc_delete_all(nyx_xmldoc_t *xmldoc, bool itself, bool children, bool attributes) // NOLINT(*-no-recursion)
30{
31 if(xmldoc == NULL)
32 {
33 return;
34 }
35
36 /*----------------------------------------------------------------------------------------------------------------*/
37 /* REMOVE ATTRIBUTES */
38 /*----------------------------------------------------------------------------------------------------------------*/
39
40 if(attributes)
41 {
42 for(nyx_xmldoc_t *curr_child = xmldoc->attributes, *next_child; curr_child; curr_child = next_child)
43 {
44 next_child = curr_child->next;
45
46 nyx_xmldoc_delete_all(curr_child, true, true, true);
47 }
48
49 xmldoc->attributes = NULL;
50 }
51
52 /*----------------------------------------------------------------------------------------------------------------*/
53 /* REMOVE CHILDREN */
54 /*----------------------------------------------------------------------------------------------------------------*/
55
56 if(children)
57 {
58 for(nyx_xmldoc_t *curr_child = xmldoc->children, *next_child; curr_child; curr_child = next_child)
59 {
60 next_child = curr_child->next;
61
62 nyx_xmldoc_delete_all(curr_child, true, true, true);
63 }
64
65 xmldoc->children = NULL;
66 }
67
68 /*----------------------------------------------------------------------------------------------------------------*/
69 /* REMOVE ITSELF */
70 /*----------------------------------------------------------------------------------------------------------------*/
71
72 if(itself)
73 {
74 nyx_memory_free(xmldoc->name);
75
76 nyx_memory_free(xmldoc->data);
77
78 nyx_memory_free(xmldoc);
79 }
80
81 /*----------------------------------------------------------------------------------------------------------------*/
82}
83
84/*--------------------------------------------------------------------------------------------------------------------*/
85
86void nyx_xmldoc_free(nyx_xmldoc_t *xmldoc) // NOLINT(*-no-recursion)
87{
88 nyx_xmldoc_delete_all(xmldoc, true, true, true);
89}
90
91/*--------------------------------------------------------------------------------------------------------------------*/
92
93str_t nyx_xmldoc_get_name(const nyx_xmldoc_t *xmldoc)
94{
95 return xmldoc->name;
96}
97
98/*--------------------------------------------------------------------------------------------------------------------*/
99
100void nyx_xmldoc_set_name(nyx_xmldoc_t *xmldoc, STR_t name)
101{
102 if(xmldoc->name != NULL)
103 {
104 nyx_memory_free(xmldoc->name);
105 }
106
107 xmldoc->name = nyx_string_dup(name);
108}
109
110/*--------------------------------------------------------------------------------------------------------------------*/
111
112str_t nyx_xmldoc_get_content(const nyx_xmldoc_t *xmldoc)
113{
114 for(nyx_xmldoc_t *curr_child = xmldoc->children, *next_child; curr_child; curr_child = next_child)
115 {
116 next_child = curr_child->next;
117
118 if(curr_child->type == NYX_XML_TEXT
119 ||
120 curr_child->type == NYX_XML_CDATA
121 ) {
122 return curr_child->data;
123 }
124 }
125
126 return NULL;
127}
128
129/*--------------------------------------------------------------------------------------------------------------------*/
130
131void nyx_xmldoc_set_content(nyx_xmldoc_t *xmldoc, STR_t data)
132{
133 nyx_xmldoc_delete_all(xmldoc, false, true, false);
134
135 if(data != NULL)
136 {
137 nyx_xmldoc_t *node = nyx_xmldoc_new(NYX_XML_TEXT);
138
139 node->name = nyx_string_dup("@@");
140 node->data = nyx_string_dup(data);
141
142 nyx_xmldoc_add_child(xmldoc, node);
143 }
144}
145
146/*--------------------------------------------------------------------------------------------------------------------*/
147
148void nyx_xmldoc_add_child(nyx_xmldoc_t *xmldoc, nyx_xmldoc_t *child)
149{
150 if(child == NULL)
151 {
152 return;
153 }
154
155 /*----------------------------------------------------------------------------------------------------------------*/
156
157 if(child->type == NYX_XML_ATTR)
158 {
159 /*------------------------------------------------------------------------------------------------------------*/
160 /* ADD ATTRIBUTE */
161 /*------------------------------------------------------------------------------------------------------------*/
162
163 nyx_xmldoc_t *last_child = xmldoc->attributes;
164
165 if(last_child != NULL)
166 {
167 while(last_child->next != NULL)
168 {
169 last_child = last_child->next;
170 }
171
172 last_child->next = child;
173 }
174 else
175 {
176 xmldoc->attributes = child;
177 }
178
179 /*------------------------------------------------------------------------------------------------------------*/
180 }
181 else
182 {
183 /*------------------------------------------------------------------------------------------------------------*/
184 /* ADD ELEMENT / CDATA / TEXT */
185 /*------------------------------------------------------------------------------------------------------------*/
186
187 nyx_xmldoc_t *last_child = xmldoc->children;
188
189 if(last_child != NULL)
190 {
191 while(last_child->next != NULL)
192 {
193 last_child = last_child->next;
194 }
195
196 last_child->next = child;
197 }
198 else
199 {
200 xmldoc->children = child;
201 }
202
203 /*------------------------------------------------------------------------------------------------------------*/
204 }
205
206 /*----------------------------------------------------------------------------------------------------------------*/
207
208 child->parent = xmldoc;
209
210 /*----------------------------------------------------------------------------------------------------------------*/
211}
212
213/*--------------------------------------------------------------------------------------------------------------------*/
214
215void nyx_xmldoc_add_attribute(nyx_xmldoc_t *xmldoc, STR_t name, STR_t data)
216{
217 if(name != NULL
218 &&
219 data != NULL
220 ) {
221 nyx_xmldoc_t *node = nyx_xmldoc_new(NYX_XML_ATTR);
222
223 node->name = nyx_string_dup(name);
224 node->data = nyx_string_dup(data);
225
226 nyx_xmldoc_add_child(xmldoc, node);
227 }
228}
229
230/*--------------------------------------------------------------------------------------------------------------------*/
231
232__NYX_INLINE__ void to_string_append_attribute(nyx_string_builder_t *sb, const nyx_xmldoc_t *xmldoc)
233{
234 for(nyx_xmldoc_t *curr_child = xmldoc->attributes, *next_child; curr_child; curr_child = next_child)
235 {
236 next_child = curr_child->next;
237
238 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, " ", curr_child->name, "=\"");
239 nyx_string_builder_append(sb, NYX_SB_ESCAPE_XML, curr_child->data);
240 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "\"");
241 }
242}
243
244/*--------------------------------------------------------------------------------------------------------------------*/
245
246__NYX_INLINE__ void to_string_append_content(nyx_string_builder_t *sb, const nyx_xmldoc_t *xmldoc) // NOLINT(*-no-recursion)
247{
248 for(nyx_xmldoc_t *curr_child = xmldoc->children, *next_child; curr_child; curr_child = next_child)
249 {
250 next_child = curr_child->next;
251
252 /*------------------------------------------------------------------------------------------------------------*/
253
254 if(curr_child->type == NYX_XML_ELEM)
255 {
256 str_t node = nyx_xmldoc_to_string(curr_child);
257
258 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, node);
259
260 nyx_memory_free(node);
261 }
262
263 /*------------------------------------------------------------------------------------------------------------*/
264
265 else if(curr_child->type == NYX_XML_COMMENT)
266 {
267 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "<!--", curr_child->data, "-->");
268 }
269 else if(curr_child->type == NYX_XML_CDATA)
270 {
271 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "<![CDATA[", curr_child->data, "]]>");
272 }
273 else if(curr_child->type == NYX_XML_TEXT)
274 {
275 nyx_string_builder_append(sb, NYX_SB_ESCAPE_XML, curr_child->data);
276 }
277
278 /*------------------------------------------------------------------------------------------------------------*/
279 }
280}
281
282/*--------------------------------------------------------------------------------------------------------------------*/
283
284str_t nyx_xmldoc_to_string(const nyx_xmldoc_t *xmldoc) // NOLINT(*-no-recursion)
285{
286 nyx_string_builder_t *sb = nyx_string_builder_new();
287
288 /*----------------------------------------------------------------------------------------------------------------*/
289
290 if(xmldoc->self_closing)
291 {
292 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "<", xmldoc->name); to_string_append_attribute(sb, xmldoc); nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, " />");
293 }
294 else
295 {
296 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "<", xmldoc->name); to_string_append_attribute(sb, xmldoc); nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, ">");
297
298 to_string_append_content(sb, xmldoc);
299
300 nyx_string_builder_append(sb, NYX_SB_NO_ESCAPE, "</", xmldoc->name, ">");
301 }
302
303 /*----------------------------------------------------------------------------------------------------------------*/
304
305 str_t result = nyx_string_builder_to_string(sb);
306
307 nyx_string_builder_free(sb);
308
309 return result;
310
311 /*----------------------------------------------------------------------------------------------------------------*/
312}
313
314/*--------------------------------------------------------------------------------------------------------------------*/
315#endif
316/*--------------------------------------------------------------------------------------------------------------------*/
#define STR_t
Alias for const char *.
Definition nyx_node.h:71
__NYX_NULLABLE__ buff_t nyx_memory_alloc(__NYX_ZEROABLE__ size_t size)
Similar to libc malloc except that a memory overflow causes the node to stop.
__NYX_ZEROABLE__ size_t nyx_memory_free(__NYX_NULLABLE__ buff_t buff)
Similar to libc free except that it returns the amount of memory freed.
__NYX_NULLABLE__ str_t nyx_string_dup(__NYX_NULLABLE__ STR_t s)
Similar to libc strdup.
#define str_t
Alias for char *.
Definition nyx_node.h:70
Struct describing an XML document.