File Coverage

src/xh_xml.h
Criterion Covered Total %
statement 101 124 81.4
branch 46 104 44.2
condition n/a
subroutine n/a
pod n/a
total 147 228 64.4


line stmt bran cond sub pod time code
1             #ifndef _XH_XML_H_
2             #define _XH_XML_H_
3              
4             #include "xh_config.h"
5             #include "xh_core.h"
6              
7             static const xh_char_t indent_string[60] = " ";
8              
9             XH_INLINE void
10             xh_xml_write_xml_declaration(xh_writer_t *writer, xh_char_t *version, xh_char_t *encoding)
11             {
12             xh_perl_buffer_t *buf;
13             size_t ver_len, enc_len;
14              
15             buf = &writer->main_buf;
16             ver_len = xh_strlen(version);
17             if (encoding[0] == '\0')
18             encoding = XH_CHAR_CAST XH_INTERNAL_ENCODING;
19             enc_len = xh_strlen(encoding);
20              
21             XH_WRITER_RESIZE_BUFFER(writer, buf, sizeof("\n") - 1 + ver_len * 6 + enc_len * 6)
22              
23             XH_BUFFER_WRITE_CONSTANT(buf, "
24             XH_BUFFER_WRITE_ESCAPE_ATTR(buf, version, ver_len);
25             XH_BUFFER_WRITE_CONSTANT(buf, "\" encoding=\"")
26             XH_BUFFER_WRITE_ESCAPE_ATTR(buf, encoding, enc_len);
27             XH_BUFFER_WRITE_CHAR4(buf, "\"?>\n");
28              
29             }
30              
31             XH_INLINE void
32 7           xh_xml_write_node(xh_writer_t *writer, xh_char_t *name, size_t name_len, SV *value, xh_bool_t raw)
33             {
34             size_t indent_len;
35             xh_perl_buffer_t *buf;
36             xh_char_t *content;
37             STRLEN content_len;
38              
39 7           buf = &writer->main_buf;
40 7           content = XH_CHAR_CAST SvPV(value, content_len);
41              
42 7 50         if (writer->trim && content_len) {
    0          
43 0           content = xh_str_trim(content, &content_len);
44             }
45              
46 7 50         if (writer->indent) {
47 7           indent_len = writer->indent_count * writer->indent;
48 7 50         if (indent_len > sizeof(indent_string)) {
49 0           indent_len = sizeof(indent_string);
50             }
51              
52             /* "" + "\n" */
53 7 50         XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len * 2 + 10 + (raw ? content_len : content_len * 5))
    50          
    0          
54              
55 7           XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
56             }
57             else {
58             /* "" + "\n" */
59 0 0         XH_WRITER_RESIZE_BUFFER(writer, buf, name_len * 2 + 10 + (raw ? content_len : content_len * 5))
    0          
    0          
60             }
61              
62 7           XH_BUFFER_WRITE_CHAR(buf, '<')
63              
64 7 50         if (name[0] >= '0' && name[0] <= '9') {
    50          
65 0           XH_BUFFER_WRITE_CHAR(buf, '_')
66             }
67              
68 7           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
69              
70 7           XH_BUFFER_WRITE_CHAR(buf, '>')
71              
72 7 50         if (raw) {
73 0           XH_BUFFER_WRITE_LONG_STRING(buf, content, content_len)
74             }
75             else {
76 18 100         XH_BUFFER_WRITE_ESCAPE_STRING(buf, content, content_len)
77             }
78              
79 7           XH_BUFFER_WRITE_CHAR2(buf, "
80              
81 7 50         if (name[0] >= '0' && name[0] <= '9') {
    50          
82 0           XH_BUFFER_WRITE_CHAR(buf, '_')
83             }
84              
85 7           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
86              
87 7           XH_BUFFER_WRITE_CHAR(buf, '>')
88              
89 7 50         if (writer->indent) {
90 7           XH_BUFFER_WRITE_CHAR(buf, '\n')
91             }
92 7           }
93              
94             XH_INLINE void
95 1           xh_xml_write_empty_node(xh_writer_t *writer, xh_char_t *name, size_t name_len)
96             {
97             size_t indent_len;
98             xh_perl_buffer_t *buf;
99              
100 1           buf = &writer->main_buf;
101              
102 1 50         if (writer->indent) {
103 1           indent_len = writer->indent_count * writer->indent;
104 1 50         if (indent_len > sizeof(indent_string)) {
105 0           indent_len = sizeof(indent_string);
106             }
107              
108             /* "" + "\n" */
109 1 50         XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len + 5)
110              
111 1           XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
112             }
113             else {
114             /* "" + "\n" */
115 0 0         XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + 5)
116             }
117              
118 1           XH_BUFFER_WRITE_CHAR(buf, '<')
119              
120 1 50         if (name[0] >= '0' && name[0] <= '9') {
    50          
121 0           XH_BUFFER_WRITE_CHAR(buf, '_')
122             }
123              
124 1           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
125              
126 1           XH_BUFFER_WRITE_CHAR2(buf, "/>")
127              
128 1 50         if (writer->indent) {
129 1           XH_BUFFER_WRITE_CHAR(buf, '\n')
130             }
131 1           }
132              
133             XH_INLINE void
134             xh_xml_write_start_node(xh_writer_t *writer, xh_char_t *name, size_t name_len)
135             {
136             size_t indent_len;
137             xh_perl_buffer_t *buf;
138              
139             buf = &writer->main_buf;
140              
141             if (writer->indent) {
142             indent_len = writer->indent_count++ * writer->indent;
143             if (indent_len > sizeof(indent_string)) {
144             indent_len = sizeof(indent_string);
145             }
146              
147             /* "" + "\n" */
148             XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len + 5)
149              
150             XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
151             }
152             else {
153             /* "" + "\n" */
154             XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + 5)
155             }
156              
157             XH_BUFFER_WRITE_CHAR(buf, '<')
158              
159             if (name[0] >= '0' && name[0] <= '9') {
160             XH_BUFFER_WRITE_CHAR(buf, '_')
161             }
162              
163             XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
164              
165             XH_BUFFER_WRITE_CHAR(buf, '>')
166              
167             if (writer->indent) {
168             XH_BUFFER_WRITE_CHAR(buf, '\n')
169             }
170             }
171              
172             XH_INLINE void
173 6           xh_xml_write_end_node(xh_writer_t *writer, xh_char_t *name, size_t name_len)
174             {
175             size_t indent_len;
176             xh_perl_buffer_t *buf;
177              
178 6           buf = &writer->main_buf;
179              
180 6 50         if (writer->indent) {
181 6           indent_len = --writer->indent_count * writer->indent;
182 6 50         if (indent_len > sizeof(indent_string)) {
183 0           indent_len = sizeof(indent_string);
184             }
185              
186             /* "" + "\n" */
187 6 50         XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len + 5)
188              
189 6           XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
190             }
191             else {
192             /* "" + "\n" */
193 0 0         XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + 5)
194             }
195              
196 6           XH_BUFFER_WRITE_CHAR2(buf, "
197              
198 6 50         if (name[0] >= '0' && name[0] <= '9') {
    50          
199 0           XH_BUFFER_WRITE_CHAR(buf, '_')
200             }
201              
202 6           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
203              
204 6           XH_BUFFER_WRITE_CHAR(buf, '>')
205              
206 6 50         if (writer->indent) {
207 6           XH_BUFFER_WRITE_CHAR(buf, '\n')
208             }
209 6           }
210              
211             XH_INLINE void
212 4           xh_xml_write_content(xh_writer_t *writer, SV *value)
213             {
214             size_t indent_len;
215             xh_perl_buffer_t *buf;
216             xh_char_t *content;
217             size_t content_len;
218             STRLEN str_len;
219              
220 4           buf = &writer->main_buf;
221 4           content = XH_CHAR_CAST SvPV(value, str_len);
222 4           content_len = str_len;
223              
224 4 50         if (writer->trim) {
225 0           content = xh_str_trim(content, &content_len);
226             }
227              
228 4 50         if (writer->indent) {
229 4           indent_len = writer->indent_count * writer->indent;
230 4 50         if (indent_len > sizeof(indent_string)) {
231 0           indent_len = sizeof(indent_string);
232             }
233              
234 4 50         XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + content_len * 5)
235              
236 4           XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
237             }
238             else {
239 0 0         XH_WRITER_RESIZE_BUFFER(writer, buf, content_len * 5)
240             }
241              
242 45 100         XH_BUFFER_WRITE_ESCAPE_STRING(buf, content, content_len);
243              
244 4 50         if (writer->indent) {
245 4           XH_BUFFER_WRITE_CHAR(buf, '\n')
246             }
247 4           }
248              
249             XH_INLINE void
250             xh_xml_write_comment(xh_writer_t *writer, SV *value)
251             {
252             size_t indent_len;
253             xh_perl_buffer_t *buf;
254             xh_char_t *content;
255             size_t content_len;
256             STRLEN str_len;
257              
258             buf = &writer->main_buf;
259              
260             if (value == NULL) {
261             content = XH_EMPTY_STRING;
262             content_len = 0;
263             }
264             else {
265             content = XH_CHAR_CAST SvPV(value, str_len);
266             content_len = str_len;
267             }
268              
269             if (writer->trim && content_len) {
270             content = xh_str_trim(content, &content_len);
271             }
272              
273             if (writer->indent) {
274             indent_len = writer->indent_count * writer->indent;
275             if (indent_len > sizeof(indent_string)) {
276             indent_len = sizeof(indent_string);
277             }
278              
279             /* "" */
280             XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + content_len + 7)
281              
282             XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
283             }
284             else {
285             /* "" */
286             XH_WRITER_RESIZE_BUFFER(writer, buf, content_len + 7)
287             }
288              
289             XH_BUFFER_WRITE_CHAR4(buf, "")
292              
293             if (writer->indent) {
294             XH_BUFFER_WRITE_CHAR(buf, '\n')
295             }
296             }
297              
298             XH_INLINE void
299             xh_xml_write_cdata(xh_writer_t *writer, SV *value)
300             {
301             size_t indent_len;
302             xh_perl_buffer_t *buf;
303             xh_char_t *content;
304             size_t content_len;
305             STRLEN str_len;
306              
307             buf = &writer->main_buf;
308              
309             if (value == NULL) {
310             content = XH_EMPTY_STRING;
311             content_len = 0;
312             }
313             else {
314             content = XH_CHAR_CAST SvPV(value, str_len);
315             content_len = str_len;
316             }
317              
318             if (writer->trim && content_len) {
319             content = xh_str_trim(content, &content_len);
320             }
321              
322             if (writer->indent) {
323             indent_len = writer->indent_count * writer->indent;
324             if (indent_len > sizeof(indent_string)) {
325             indent_len = sizeof(indent_string);
326             }
327              
328             /* "" */
329             XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + content_len + 12)
330              
331             XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
332             }
333             else {
334             /* "" */
335             XH_WRITER_RESIZE_BUFFER(writer, buf, content_len + 12)
336             }
337              
338             XH_BUFFER_WRITE_CHAR9(buf, "
339             XH_BUFFER_WRITE_LONG_STRING(buf, content, content_len);
340             XH_BUFFER_WRITE_CHAR3(buf, "]]>")
341              
342             if (writer->indent) {
343             XH_BUFFER_WRITE_CHAR(buf, '\n')
344             }
345             }
346              
347             XH_INLINE void
348 12           xh_xml_write_start_tag(xh_writer_t *writer, xh_char_t *name, size_t name_len)
349             {
350             size_t indent_len;
351             xh_perl_buffer_t *buf;
352              
353 12           buf = &writer->main_buf;
354              
355 12 50         if (writer->indent) {
356 12           indent_len = writer->indent_count * writer->indent;
357 12 50         if (indent_len > sizeof(indent_string)) {
358 0           indent_len = sizeof(indent_string);
359             }
360              
361             /* "<" + "_" */
362 12 50         XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len + 2)
363              
364 12           XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
365             }
366             else {
367             /* "<" + "_" */
368 0 0         XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + 2)
369             }
370              
371 12           XH_BUFFER_WRITE_CHAR(buf, '<')
372              
373 12 50         if (name[0] >= '0' && name[0] <= '9') {
    50          
374 0           XH_BUFFER_WRITE_CHAR(buf, '_')
375             }
376              
377 12           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
378 12           }
379              
380             XH_INLINE void
381 6           xh_xml_write_end_tag(xh_writer_t *writer)
382             {
383             xh_perl_buffer_t *buf;
384              
385 6           buf = &writer->main_buf;
386              
387 6 50         XH_WRITER_RESIZE_BUFFER(writer, buf, 2)
388              
389 6 50         if (writer->indent) {
390 6           XH_BUFFER_WRITE_CHAR2(buf, ">\n");
391 6           writer->indent_count++;
392             }
393             else {
394 0           XH_BUFFER_WRITE_CHAR(buf, '>')
395             }
396 6           }
397              
398             XH_INLINE void
399 6           xh_xml_write_closed_end_tag(xh_writer_t *writer)
400             {
401             xh_perl_buffer_t *buf;
402              
403 6           buf = &writer->main_buf;
404              
405 6 50         XH_WRITER_RESIZE_BUFFER(writer, buf, 3)
406              
407 6 50         if (writer->indent) {
408 6           XH_BUFFER_WRITE_CHAR3(buf, "/>\n");
409             }
410             else {
411 0           XH_BUFFER_WRITE_CHAR2(buf, "/>");
412             }
413 6           }
414              
415             XH_INLINE void
416 11           xh_xml_write_attribute(xh_writer_t *writer, xh_char_t *name, size_t name_len, SV *value)
417             {
418             xh_perl_buffer_t *buf;
419             xh_char_t *content;
420             size_t content_len;
421             STRLEN str_len;
422              
423 11           buf = &writer->main_buf;
424              
425 11 50         if (value == NULL) {
426 0           content = XH_EMPTY_STRING;
427 0           content_len = 0;
428             }
429             else {
430 11           content = XH_CHAR_CAST SvPV(value, str_len);
431 11           content_len = str_len;
432             }
433              
434             /* ' =""' */
435 11 50         XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + content_len * 6 + 4)
436              
437 11           XH_BUFFER_WRITE_CHAR(buf, ' ')
438              
439 11           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
440              
441 11 50         if (content_len == 0) {
442 0           XH_BUFFER_WRITE_CHAR3(buf, "=\"\"");
443             }
444             else {
445 11           XH_BUFFER_WRITE_CHAR2(buf, "=\"");
446 89 100         XH_BUFFER_WRITE_ESCAPE_ATTR(buf, content, content_len);
447 11           XH_BUFFER_WRITE_CHAR(buf, '"');
448             }
449 11           }
450              
451             #endif /* _XH_XML_H_ */