File Coverage

src/xh_h2x_lx.c
Criterion Covered Total %
statement 53 59 89.8
branch 52 62 83.8
condition n/a
subroutine n/a
pod n/a
total 105 121 86.7


line stmt bran cond sub pod time code
1             #include "xh_config.h"
2             #include "xh_core.h"
3              
4             XH_INLINE void
5 27           _xh_h2x_lx_write_complex_node(xh_h2x_ctx_t *ctx, xh_char_t *key, I32 key_len, SV *value)
6             {
7             /* '
8 27           xh_xml_write_start_tag(&ctx->writer, key, key_len);
9             /* ' attr1="..." attr2="..."' */
10 27           xh_h2x_lx(ctx, value, key, key_len, XH_H2X_F_ATTR_ONLY);
11             /* '>' */
12 27           xh_xml_write_end_tag(&ctx->writer);
13              
14 27           xh_h2x_lx(ctx, value, key, key_len, XH_H2X_F_NONE);
15              
16 27           xh_xml_write_end_node(&ctx->writer, key, key_len);
17 27           }
18              
19             XH_INLINE void
20 49           _xh_h2x_lx(xh_h2x_ctx_t *ctx, xh_char_t *key, I32 key_len, SV *value, xh_int_t flag)
21             {
22             xh_uint_t type;
23              
24 49           value = xh_h2x_resolve_value(ctx, value, &type);
25              
26 49 100         if (ctx->opts.cdata[0] != '\0' && xh_strcmp(key, ctx->opts.cdata) == 0) {
    100          
27 19 100         if (flag & XH_H2X_F_ATTR_ONLY || !(type & XH_H2X_T_SCALAR)) return;
    100          
28 1           xh_xml_write_cdata(&ctx->writer, value);
29             }
30 45 50         else if (ctx->opts.text[0] != '\0' && xh_strcmp(key, ctx->opts.text) == 0) {
    100          
31 4 100         if (flag & XH_H2X_F_ATTR_ONLY || !(type & XH_H2X_T_SCALAR)) return;
    50          
32 2           xh_xml_write_content(&ctx->writer, value);
33             }
34 41 100         else if (ctx->opts.comm[0] != '\0' && xh_strcmp(key, ctx->opts.comm) == 0) {
    100          
35 4 100         if (flag & XH_H2X_F_ATTR_ONLY) return;
36              
37 4 100         if (type & XH_H2X_T_SCALAR) {
38 1           xh_xml_write_comment(&ctx->writer, value);
39             }
40             else {
41 1           xh_xml_write_comment(&ctx->writer, NULL);
42             }
43             }
44 37 50         else if (ctx->opts.attr[0] != '\0') {
45 37 100         if (xh_strncmp(key, ctx->opts.attr, ctx->opts.attr_len) == 0) {
46 8 100         if (!(flag & XH_H2X_F_ATTR_ONLY)) return;
47              
48 4           key += ctx->opts.attr_len;
49 4           key_len -= ctx->opts.attr_len;
50              
51 4 100         if (type & XH_H2X_T_SCALAR) {
52 3           xh_xml_write_attribute(&ctx->writer, key, key_len, value);
53             }
54             else {
55 4           xh_xml_write_attribute(&ctx->writer, key, key_len, NULL);
56             }
57             }
58             else {
59 29 100         if (flag & XH_H2X_F_ATTR_ONLY) return;
60              
61 22 100         if (type & XH_H2X_T_ARRAY) {
62 1           xh_h2x_lx(ctx, value, key, key_len, XH_H2X_F_NONE);
63             }
64 21 100         else if (type & XH_H2X_T_NOT_NULL) {
65 20           _xh_h2x_lx_write_complex_node(ctx, key, key_len, value);
66             }
67             else {
68 26           xh_xml_write_empty_node(&ctx->writer, key, key_len);
69             }
70             }
71             }
72             else {
73 0 0         if (type & XH_H2X_T_NOT_NULL) {
74 0           xh_h2x_lx(ctx, value, key, key_len, XH_H2X_F_NONE);
75             }
76             else {
77 31           xh_xml_write_empty_node(&ctx->writer, key, key_len);
78             }
79             }
80             }
81              
82             void
83 70           xh_h2x_lx(xh_h2x_ctx_t *ctx, SV *value, xh_char_t *key, I32 key_len, xh_int_t flag)
84             {
85             SV *hash_value;
86             size_t len, i;
87             xh_uint_t type;
88             xh_sort_hash_t *sorted_hash;
89              
90 70           value = xh_h2x_resolve_value(ctx, value, &type);
91              
92 70 100         if (type & XH_H2X_T_SCALAR) {
93 20 100         if (flag & XH_H2X_F_ATTR_ONLY) goto FINISH;
94 10           xh_xml_write_content(&ctx->writer, value);
95             }
96 50 100         else if (type & XH_H2X_T_HASH) {
97 47 50         len = HvUSEDKEYS((HV *) value);
98              
99 47 100         if (len > 1 && ctx->opts.canonical) {
    50          
100 0           sorted_hash = xh_sort_hash((HV *) value, len);
101 0 0         for (i = 0; i < len; i++) {
102 0           _xh_h2x_lx(ctx, sorted_hash[i].key, sorted_hash[i].key_len, sorted_hash[i].value, flag);
103             }
104 0           free(sorted_hash);
105             }
106             else {
107 47           hv_iterinit((HV *) value);
108 96 100         while ((hash_value = hv_iternextsv((HV *) value, (char **) &key, &key_len))) {
109 49           _xh_h2x_lx(ctx, key, key_len, hash_value, flag);
110             }
111             }
112             }
113 3 50         else if (type & XH_H2X_T_ARRAY) {
114 3 100         if (flag & XH_H2X_F_ATTR_ONLY) goto FINISH;
115 2           len = av_len((AV *) value) + 1;
116 9 100         for (i = 0; i < len; i++) {
117 7           _xh_h2x_lx_write_complex_node(ctx, key, key_len, *av_fetch((AV *) value, i, 0));
118             }
119             }
120              
121             FINISH:
122 70           ctx->depth--;
123 70           }
124              
125             #ifdef XH_HAVE_DOM
126             XH_INLINE void
127             _xh_h2d_lx_write_complex_node(xh_h2x_ctx_t *ctx, xmlNodePtr rootNode, xh_char_t *key, I32 key_len, SV *value)
128             {
129             //rootNode = xh_dom_new_node(ctx, rootNode, key, key_len, NULL, type & XH_H2X_T_RAW);
130             rootNode = xh_dom_new_node(ctx, rootNode, key, key_len, NULL, XH_H2X_T_RAW);
131              
132             xh_h2d_lx(ctx, rootNode, value, key, key_len, XH_H2X_F_ATTR_ONLY);
133             xh_h2d_lx(ctx, rootNode, value, key, key_len, XH_H2X_F_NONE);
134             }
135              
136             XH_INLINE void
137             _xh_h2d_lx(xh_h2x_ctx_t *ctx, xmlNodePtr rootNode, xh_char_t *key, I32 key_len, SV *value, xh_int_t flag)
138             {
139             xh_uint_t type;
140              
141             value = xh_h2x_resolve_value(ctx, value, &type);
142              
143             if (ctx->opts.cdata[0] != '\0' && xh_strcmp(key, ctx->opts.cdata) == 0) {
144             if (flag & XH_H2X_F_ATTR_ONLY || !(type & XH_H2X_T_SCALAR)) return;
145             xh_dom_new_cdata(ctx, rootNode, value);
146             }
147             else if (ctx->opts.text[0] != '\0' && xh_strcmp(key, ctx->opts.text) == 0) {
148             if (flag & XH_H2X_F_ATTR_ONLY || !(type & XH_H2X_T_SCALAR)) return;
149             xh_dom_new_content(ctx, rootNode, value);
150             }
151             else if (ctx->opts.comm[0] != '\0' && xh_strcmp(key, ctx->opts.comm) == 0) {
152             if (flag & XH_H2X_F_ATTR_ONLY) return;
153              
154             if (!type) {
155             xh_dom_new_comment(ctx, rootNode, NULL);
156             }
157             else if (type & XH_H2X_T_SCALAR) {
158             xh_dom_new_comment(ctx, rootNode, value);
159             }
160             }
161             else if (ctx->opts.attr[0] != '\0') {
162             if (xh_strncmp(key, ctx->opts.attr, ctx->opts.attr_len) == 0) {
163             if (!(flag & XH_H2X_F_ATTR_ONLY)) return;
164              
165             key += ctx->opts.attr_len;
166             key_len -= ctx->opts.attr_len;
167              
168             if (type & XH_H2X_T_SCALAR) {
169             xh_dom_new_attribute(ctx, rootNode, key, key_len, value);
170             }
171             else {
172             xh_dom_new_attribute(ctx, rootNode, key, key_len, NULL);
173             }
174             }
175             else {
176             if (flag & XH_H2X_F_ATTR_ONLY) return;
177              
178             if (type & XH_H2X_T_ARRAY) {
179             xh_h2d_lx(ctx, rootNode, value, key, key_len, XH_H2X_F_NONE);
180             }
181             else if (type & XH_H2X_T_NOT_NULL) {
182             _xh_h2d_lx_write_complex_node(ctx, rootNode, key, key_len, value);
183             }
184             else {
185             xh_dom_new_node(ctx, rootNode, key, key_len, NULL, type & XH_H2X_T_RAW);
186             }
187             }
188             }
189             else {
190             rootNode = xh_dom_new_node(ctx, rootNode, key, key_len, NULL, type & XH_H2X_T_RAW);
191             if (type & XH_H2X_T_NOT_NULL) {
192             xh_h2d_lx(ctx, rootNode, value, key, key_len, XH_H2X_F_NONE);
193             }
194             }
195             }
196              
197             void
198             xh_h2d_lx(xh_h2x_ctx_t *ctx, xmlNodePtr rootNode, SV *value, xh_char_t *key, I32 key_len, xh_int_t flag)
199             {
200             SV *hash_value;
201             size_t len, i;
202             xh_uint_t type;
203             xh_sort_hash_t *sorted_hash;
204              
205             value = xh_h2x_resolve_value(ctx, value, &type);
206              
207             if (type & XH_H2X_T_SCALAR) {
208             if (flag & XH_H2X_F_ATTR_ONLY) goto FINISH;
209             xh_dom_new_content(ctx, rootNode, value);
210             }
211             else if (type & XH_H2X_T_HASH) {
212             len = HvUSEDKEYS((HV *) value);
213             hv_iterinit((HV *) value);
214              
215             if (len > 1 && ctx->opts.canonical) {
216             sorted_hash = xh_sort_hash((HV *) value, len);
217             for (i = 0; i < len; i++) {
218             _xh_h2d_lx(ctx, rootNode, sorted_hash[i].key, sorted_hash[i].key_len, sorted_hash[i].value, flag);
219             }
220             free(sorted_hash);
221             }
222             else {
223             while ((hash_value = hv_iternextsv((HV *) value, (char **) &key, &key_len))) {
224             _xh_h2d_lx(ctx, rootNode, key, key_len, hash_value, flag);
225             }
226             }
227             }
228             else if (type & XH_H2X_T_ARRAY) {
229             if (flag & XH_H2X_F_ATTR_ONLY) goto FINISH;
230             len = av_len((AV *) value) + 1;
231             for (i = 0; i < len; i++) {
232             _xh_h2d_lx_write_complex_node(ctx, rootNode, key, key_len, *av_fetch((AV *) value, i, 0));
233             }
234             }
235              
236             FINISH:
237             ctx->depth--;
238             }
239             #endif