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 <utility>
8
9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/values.h"
12 #include "chromeos/network/onc/onc_signature.h"
13
14 namespace chromeos {
15 namespace onc {
16
17 Mapper::Mapper() = default;
18
19 Mapper::~Mapper() = default;
20
MapValue(const OncValueSignature & signature,const base::Value & onc_value,bool * error)21 std::unique_ptr<base::Value> Mapper::MapValue(
22 const OncValueSignature& signature,
23 const base::Value& onc_value,
24 bool* error) {
25 std::unique_ptr<base::Value> result_value;
26 switch (onc_value.type()) {
27 case base::Value::Type::DICTIONARY: {
28 const base::DictionaryValue* dict = NULL;
29 onc_value.GetAsDictionary(&dict);
30 result_value = MapObject(signature, *dict, error);
31 break;
32 }
33 case base::Value::Type::LIST: {
34 const base::ListValue* list = NULL;
35 onc_value.GetAsList(&list);
36 result_value = MapArray(signature, *list, error);
37 break;
38 }
39 default: {
40 result_value = MapPrimitive(signature, onc_value, error);
41 break;
42 }
43 }
44
45 return result_value;
46 }
47
MapObject(const OncValueSignature & signature,const base::Value & onc_object,bool * error)48 std::unique_ptr<base::DictionaryValue> Mapper::MapObject(
49 const OncValueSignature& signature,
50 const base::Value& onc_object,
51 bool* error) {
52 std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue);
53
54 bool found_unknown_field = false;
55 MapFields(signature, onc_object, &found_unknown_field, error, result.get());
56 if (found_unknown_field)
57 *error = true;
58 return result;
59 }
60
MapPrimitive(const OncValueSignature & signature,const base::Value & onc_primitive,bool * error)61 std::unique_ptr<base::Value> Mapper::MapPrimitive(
62 const OncValueSignature& signature,
63 const base::Value& onc_primitive,
64 bool* error) {
65 return base::WrapUnique(onc_primitive.DeepCopy());
66 }
67
MapFields(const OncValueSignature & object_signature,const base::Value & onc_object,bool * found_unknown_field,bool * nested_error,base::DictionaryValue * result)68 void Mapper::MapFields(const OncValueSignature& object_signature,
69 const base::Value& onc_object,
70 bool* found_unknown_field,
71 bool* nested_error,
72 base::DictionaryValue* result) {
73 DCHECK(onc_object.is_dict());
74 for (auto it : onc_object.DictItems()) {
75 bool current_field_unknown = false;
76 std::unique_ptr<base::Value> result_value =
77 MapField(it.first, object_signature, it.second, ¤t_field_unknown,
78 nested_error);
79
80 if (current_field_unknown)
81 *found_unknown_field = true;
82 else if (result_value.get() != NULL)
83 result->SetWithoutPathExpansion(it.first, std::move(result_value));
84 else
85 DCHECK(*nested_error);
86 }
87 }
88
MapField(const std::string & field_name,const OncValueSignature & object_signature,const base::Value & onc_value,bool * found_unknown_field,bool * error)89 std::unique_ptr<base::Value> Mapper::MapField(
90 const std::string& field_name,
91 const OncValueSignature& object_signature,
92 const base::Value& onc_value,
93 bool* found_unknown_field,
94 bool* error) {
95 const OncFieldSignature* field_signature =
96 GetFieldSignature(object_signature, field_name);
97
98 if (field_signature != NULL) {
99 DCHECK(field_signature->value_signature != NULL)
100 << "Found missing value signature at field '" << field_name << "'.";
101
102 return MapValue(*field_signature->value_signature, onc_value, error);
103 } else {
104 DVLOG(1) << "Found unknown field name: '" << field_name << "'";
105 *found_unknown_field = true;
106 return std::unique_ptr<base::Value>();
107 }
108 }
109
MapArray(const OncValueSignature & array_signature,const base::ListValue & onc_array,bool * nested_error)110 std::unique_ptr<base::ListValue> Mapper::MapArray(
111 const OncValueSignature& array_signature,
112 const base::ListValue& onc_array,
113 bool* nested_error) {
114 DCHECK(array_signature.onc_array_entry_signature != NULL)
115 << "Found missing onc_array_entry_signature.";
116
117 std::unique_ptr<base::ListValue> result_array(new base::ListValue);
118 int original_index = 0;
119 for (const auto& entry : onc_array) {
120 std::unique_ptr<base::Value> result_entry;
121 result_entry =
122 MapEntry(original_index, *array_signature.onc_array_entry_signature,
123 entry, nested_error);
124 if (result_entry.get() != NULL)
125 result_array->Append(std::move(result_entry));
126 else
127 DCHECK(*nested_error);
128 ++original_index;
129 }
130 return result_array;
131 }
132
MapEntry(int index,const OncValueSignature & signature,const base::Value & onc_value,bool * error)133 std::unique_ptr<base::Value> Mapper::MapEntry(
134 int index,
135 const OncValueSignature& signature,
136 const base::Value& onc_value,
137 bool* error) {
138 return MapValue(signature, onc_value, error);
139 }
140
141 } // namespace onc
142 } // namespace chromeos
143