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 auto& 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));
123   return std::move(result);
124 }
125 
126 template <typename T, typename Pred, typename Alloc>
ToValue(const std::map<std::string,T,Pred,Alloc> & dictionary)127 std::unique_ptr<base::Value> ToValue(
128     const std::map<std::string, T, Pred, Alloc>& dictionary) {
129   std::unique_ptr<base::DictionaryValue> result{new base::DictionaryValue};
130   for (const auto& pair : dictionary)
131     result->Set(pair.first, ToValue(pair.second));
132   return std::move(result);
133 }
134 
135 }  // namespace brillo
136 
137 #endif  // BRILLO_VALUE_CONVERSION_H_
138