// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chromeos/network/onc/onc_mapper.h" #include "base/logging.h" #include "base/values.h" #include "chromeos/network/onc/onc_signature.h" namespace chromeos { namespace onc { Mapper::Mapper() { } Mapper::~Mapper() { } scoped_ptr Mapper::MapValue(const OncValueSignature& signature, const base::Value& onc_value, bool* error) { scoped_ptr result_value; switch (onc_value.GetType()) { case base::Value::TYPE_DICTIONARY: { const base::DictionaryValue* dict = NULL; onc_value.GetAsDictionary(&dict); result_value = MapObject(signature, *dict, error); break; } case base::Value::TYPE_LIST: { const base::ListValue* list = NULL; onc_value.GetAsList(&list); result_value = MapArray(signature, *list, error); break; } default: { result_value = MapPrimitive(signature, onc_value, error); break; } } return result_value.Pass(); } scoped_ptr Mapper::MapObject( const OncValueSignature& signature, const base::DictionaryValue& onc_object, bool* error) { scoped_ptr result(new base::DictionaryValue); bool found_unknown_field = false; MapFields(signature, onc_object, &found_unknown_field, error, result.get()); if (found_unknown_field) *error = true; return result.Pass(); } scoped_ptr Mapper::MapPrimitive(const OncValueSignature& signature, const base::Value& onc_primitive, bool* error) { return make_scoped_ptr(onc_primitive.DeepCopy()); } void Mapper::MapFields(const OncValueSignature& object_signature, const base::DictionaryValue& onc_object, bool* found_unknown_field, bool* nested_error, base::DictionaryValue* result) { for (base::DictionaryValue::Iterator it(onc_object); !it.IsAtEnd(); it.Advance()) { bool current_field_unknown = false; scoped_ptr result_value = MapField(it.key(), object_signature, it.value(), ¤t_field_unknown, nested_error); if (current_field_unknown) *found_unknown_field = true; else if (result_value.get() != NULL) result->SetWithoutPathExpansion(it.key(), result_value.release()); else DCHECK(*nested_error); } } scoped_ptr Mapper::MapField( const std::string& field_name, const OncValueSignature& object_signature, const base::Value& onc_value, bool* found_unknown_field, bool* error) { const OncFieldSignature* field_signature = GetFieldSignature(object_signature, field_name); if (field_signature != NULL) { DCHECK(field_signature->value_signature != NULL) << "Found missing value signature at field '" << field_name << "'."; return MapValue(*field_signature->value_signature, onc_value, error); } else { DVLOG(1) << "Found unknown field name: '" << field_name << "'"; *found_unknown_field = true; return scoped_ptr(); } } scoped_ptr Mapper::MapArray( const OncValueSignature& array_signature, const base::ListValue& onc_array, bool* nested_error) { DCHECK(array_signature.onc_array_entry_signature != NULL) << "Found missing onc_array_entry_signature."; scoped_ptr result_array(new base::ListValue); int original_index = 0; for (base::ListValue::const_iterator it = onc_array.begin(); it != onc_array.end(); ++it, ++original_index) { const base::Value* entry = *it; scoped_ptr result_entry; result_entry = MapEntry(original_index, *array_signature.onc_array_entry_signature, *entry, nested_error); if (result_entry.get() != NULL) result_array->Append(result_entry.release()); else DCHECK(*nested_error); } return result_array.Pass(); } scoped_ptr Mapper::MapEntry(int index, const OncValueSignature& signature, const base::Value& onc_value, bool* error) { return MapValue(signature, onc_value, error); } } // namespace onc } // namespace chromeos