1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chromeos/network/onc/onc_mapper.h" 6 7#include "base/logging.h" 8#include "base/values.h" 9#include "chromeos/network/onc/onc_signature.h" 10 11namespace chromeos { 12namespace onc { 13 14Mapper::Mapper() { 15} 16 17Mapper::~Mapper() { 18} 19 20scoped_ptr<base::Value> Mapper::MapValue(const OncValueSignature& signature, 21 const base::Value& onc_value, 22 bool* error) { 23 scoped_ptr<base::Value> result_value; 24 switch (onc_value.GetType()) { 25 case base::Value::TYPE_DICTIONARY: { 26 const base::DictionaryValue* dict = NULL; 27 onc_value.GetAsDictionary(&dict); 28 result_value = MapObject(signature, *dict, error); 29 break; 30 } 31 case base::Value::TYPE_LIST: { 32 const base::ListValue* list = NULL; 33 onc_value.GetAsList(&list); 34 result_value = MapArray(signature, *list, error); 35 break; 36 } 37 default: { 38 result_value = MapPrimitive(signature, onc_value, error); 39 break; 40 } 41 } 42 43 return result_value.Pass(); 44} 45 46scoped_ptr<base::DictionaryValue> Mapper::MapObject( 47 const OncValueSignature& signature, 48 const base::DictionaryValue& onc_object, 49 bool* error) { 50 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); 51 52 bool found_unknown_field = false; 53 MapFields(signature, onc_object, &found_unknown_field, error, result.get()); 54 if (found_unknown_field) 55 *error = true; 56 return result.Pass(); 57} 58 59scoped_ptr<base::Value> Mapper::MapPrimitive(const OncValueSignature& signature, 60 const base::Value& onc_primitive, 61 bool* error) { 62 return make_scoped_ptr(onc_primitive.DeepCopy()); 63} 64 65void Mapper::MapFields(const OncValueSignature& object_signature, 66 const base::DictionaryValue& onc_object, 67 bool* found_unknown_field, 68 bool* nested_error, 69 base::DictionaryValue* result) { 70 for (base::DictionaryValue::Iterator it(onc_object); !it.IsAtEnd(); 71 it.Advance()) { 72 bool current_field_unknown = false; 73 scoped_ptr<base::Value> result_value = MapField(it.key(), 74 object_signature, 75 it.value(), 76 ¤t_field_unknown, 77 nested_error); 78 79 if (current_field_unknown) 80 *found_unknown_field = true; 81 else if (result_value.get() != NULL) 82 result->SetWithoutPathExpansion(it.key(), result_value.release()); 83 else 84 DCHECK(*nested_error); 85 } 86} 87 88scoped_ptr<base::Value> Mapper::MapField( 89 const std::string& field_name, 90 const OncValueSignature& object_signature, 91 const base::Value& onc_value, 92 bool* found_unknown_field, 93 bool* error) { 94 const OncFieldSignature* field_signature = 95 GetFieldSignature(object_signature, field_name); 96 97 if (field_signature != NULL) { 98 DCHECK(field_signature->value_signature != NULL) 99 << "Found missing value signature at field '" << field_name << "'."; 100 101 return MapValue(*field_signature->value_signature, onc_value, error); 102 } else { 103 DVLOG(1) << "Found unknown field name: '" << field_name << "'"; 104 *found_unknown_field = true; 105 return scoped_ptr<base::Value>(); 106 } 107} 108 109scoped_ptr<base::ListValue> Mapper::MapArray( 110 const OncValueSignature& array_signature, 111 const base::ListValue& onc_array, 112 bool* nested_error) { 113 DCHECK(array_signature.onc_array_entry_signature != NULL) 114 << "Found missing onc_array_entry_signature."; 115 116 scoped_ptr<base::ListValue> result_array(new base::ListValue); 117 int original_index = 0; 118 for (base::ListValue::const_iterator it = onc_array.begin(); 119 it != onc_array.end(); ++it, ++original_index) { 120 const base::Value* entry = *it; 121 122 scoped_ptr<base::Value> result_entry; 123 result_entry = MapEntry(original_index, 124 *array_signature.onc_array_entry_signature, 125 *entry, 126 nested_error); 127 if (result_entry.get() != NULL) 128 result_array->Append(result_entry.release()); 129 else 130 DCHECK(*nested_error); 131 } 132 return result_array.Pass(); 133} 134 135scoped_ptr<base::Value> Mapper::MapEntry(int index, 136 const OncValueSignature& signature, 137 const base::Value& onc_value, 138 bool* error) { 139 return MapValue(signature, onc_value, error); 140} 141 142} // namespace onc 143} // namespace chromeos 144