1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef BRILLO_VALUE_CONVERSION_H_
16 #define BRILLO_VALUE_CONVERSION_H_
17
18 // This file provides a set of helper functions to convert between base::Value
19 // and native types. Apart from handling standard types such as 'int' and
20 // 'std::string' it also provides conversion to/from std::vector<T> (which
21 // converts to Base::listValue) and std::map<std::string, T> (convertible to
22 // base::DictionaryValue).
23
24 #include <map>
25 #include <memory>
26 #include <string>
27 #include <vector>
28
29 #include <base/values.h>
30 #include <brillo/brillo_export.h>
31
32 namespace brillo {
33
FromValue(const base::Value & in_value,bool * out_value)34 inline bool FromValue(const base::Value& in_value, bool* out_value) {
35 return in_value.GetAsBoolean(out_value);
36 }
37
FromValue(const base::Value & in_value,int * out_value)38 inline bool FromValue(const base::Value& in_value, int* out_value) {
39 return in_value.GetAsInteger(out_value);
40 }
41
FromValue(const base::Value & in_value,double * out_value)42 inline bool FromValue(const base::Value& in_value, double* out_value) {
43 return in_value.GetAsDouble(out_value);
44 }
45
FromValue(const base::Value & in_value,std::string * out_value)46 inline bool FromValue(const base::Value& in_value, std::string* out_value) {
47 return in_value.GetAsString(out_value);
48 }
49
FromValue(const base::Value & in_value,const base::ListValue ** out_value)50 inline bool FromValue(const base::Value& in_value,
51 const base::ListValue** out_value) {
52 return in_value.GetAsList(out_value);
53 }
54
FromValue(const base::Value & in_value,const base::DictionaryValue ** out_value)55 inline bool FromValue(const base::Value& in_value,
56 const base::DictionaryValue** out_value) {
57 return in_value.GetAsDictionary(out_value);
58 }
59
60 BRILLO_EXPORT bool FromValue(const base::Value& in_value,
61 std::unique_ptr<base::ListValue>* out_value);
62 BRILLO_EXPORT bool FromValue(const base::Value& in_value,
63 std::unique_ptr<base::DictionaryValue>* out_value);
64
65 template <typename T, typename Pred, typename Alloc>
66 bool FromValue(const base::Value& in_value,
67 std::map<std::string, T, Pred, Alloc>* out_value);
68
69 template <typename T, typename Alloc>
FromValue(const base::Value & in_value,std::vector<T,Alloc> * out_value)70 bool FromValue(const base::Value& in_value, std::vector<T, Alloc>* out_value) {
71 const base::ListValue* list = nullptr;
72 if (!in_value.GetAsList(&list))
73 return false;
74 out_value->clear();
75 out_value->reserve(list->GetSize());
76 for (const base::Value* item : *list) {
77 T value{};
78 if (!FromValue(*item, &value))
79 return false;
80 out_value->push_back(std::move(value));
81 }
82 return true;
83 }
84
85 template <typename T, typename Pred, typename Alloc>
FromValue(const base::Value & in_value,std::map<std::string,T,Pred,Alloc> * out_value)86 bool FromValue(const base::Value& in_value,
87 std::map<std::string, T, Pred, Alloc>* out_value) {
88 const base::DictionaryValue* dict = nullptr;
89 if (!in_value.GetAsDictionary(&dict))
90 return false;
91 out_value->clear();
92 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
93 if (!FromValue(it.value(), &(*out_value)[it.key()]))
94 return false;
95 }
96 return true;
97 }
98
99 template <typename T>
FromValue(const base::Value & value)100 T FromValue(const base::Value& value) {
101 T out_value{};
102 CHECK(FromValue(value, &out_value));
103 return out_value;
104 }
105
106 BRILLO_EXPORT std::unique_ptr<base::Value> ToValue(int value);
107 BRILLO_EXPORT std::unique_ptr<base::Value> ToValue(bool value);
108 BRILLO_EXPORT std::unique_ptr<base::Value> ToValue(double value);
109 BRILLO_EXPORT std::unique_ptr<base::Value> ToValue(const std::string& value);
110 // Implicit conversion of char* to 'bool' has precedence over the user-defined
111 // std::string conversion. Override this behavior explicitly.
112 BRILLO_EXPORT std::unique_ptr<base::Value> ToValue(const char* value);
113
114 template <typename T, typename Pred, typename Alloc>
115 std::unique_ptr<base::Value> ToValue(
116 const std::map<std::string, T, Pred, Alloc>& dictionary);
117
118 template <typename T, typename Alloc>
ToValue(const std::vector<T,Alloc> & list)119 std::unique_ptr<base::Value> ToValue(const std::vector<T, Alloc>& list) {
120 std::unique_ptr<base::ListValue> result{new base::ListValue};
121 for (const auto& value : list) {
122 result->Append(ToValue(value).release());
123 }
124 return std::move(result);
125 }
126
127 template <typename T, typename Pred, typename Alloc>
ToValue(const std::map<std::string,T,Pred,Alloc> & dictionary)128 std::unique_ptr<base::Value> ToValue(
129 const std::map<std::string, T, Pred, Alloc>& dictionary) {
130 std::unique_ptr<base::DictionaryValue> result{new base::DictionaryValue};
131 for (const auto& pair : dictionary) {
132 result->Set(pair.first, ToValue(pair.second).release());
133 }
134 return std::move(result);
135 }
136
137 } // namespace brillo
138
139 #endif // BRILLO_VALUE_CONVERSION_H_
140