File Coverage

src/xh_xml.h
Criterion Covered Total %
statement 67 79 84.8
branch 48 78 61.5
condition n/a
subroutine n/a
pod n/a
total 115 157 73.2


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 32           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 32           buf = &writer->main_buf;
40 32 100         content = XH_CHAR_CAST SvPV(value, content_len);
41              
42 32 100         if (writer->trim && content_len) {
    50          
43 1           content = xh_str_trim(content, &content_len);
44             }
45              
46 32 100         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 25 100         XH_WRITER_RESIZE_BUFFER(writer, buf, name_len * 2 + 10 + (raw ? content_len : content_len * 5))
    50          
    0          
60             }
61              
62 32           XH_BUFFER_WRITE_CHAR(buf, '<')
63              
64 32 50         if (name[0] >= '0' && name[0] <= '9') {
    100          
65 1           XH_BUFFER_WRITE_CHAR(buf, '_')
66             }
67              
68 32           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
69              
70 32           XH_BUFFER_WRITE_CHAR(buf, '>')
71              
72 32 100         if (raw) {
73 1           XH_BUFFER_WRITE_LONG_STRING(buf, content, content_len)
74             }
75             else {
76 169 100         XH_BUFFER_WRITE_ESCAPE_STRING(buf, content, content_len)
77             }
78              
79 32           XH_BUFFER_WRITE_CHAR2(buf, "
80              
81 32 50         if (name[0] >= '0' && name[0] <= '9') {
    100          
82 1           XH_BUFFER_WRITE_CHAR(buf, '_')
83             }
84              
85 32           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
86              
87 32           XH_BUFFER_WRITE_CHAR(buf, '>')
88              
89 32 100         if (writer->indent) {
90 7           XH_BUFFER_WRITE_CHAR(buf, '\n')
91             }
92 32           }
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 0           indent_len = writer->indent_count * writer->indent;
104 0 0         if (indent_len > sizeof(indent_string)) {
105 0           indent_len = sizeof(indent_string);
106             }
107              
108             /* "" + "\n" */
109 0 0         XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len + 5)
110              
111 0           XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
112             }
113             else {
114             /* "" + "\n" */
115 1 50         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 0           XH_BUFFER_WRITE_CHAR(buf, '\n')
130             }
131 1           }
132              
133             XH_INLINE void
134 24           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 24           buf = &writer->main_buf;
140              
141 24 100         if (writer->indent) {
142 4           indent_len = writer->indent_count++ * writer->indent;
143 4 50         if (indent_len > sizeof(indent_string)) {
144 0           indent_len = sizeof(indent_string);
145             }
146              
147             /* "" + "\n" */
148 4 50         XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len + 5)
149              
150 4           XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
151             }
152             else {
153             /* "" + "\n" */
154 20 50         XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + 5)
155             }
156              
157 24           XH_BUFFER_WRITE_CHAR(buf, '<')
158              
159 24 50         if (name[0] >= '0' && name[0] <= '9') {
    50          
160 0           XH_BUFFER_WRITE_CHAR(buf, '_')
161             }
162              
163 24           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
164              
165 24           XH_BUFFER_WRITE_CHAR(buf, '>')
166              
167 24 100         if (writer->indent) {
168 4           XH_BUFFER_WRITE_CHAR(buf, '\n')
169             }
170 24           }
171              
172             XH_INLINE void
173 24           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 24           buf = &writer->main_buf;
179              
180 24 100         if (writer->indent) {
181 4           indent_len = --writer->indent_count * writer->indent;
182 4 50         if (indent_len > sizeof(indent_string)) {
183 0           indent_len = sizeof(indent_string);
184             }
185              
186             /* "" + "\n" */
187 4 50         XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len + 5)
188              
189 4           XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
190             }
191             else {
192             /* "" + "\n" */
193 20 50         XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + 5)
194             }
195              
196 24           XH_BUFFER_WRITE_CHAR2(buf, "
197              
198 24 50         if (name[0] >= '0' && name[0] <= '9') {
    50          
199 0           XH_BUFFER_WRITE_CHAR(buf, '_')
200             }
201              
202 24           XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
203              
204 24           XH_BUFFER_WRITE_CHAR(buf, '>')
205              
206 24 100         if (writer->indent) {
207 4           XH_BUFFER_WRITE_CHAR(buf, '\n')
208             }
209 24           }
210              
211             XH_INLINE void
212             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             buf = &writer->main_buf;
221             content = XH_CHAR_CAST SvPV(value, str_len);
222             content_len = str_len;
223              
224             if (writer->trim) {
225             content = xh_str_trim(content, &content_len);
226             }
227              
228             if (writer->indent) {
229             indent_len = writer->indent_count * writer->indent;
230             if (indent_len > sizeof(indent_string)) {
231             indent_len = sizeof(indent_string);
232             }
233              
234             XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + content_len * 5)
235              
236             XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
237             }
238             else {
239             XH_WRITER_RESIZE_BUFFER(writer, buf, content_len * 5)
240             }
241              
242             XH_BUFFER_WRITE_ESCAPE_STRING(buf, content, content_len);
243              
244             if (writer->indent) {
245             XH_BUFFER_WRITE_CHAR(buf, '\n')
246             }
247             }
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             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             buf = &writer->main_buf;
354              
355             if (writer->indent) {
356             indent_len = writer->indent_count * writer->indent;
357             if (indent_len > sizeof(indent_string)) {
358             indent_len = sizeof(indent_string);
359             }
360              
361             /* "<" + "_" */
362             XH_WRITER_RESIZE_BUFFER(writer, buf, indent_len + name_len + 2)
363              
364             XH_BUFFER_WRITE_LONG_STRING(buf, indent_string, indent_len);
365             }
366             else {
367             /* "<" + "_" */
368             XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + 2)
369             }
370              
371             XH_BUFFER_WRITE_CHAR(buf, '<')
372              
373             if (name[0] >= '0' && name[0] <= '9') {
374             XH_BUFFER_WRITE_CHAR(buf, '_')
375             }
376              
377             XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
378             }
379              
380             XH_INLINE void
381             xh_xml_write_end_tag(xh_writer_t *writer)
382             {
383             xh_perl_buffer_t *buf;
384              
385             buf = &writer->main_buf;
386              
387             XH_WRITER_RESIZE_BUFFER(writer, buf, 2)
388              
389             if (writer->indent) {
390             XH_BUFFER_WRITE_CHAR2(buf, ">\n");
391             writer->indent_count++;
392             }
393             else {
394             XH_BUFFER_WRITE_CHAR(buf, '>')
395             }
396             }
397              
398             XH_INLINE void
399             xh_xml_write_closed_end_tag(xh_writer_t *writer)
400             {
401             xh_perl_buffer_t *buf;
402              
403             buf = &writer->main_buf;
404              
405             XH_WRITER_RESIZE_BUFFER(writer, buf, 3)
406              
407             if (writer->indent) {
408             XH_BUFFER_WRITE_CHAR3(buf, "/>\n");
409             }
410             else {
411             XH_BUFFER_WRITE_CHAR2(buf, "/>");
412             }
413             }
414              
415             XH_INLINE void
416             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             buf = &writer->main_buf;
424              
425             if (value == NULL) {
426             content = XH_EMPTY_STRING;
427             content_len = 0;
428             }
429             else {
430             content = XH_CHAR_CAST SvPV(value, str_len);
431             content_len = str_len;
432             }
433              
434             /* ' =""' */
435             XH_WRITER_RESIZE_BUFFER(writer, buf, name_len + content_len * 6 + 4)
436              
437             XH_BUFFER_WRITE_CHAR(buf, ' ')
438              
439             XH_BUFFER_WRITE_LONG_STRING(buf, name, name_len)
440              
441             if (content_len == 0) {
442             XH_BUFFER_WRITE_CHAR3(buf, "=\"\"");
443             }
444             else {
445             XH_BUFFER_WRITE_CHAR2(buf, "=\"");
446             XH_BUFFER_WRITE_ESCAPE_ATTR(buf, content, content_len);
447             XH_BUFFER_WRITE_CHAR(buf, '"');
448             }
449             }
450              
451             #endif /* _XH_XML_H_ */