Commit c109128a authored by jdoerrie's avatar jdoerrie Committed by Commit Bot

[base] Expose MergeDictionary on base::Value

This change moves MergeDictionary() from base::DictionaryValue to the
parent class base::Value and relaxes its interface to accept base::Value
pointers as well. Appropriate CHECKs are added.

Bug: 646133
Change-Id: Ib6dab60ea2ff4f56b320e4a54f0782905aa3c4ae
Reviewed-on: https://chromium-review.googlesource.com/1158233Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#579847}
parent 8d6faa88
......@@ -443,6 +443,26 @@ bool Value::DictEmpty() const {
return dict_.empty();
}
void Value::MergeDictionary(const Value* dictionary) {
CHECK(is_dict());
CHECK(dictionary->is_dict());
for (const auto& pair : dictionary->dict_) {
const auto& key = pair.first;
const auto& val = pair.second;
// Check whether we have to merge dictionaries.
if (val->is_dict()) {
auto found = dict_.find(key);
if (found != dict_.end() && found->second->is_dict()) {
found->second->MergeDictionary(val.get());
continue;
}
}
// All other cases: Make a copy and hook it up.
SetKey(key, val->Clone());
}
}
bool Value::GetAsBoolean(bool* out_value) const {
if (out_value && is_bool()) {
*out_value = bool_value_;
......@@ -1114,24 +1134,6 @@ std::unique_ptr<DictionaryValue> DictionaryValue::DeepCopyWithoutEmptyChildren()
return copy;
}
void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
CHECK(dictionary->is_dict());
for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
const Value* merge_value = &it.value();
// Check whether we have to merge dictionaries.
if (merge_value->is_dict()) {
DictionaryValue* sub_dict;
if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
sub_dict->MergeDictionary(
static_cast<const DictionaryValue*>(merge_value));
continue;
}
}
// All other cases: Make a copy and hook it up.
SetKey(it.key(), merge_value->Clone());
}
}
void DictionaryValue::Swap(DictionaryValue* other) {
CHECK(other->is_dict());
dict_.swap(other->dict_);
......
......@@ -302,6 +302,15 @@ class BASE_EXPORT Value {
size_t DictSize() const;
bool DictEmpty() const;
// Merge |dictionary| into this value. This is done recursively, i.e. any
// sub-dictionaries will be merged as well. In case of key collisions, the
// passed in dictionary takes precedence and data already present will be
// replaced. Values within |dictionary| are deep-copied, so |dictionary| may
// be freed any time after this call.
// Note: This fatally asserts if type() or dictionary->type() is not
// Type::DICTIONARY.
void MergeDictionary(const Value* dictionary);
// These methods allow the convenient retrieval of the contents of the Value.
// If the current object can be converted into the given type, the value is
// returned through the |out_value| parameter and true is returned;
......@@ -542,13 +551,6 @@ class BASE_EXPORT DictionaryValue : public Value {
// the copy. This never returns NULL, even if |this| itself is empty.
std::unique_ptr<DictionaryValue> DeepCopyWithoutEmptyChildren() const;
// Merge |dictionary| into this dictionary. This is done recursively, i.e. any
// sub-dictionaries will be merged as well. In case of key collisions, the
// passed in dictionary takes precedence and data already present will be
// replaced. Values within |dictionary| are deep-copied, so |dictionary| may
// be freed any time after this call.
void MergeDictionary(const DictionaryValue* dictionary);
// Swaps contents with the |other| dictionary.
void Swap(DictionaryValue* other);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment