@@ -66,9 +66,13 @@ typedef struct {
66
66
const xmlChar * prefix , * name ;
67
67
} dom_qname_pair ;
68
68
69
+ typedef struct dom_xml_serialize_ctx {
70
+ xmlSaveCtxtPtr ctxt ;
71
+ xmlOutputBufferPtr out ;
72
+ } dom_xml_serialize_ctx ;
73
+
69
74
static int dom_xml_serialization_algorithm (
70
- xmlSaveCtxtPtr ctxt ,
71
- xmlOutputBufferPtr out ,
75
+ dom_xml_serialize_ctx * ctx ,
72
76
dom_xml_ns_prefix_map * namespace_prefix_map ,
73
77
xmlNodePtr node ,
74
78
const xmlChar * namespace ,
@@ -895,8 +899,7 @@ static int dom_xml_output_indents(xmlOutputBufferPtr out, int indent)
895
899
896
900
/* https://w3c.github.io/DOM-Parsing/#dfn-xml-serializing-an-element-node */
897
901
static int dom_xml_serialize_element_node (
898
- xmlSaveCtxtPtr ctxt ,
899
- xmlOutputBufferPtr out ,
902
+ dom_xml_serialize_ctx * ctx ,
900
903
const xmlChar * namespace ,
901
904
dom_xml_ns_prefix_map * namespace_prefix_map ,
902
905
xmlNodePtr element ,
@@ -916,7 +919,7 @@ static int dom_xml_serialize_element_node(
916
919
bool should_format = indent >= 0 && element -> children != NULL && dom_xml_should_format_element (element );
917
920
918
921
/* 2. Let markup be the string "<" (U+003C LESS-THAN SIGN). */
919
- TRY (xmlOutputBufferWriteLit (out , "<" ));
922
+ TRY (xmlOutputBufferWriteLit (ctx -> out , "<" ));
920
923
921
924
/* 3. Let qualified name be an empty string.
922
925
* => We're going to do it a bit differently.
@@ -966,7 +969,7 @@ static int dom_xml_serialize_element_node(
966
969
}
967
970
968
971
/* 11.4. Append the value of qualified name to markup. */
969
- TRY_OR_CLEANUP (dom_xml_output_qname (out , & qualified_name ));
972
+ TRY_OR_CLEANUP (dom_xml_output_qname (ctx -> out , & qualified_name ));
970
973
}
971
974
/* 12. Otherwise, inherited ns is not equal to ns */
972
975
else {
@@ -1011,7 +1014,7 @@ static int dom_xml_serialize_element_node(
1011
1014
}
1012
1015
1013
1016
/* 12.4.3. Append the value of qualified name to markup. */
1014
- TRY_OR_CLEANUP (dom_xml_output_qname (out , & qualified_name ));
1017
+ TRY_OR_CLEANUP (dom_xml_output_qname (ctx -> out , & qualified_name ));
1015
1018
}
1016
1019
/* 12.5. Otherwise, if prefix is not null, then: */
1017
1020
else if (prefix != NULL ) {
@@ -1033,14 +1036,14 @@ static int dom_xml_serialize_element_node(
1033
1036
qualified_name .name = element -> name ;
1034
1037
1035
1038
/* 12.5.4. Append the value of qualified name to markup. */
1036
- TRY_OR_CLEANUP (dom_xml_output_qname (out , & qualified_name ));
1039
+ TRY_OR_CLEANUP (dom_xml_output_qname (ctx -> out , & qualified_name ));
1037
1040
1038
1041
/* 12.5.5. Append the following to markup, in the order listed: ... */
1039
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , " xmlns:" )); /* 12.5.5.1 - 12.5.5.2 */
1040
- TRY_OR_CLEANUP (xmlOutputBufferWriteString (out , (const char * ) prefix ));
1041
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , "=\"" ));
1042
- TRY_OR_CLEANUP (dom_xml_common_text_serialization (out , (const char * ) ns , true));
1043
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , "\"" ));
1042
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , " xmlns:" )); /* 12.5.5.1 - 12.5.5.2 */
1043
+ TRY_OR_CLEANUP (xmlOutputBufferWriteString (ctx -> out , (const char * ) prefix ));
1044
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , "=\"" ));
1045
+ TRY_OR_CLEANUP (dom_xml_common_text_serialization (ctx -> out , (const char * ) ns , true));
1046
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , "\"" ));
1044
1047
1045
1048
/* 12.5.6. If local default namespace is not null ... (editorial numbering error: https://github.com/w3c/DOM-Parsing/issues/43) */
1046
1049
if (local_default_namespace != NULL ) {
@@ -1064,24 +1067,24 @@ static int dom_xml_serialize_element_node(
1064
1067
inherited_ns = ns ;
1065
1068
1066
1069
/* 12.6.4. Append the value of qualified name to markup. */
1067
- TRY_OR_CLEANUP (dom_xml_output_qname (out , & qualified_name ));
1070
+ TRY_OR_CLEANUP (dom_xml_output_qname (ctx -> out , & qualified_name ));
1068
1071
1069
1072
/* 12.6.5. Append the following to markup, in the order listed: ... */
1070
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , " xmlns=\"" )); /* 12.6.5.1 - 12.6.5.2 */
1071
- TRY_OR_CLEANUP (dom_xml_common_text_serialization (out , (const char * ) ns , true));
1072
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , "\"" ));
1073
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , " xmlns=\"" )); /* 12.6.5.1 - 12.6.5.2 */
1074
+ TRY_OR_CLEANUP (dom_xml_common_text_serialization (ctx -> out , (const char * ) ns , true));
1075
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , "\"" ));
1073
1076
}
1074
1077
/* 12.7. Otherwise, the node has a local default namespace that matches ns ... */
1075
1078
else {
1076
1079
qualified_name .name = element -> name ;
1077
1080
inherited_ns = ns ;
1078
- TRY_OR_CLEANUP (dom_xml_output_qname (out , & qualified_name ));
1081
+ TRY_OR_CLEANUP (dom_xml_output_qname (ctx -> out , & qualified_name ));
1079
1082
}
1080
1083
}
1081
1084
1082
1085
/* 13. Append to markup the result of the XML serialization of node's attributes given map, prefix index,
1083
1086
* local prefixes map, ignore namespace definition attribute flag, and require well-formed flag. */
1084
- TRY_OR_CLEANUP (dom_xml_serialize_attributes (out , element , & map , & local_prefixes_map , prefix_index , ignore_namespace_definition_attribute , require_well_formed ));
1087
+ TRY_OR_CLEANUP (dom_xml_serialize_attributes (ctx -> out , element , & map , & local_prefixes_map , prefix_index , ignore_namespace_definition_attribute , require_well_formed ));
1085
1088
1086
1089
/* 14. If ns is the HTML namespace, and the node's list of children is empty, and the node's localName matches
1087
1090
* any one of the following void elements: ... */
@@ -1109,19 +1112,19 @@ static int dom_xml_serialize_element_node(
1109
1112
|| dom_local_name_compare_ex (element , "source" , strlen ("source" ), name_length )
1110
1113
|| dom_local_name_compare_ex (element , "track" , strlen ("track" ), name_length )
1111
1114
|| dom_local_name_compare_ex (element , "wbr" , strlen ("wbr" ), name_length )) {
1112
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , " /" ));
1115
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , " /" ));
1113
1116
skip_end_tag = true;
1114
1117
}
1115
1118
} else {
1116
1119
/* 15. If ns is not the HTML namespace, and the node's list of children is empty,
1117
1120
* then append "/" (U+002F SOLIDUS) to markup and set the skip end tag flag to true. */
1118
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , "/" ));
1121
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , "/" ));
1119
1122
skip_end_tag = true;
1120
1123
}
1121
1124
}
1122
1125
1123
1126
/* 16. Append ">" (U+003E GREATER-THAN SIGN) to markup. */
1124
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , ">" ));
1127
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , ">" ));
1125
1128
1126
1129
/* 17. If the value of skip end tag is true, then return the value of markup and skip the remaining steps. */
1127
1130
if (!skip_end_tag ) {
@@ -1136,20 +1139,20 @@ static int dom_xml_serialize_element_node(
1136
1139
/* 19. Otherwise, append to markup the result of running the XML serialization algorithm on each of node's children. */
1137
1140
for (xmlNodePtr child = element -> children ; child != NULL ; child = child -> next ) {
1138
1141
if (should_format ) {
1139
- TRY_OR_CLEANUP (dom_xml_output_indents (out , indent ));
1142
+ TRY_OR_CLEANUP (dom_xml_output_indents (ctx -> out , indent ));
1140
1143
}
1141
- TRY_OR_CLEANUP (dom_xml_serialization_algorithm (ctxt , out , & map , child , inherited_ns , prefix_index , indent , require_well_formed ));
1144
+ TRY_OR_CLEANUP (dom_xml_serialization_algorithm (ctx , & map , child , inherited_ns , prefix_index , indent , require_well_formed ));
1142
1145
}
1143
1146
1144
1147
if (should_format ) {
1145
1148
indent -- ;
1146
- TRY_OR_CLEANUP (dom_xml_output_indents (out , indent ));
1149
+ TRY_OR_CLEANUP (dom_xml_output_indents (ctx -> out , indent ));
1147
1150
}
1148
1151
1149
1152
/* 20. Append the following to markup, in the order listed: */
1150
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , "</" ));
1151
- TRY_OR_CLEANUP (dom_xml_output_qname (out , & qualified_name ));
1152
- TRY_OR_CLEANUP (xmlOutputBufferWriteLit (out , ">" ));
1153
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , "</" ));
1154
+ TRY_OR_CLEANUP (dom_xml_output_qname (ctx -> out , & qualified_name ));
1155
+ TRY_OR_CLEANUP (xmlOutputBufferWriteLit (ctx -> out , ">" ));
1153
1156
}
1154
1157
1155
1158
/* 21. Return the value of markup.
@@ -1166,8 +1169,7 @@ static int dom_xml_serialize_element_node(
1166
1169
1167
1170
/* https://w3c.github.io/DOM-Parsing/#xml-serializing-a-documentfragment-node */
1168
1171
static int dom_xml_serializing_a_document_fragment_node (
1169
- xmlSaveCtxtPtr ctxt ,
1170
- xmlOutputBufferPtr out ,
1172
+ dom_xml_serialize_ctx * ctx ,
1171
1173
dom_xml_ns_prefix_map * namespace_prefix_map ,
1172
1174
xmlNodePtr node ,
1173
1175
const xmlChar * namespace ,
@@ -1182,7 +1184,7 @@ static int dom_xml_serializing_a_document_fragment_node(
1182
1184
/* 2. For each child child of node, in tree order, run the XML serialization algorithm on the child ... */
1183
1185
xmlNodePtr child = node -> children ;
1184
1186
while (child != NULL ) {
1185
- TRY (dom_xml_serialization_algorithm (ctxt , out , namespace_prefix_map , child , namespace , prefix_index , indent , require_well_formed ));
1187
+ TRY (dom_xml_serialization_algorithm (ctx , namespace_prefix_map , child , namespace , prefix_index , indent , require_well_formed ));
1186
1188
child = child -> next ;
1187
1189
}
1188
1190
@@ -1193,8 +1195,7 @@ static int dom_xml_serializing_a_document_fragment_node(
1193
1195
1194
1196
/* https://w3c.github.io/DOM-Parsing/#dfn-xml-serializing-a-document-node */
1195
1197
static int dom_xml_serializing_a_document_node (
1196
- xmlSaveCtxtPtr ctxt ,
1197
- xmlOutputBufferPtr out ,
1198
+ dom_xml_serialize_ctx * ctx ,
1198
1199
dom_xml_ns_prefix_map * namespace_prefix_map ,
1199
1200
xmlNodePtr node ,
1200
1201
const xmlChar * namespace ,
@@ -1210,16 +1211,16 @@ static int dom_xml_serializing_a_document_node(
1210
1211
node -> children = NULL ;
1211
1212
1212
1213
/* https://github.com/w3c/DOM-Parsing/issues/50 */
1213
- TRY (xmlOutputBufferFlush (out ));
1214
- TRY (xmlSaveDoc (ctxt , (xmlDocPtr ) node ));
1215
- TRY (xmlSaveFlush (ctxt ));
1214
+ TRY (xmlOutputBufferFlush (ctx -> out ));
1215
+ TRY (xmlSaveDoc (ctx -> ctxt , (xmlDocPtr ) node ));
1216
+ TRY (xmlSaveFlush (ctx -> ctxt ));
1216
1217
1217
1218
node -> children = child ;
1218
1219
1219
1220
/* 2. For each child child of node, in tree order, run the XML serialization algorithm on the child passing along the provided arguments,
1220
1221
* and append the result to serialized document. */
1221
1222
while (child != NULL ) {
1222
- TRY (dom_xml_serialization_algorithm (ctxt , out , namespace_prefix_map , child , namespace , prefix_index , indent , require_well_formed ));
1223
+ TRY (dom_xml_serialization_algorithm (ctx , namespace_prefix_map , child , namespace , prefix_index , indent , require_well_formed ));
1223
1224
child = child -> next ;
1224
1225
}
1225
1226
@@ -1230,8 +1231,7 @@ static int dom_xml_serializing_a_document_node(
1230
1231
1231
1232
/* https://w3c.github.io/DOM-Parsing/#dfn-xml-serialization-algorithm */
1232
1233
static int dom_xml_serialization_algorithm (
1233
- xmlSaveCtxtPtr ctxt ,
1234
- xmlOutputBufferPtr out ,
1234
+ dom_xml_serialize_ctx * ctx ,
1235
1235
dom_xml_ns_prefix_map * namespace_prefix_map ,
1236
1236
xmlNodePtr node ,
1237
1237
const xmlChar * namespace ,
@@ -1243,36 +1243,36 @@ static int dom_xml_serialization_algorithm(
1243
1243
/* If node's interface is: */
1244
1244
switch (node -> type ) {
1245
1245
case XML_ELEMENT_NODE :
1246
- return dom_xml_serialize_element_node (ctxt , out , namespace , namespace_prefix_map , node , prefix_index , indent , require_well_formed );
1246
+ return dom_xml_serialize_element_node (ctx , namespace , namespace_prefix_map , node , prefix_index , indent , require_well_formed );
1247
1247
1248
1248
case XML_DOCUMENT_FRAG_NODE :
1249
- return dom_xml_serializing_a_document_fragment_node (ctxt , out , namespace_prefix_map , node , namespace , prefix_index , indent , require_well_formed );
1249
+ return dom_xml_serializing_a_document_fragment_node (ctx , namespace_prefix_map , node , namespace , prefix_index , indent , require_well_formed );
1250
1250
1251
1251
case XML_HTML_DOCUMENT_NODE :
1252
1252
case XML_DOCUMENT_NODE :
1253
- return dom_xml_serializing_a_document_node (ctxt , out , namespace_prefix_map , node , namespace , prefix_index , indent , require_well_formed );
1253
+ return dom_xml_serializing_a_document_node (ctx , namespace_prefix_map , node , namespace , prefix_index , indent , require_well_formed );
1254
1254
1255
1255
case XML_TEXT_NODE :
1256
- return dom_xml_serialize_text_node (out , node , require_well_formed );
1256
+ return dom_xml_serialize_text_node (ctx -> out , node , require_well_formed );
1257
1257
1258
1258
case XML_COMMENT_NODE :
1259
- return dom_xml_serialize_comment_node (out , node , require_well_formed );
1259
+ return dom_xml_serialize_comment_node (ctx -> out , node , require_well_formed );
1260
1260
1261
1261
case XML_PI_NODE :
1262
- return dom_xml_serialize_processing_instruction (out , node , require_well_formed );
1262
+ return dom_xml_serialize_processing_instruction (ctx -> out , node , require_well_formed );
1263
1263
1264
1264
case XML_CDATA_SECTION_NODE :
1265
- return dom_xml_serialize_cdata_section_node (out , node );
1265
+ return dom_xml_serialize_cdata_section_node (ctx -> out , node );
1266
1266
1267
1267
case XML_ATTRIBUTE_NODE :
1268
- return dom_xml_serialize_attribute_node (out , node );
1268
+ return dom_xml_serialize_attribute_node (ctx -> out , node );
1269
1269
1270
1270
default :
1271
- TRY (xmlOutputBufferFlush (out ));
1272
- TRY (xmlSaveTree (ctxt , node ));
1273
- TRY (xmlSaveFlush (ctxt ));
1271
+ TRY (xmlOutputBufferFlush (ctx -> out ));
1272
+ TRY (xmlSaveTree (ctx -> ctxt , node ));
1273
+ TRY (xmlSaveFlush (ctx -> ctxt ));
1274
1274
if (node -> type == XML_DTD_NODE ) {
1275
- return xmlOutputBufferWriteLit (out , "\n" );
1275
+ return xmlOutputBufferWriteLit (ctx -> out , "\n" );
1276
1276
}
1277
1277
return 0 ;
1278
1278
}
@@ -1297,8 +1297,11 @@ int dom_xml_serialize(xmlSaveCtxtPtr ctxt, xmlOutputBufferPtr out, xmlNodePtr no
1297
1297
unsigned int prefix_index = 1 ;
1298
1298
1299
1299
/* 5. Return the result of running the XML serialization algorithm ... */
1300
+ dom_xml_serialize_ctx ctx ;
1301
+ ctx .out = out ;
1302
+ ctx .ctxt = ctxt ;
1300
1303
int indent = format ? 0 : -1 ;
1301
- int result = dom_xml_serialization_algorithm (ctxt , out , & namespace_prefix_map , node , namespace , & prefix_index , indent , require_well_formed );
1304
+ int result = dom_xml_serialization_algorithm (& ctx , & namespace_prefix_map , node , namespace , & prefix_index , indent , require_well_formed );
1302
1305
1303
1306
dom_xml_ns_prefix_map_dtor (& namespace_prefix_map );
1304
1307
0 commit comments