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
11 namespace chromeos {
12 namespace onc {
13
Mapper()14 Mapper::Mapper() {
15 }
16
~Mapper()17 Mapper::~Mapper() {
18 }
19
MapValue(const OncValueSignature & signature,const base::Value & onc_value,bool * error)20 scoped_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
MapObject(const OncValueSignature & signature,const base::DictionaryValue & onc_object,bool * error)46 scoped_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
MapPrimitive(const OncValueSignature & signature,const base::Value & onc_primitive,bool * error)59 scoped_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
MapFields(const OncValueSignature & object_signature,const base::DictionaryValue & onc_object,bool * found_unknown_field,bool * nested_error,base::DictionaryValue * result)65 void 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
MapField(const std::string & field_name,const OncValueSignature & object_signature,const base::Value & onc_value,bool * found_unknown_field,bool * error)88 scoped_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
MapArray(const OncValueSignature & array_signature,const base::ListValue & onc_array,bool * nested_error)109 scoped_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
MapEntry(int index,const OncValueSignature & signature,const base::Value & onc_value,bool * error)135 scoped_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