| 1248 | } |
| 1249 | |
| 1250 | gboolean |
| 1251 | apply_xml_diff(xmlNode *old, xmlNode *diff, xmlNode **new) |
| 1252 | { |
| 1253 | gboolean result = TRUE; |
| 1254 | int root_nodes_seen = 0; |
| 1255 | static struct qb_log_callsite *digest_cs = NULL; |
| 1256 | const char *digest = crm_element_value(diff, XML_ATTR_DIGEST); |
| 1257 | const char *version = crm_element_value(diff, XML_ATTR_CRM_VERSION); |
| 1258 | |
| 1259 | xmlNode *child_diff = NULL; |
| 1260 | xmlNode *added = find_xml_node(diff, "diff-added", FALSE); |
| 1261 | xmlNode *removed = find_xml_node(diff, "diff-removed", FALSE); |
| 1262 | |
| 1263 | CRM_CHECK(new != NULL, return FALSE); |
| 1264 | if(digest_cs == NULL) { |
| 1265 | digest_cs = qb_log_callsite_get(__func__, __FILE__, "diff-digest", LOG_TRACE, __LINE__, crm_trace_nonlog); |
| 1266 | } |
| 1267 | |
| 1268 | crm_trace("Substraction Phase"); |
| 1269 | for(child_diff = __xml_first_child(removed); child_diff != NULL; child_diff = __xml_next(child_diff)) { |
| 1270 | CRM_CHECK(root_nodes_seen == 0, result = FALSE); |
| 1271 | if(root_nodes_seen == 0) { |
| 1272 | *new = subtract_xml_object(NULL, old, child_diff, FALSE, NULL, NULL); |
| 1273 | } |
| 1274 | root_nodes_seen++; |
| 1275 | } |
| 1276 | |
| 1277 | if(root_nodes_seen == 0) { |
| 1278 | *new = copy_xml(old); |
| 1279 | |
| 1280 | } else if(root_nodes_seen > 1) { |
| 1281 | crm_err("(-) Diffs cannot contain more than one change set..." |
| 1282 | " saw %d", root_nodes_seen); |
| 1283 | result = FALSE; |
| 1284 | } |
| 1285 | |
| 1286 | root_nodes_seen = 0; |
| 1287 | crm_trace("Addition Phase"); |
| 1288 | if(result) { |
| 1289 | xmlNode *child_diff = NULL; |
| 1290 | for(child_diff = __xml_first_child(added); child_diff != NULL; child_diff = __xml_next(child_diff)) { |
| 1291 | CRM_CHECK(root_nodes_seen == 0, result = FALSE); |
| 1292 | if(root_nodes_seen == 0) { |
| 1293 | add_xml_object(NULL, *new, child_diff, TRUE); |
| 1294 | } |
| 1295 | root_nodes_seen++; |
| 1296 | } |
| 1297 | } |
| 1298 | |
| 1299 | if(root_nodes_seen > 1) { |
| 1300 | crm_err("(+) Diffs cannot contain more than one change set..." |
| 1301 | " saw %d", root_nodes_seen); |
| 1302 | result = FALSE; |
| 1303 | |
| 1304 | } else if(result && digest) { |
| 1305 | char *new_digest = NULL; |
| 1306 | purge_diff_markers(*new); /* Purge now so the diff is ok */ |
| 1307 | new_digest = calculate_xml_versioned_digest(*new, FALSE, TRUE, version); |
no test coverage detected