in src/util/JsonParser.cpp [258:325]
ResponseCode JsonParser::DiffValues(JsonValue &target_doc,
JsonValue &old_doc,
JsonValue &new_doc,
JsonValue::AllocatorType &allocator) {
if (old_doc.IsNull() || new_doc.IsNull() || !old_doc.IsObject() || !new_doc.IsObject()) {
return ResponseCode::JSON_MERGE_FAILED;
}
ResponseCode rc = ResponseCode::SUCCESS;
bool inner_merge_successful = true;
bool old_doc_has_key = false;
target_doc.SetObject();
util::JsonValue::MemberIterator old_doc_itr;
util::JsonValue::MemberIterator new_doc_itr = new_doc.MemberBegin();
while (new_doc_itr != new_doc.MemberEnd()) {
old_doc_itr = old_doc.MemberBegin();
old_doc_has_key = false;
inner_merge_successful = true;
while (old_doc_itr != old_doc.MemberEnd()) {
if (old_doc_itr->name == new_doc_itr->name) {
if (old_doc_itr->value != new_doc_itr->value) {
if (old_doc_itr->value.IsObject() && new_doc_itr->value.IsObject()) {
JsonValue diff_val;
diff_val.SetObject();
rc = DiffValues(diff_val, old_doc_itr->value, new_doc_itr->value, allocator);
if (ResponseCode::SUCCESS != rc) {
inner_merge_successful = false;
break;
} else {
if (diff_val.MemberCount() > 0) {
JsonValue name;
name.CopyFrom(new_doc_itr->name, allocator);
target_doc.AddMember(name.Move(), diff_val.Move(), allocator);
}
}
} else {
JsonValue name;
JsonValue value;
name.CopyFrom(new_doc_itr->name, allocator);
value.CopyFrom(new_doc_itr->value, allocator);
target_doc.AddMember(name.Move(), value.Move(), allocator);
}
}
old_doc_has_key = true;
break;
}
old_doc_itr++;
}
if (!inner_merge_successful) {
break;
}
if (!old_doc_has_key) {
JsonValue name;
JsonValue value;
name.CopyFrom(new_doc_itr->name, allocator);
value.CopyFrom(new_doc_itr->value, allocator);
target_doc.AddMember(name.Move(), value.Move(), allocator);
}
new_doc_itr++;
}
return rc;
}