1 //
2 // Copyright (C) 2015 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "proxy_util.h"
18
19 namespace {
GetXmlRpcArrayFromVector(const VectorType & vector_in,XmlRpc::XmlRpcValue * xml_rpc_value_out)20 template<typename VectorType> void GetXmlRpcArrayFromVector(
21 const VectorType& vector_in,
22 XmlRpc::XmlRpcValue* xml_rpc_value_out) {
23 if (vector_in.empty()) {
24 xml_rpc_value_out->setToNil();
25 return;
26 }
27 int i = 0;
28 for (const auto& value : vector_in) {
29 (*xml_rpc_value_out)[++i] = value;
30 }
31 }
32
GetXmlRpcStructFromStringMap(const std::map<std::string,std::string> & string_map_in,XmlRpc::XmlRpcValue * xml_rpc_value_out)33 void GetXmlRpcStructFromStringMap(
34 const std::map<std::string, std::string>& string_map_in,
35 XmlRpc::XmlRpcValue* xml_rpc_value_out) {
36 if (string_map_in.empty()) {
37 xml_rpc_value_out->setToNil();
38 return;
39 }
40 for (const auto& value : string_map_in) {
41 (*xml_rpc_value_out)[value.first] = value.second;
42 }
43 }
44
GetXmlRpcStructFromBrilloVariantDictionary(const brillo::VariantDictionary & var_dict_in,XmlRpc::XmlRpcValue * xml_rpc_value_out)45 void GetXmlRpcStructFromBrilloVariantDictionary(
46 const brillo::VariantDictionary& var_dict_in,
47 XmlRpc::XmlRpcValue* xml_rpc_value_out) {
48 if (var_dict_in.empty()) {
49 xml_rpc_value_out->setToNil();
50 return;
51 }
52 for (const auto& value : var_dict_in) {
53 XmlRpc::XmlRpcValue tmp_value;
54 GetXmlRpcValueFromBrilloAnyValue(value.second, &tmp_value);
55 (*xml_rpc_value_out)[value.first] = tmp_value;
56 }
57 }
58
GetVectorFromXmlRpcArray(XmlRpc::XmlRpcValue * xml_rpc_value_in,std::vector<ElementType> * vector_out)59 template<typename ElementType> void GetVectorFromXmlRpcArray(
60 XmlRpc::XmlRpcValue* xml_rpc_value_in,
61 std::vector<ElementType>* vector_out) {
62 int array_size = xml_rpc_value_in->size();
63 for (int i = 0; i < array_size; ++i) {
64 vector_out->push_back(static_cast<ElementType>((*xml_rpc_value_in)[i]));
65 }
66 }
67
GetBrilloAnyVectorFromXmlRpcArray(XmlRpc::XmlRpcValue * xml_rpc_value_in,brillo::Any * any_value_out)68 void GetBrilloAnyVectorFromXmlRpcArray(
69 XmlRpc::XmlRpcValue* xml_rpc_value_in,
70 brillo::Any* any_value_out) {
71 int array_size = xml_rpc_value_in->size();
72 if (!array_size) {
73 any_value_out->Clear();
74 return;
75 }
76 XmlRpc::XmlRpcValue::Type elem_type = (*xml_rpc_value_in)[0].getType();
77 for (int i = 0; i < array_size; ++i) {
78 CHECK((*xml_rpc_value_in)[i].getType() == elem_type);
79 }
80 switch (elem_type) {
81 case XmlRpc::XmlRpcValue::TypeBoolean: {
82 std::vector<bool> bool_vec;
83 GetVectorFromXmlRpcArray(xml_rpc_value_in, &bool_vec);
84 *any_value_out = bool_vec;
85 return;
86 }
87 case XmlRpc::XmlRpcValue::TypeInt: {
88 std::vector<int> int_vec;
89 GetVectorFromXmlRpcArray(xml_rpc_value_in, &int_vec);
90 *any_value_out = int_vec;
91 return;
92 }
93 case XmlRpc::XmlRpcValue::TypeDouble: {
94 std::vector<double> double_vec;
95 GetVectorFromXmlRpcArray(xml_rpc_value_in, &double_vec);
96 *any_value_out = double_vec;
97 return;
98 }
99 case XmlRpc::XmlRpcValue::TypeString: {
100 std::vector<std::string> string_vec;
101 GetVectorFromXmlRpcArray(xml_rpc_value_in, &string_vec);
102 *any_value_out = string_vec;
103 return;
104 }
105 default:
106 LOG(FATAL) << __func__ << ". Unhandled type: "
107 << (*xml_rpc_value_in)[0].getType();
108 }
109 }
110
111 template<typename ValueType> XmlRpc::XmlRpcValue::Type GetXmlRpcType();
GetXmlRpcType()112 template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<bool>() {
113 return XmlRpc::XmlRpcValue::TypeBoolean;
114 }
GetXmlRpcType()115 template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<int>() {
116 return XmlRpc::XmlRpcValue::TypeInt;
117 }
GetXmlRpcType()118 template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<double>() {
119 return XmlRpc::XmlRpcValue::TypeDouble;
120 }
GetXmlRpcType()121 template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<std::string>() {
122 return XmlRpc::XmlRpcValue::TypeString;
123 }
124
IsMemberValuePresent(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name)125 template<typename ValueType> bool IsMemberValuePresent(
126 XmlRpc::XmlRpcValue* xml_rpc_value_in,
127 const std::string& member_name) {
128 if (xml_rpc_value_in->hasMember(member_name) &&
129 ((*xml_rpc_value_in)[member_name].getType() ==
130 GetXmlRpcType<ValueType>())) {
131 return true;
132 }
133 return false;
134 }
135
GetValueFromXmlRpcValueStructMember(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name,ValueType default_value,ValueType * value_out)136 template<typename ValueType> bool GetValueFromXmlRpcValueStructMember(
137 XmlRpc::XmlRpcValue* xml_rpc_value_in,
138 const std::string& member_name,
139 ValueType default_value,
140 ValueType* value_out) {
141 if (!IsMemberValuePresent<ValueType>(xml_rpc_value_in, member_name)) {
142 *value_out = default_value;
143 return false;
144 }
145 *value_out = ValueType((*xml_rpc_value_in)[member_name]);
146 return true;
147 }
148
IsMemberVectorPresent(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name)149 template<typename ElementType> bool IsMemberVectorPresent(
150 XmlRpc::XmlRpcValue* xml_rpc_value_in,
151 const std::string& member_name) {
152 if (xml_rpc_value_in->hasMember(member_name) &&
153 ((*xml_rpc_value_in)[member_name].getType() ==
154 XmlRpc::XmlRpcValue::TypeArray) &&
155 ((*xml_rpc_value_in)[member_name][0].getType() ==
156 GetXmlRpcType<ElementType>())) {
157 return true;
158 }
159 return false;
160 }
161
GetVectorFromXmlRpcValueStructMember(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name,std::vector<ElementType> default_value,std::vector<ElementType> * value_out)162 template<typename ElementType> bool GetVectorFromXmlRpcValueStructMember(
163 XmlRpc::XmlRpcValue* xml_rpc_value_in,
164 const std::string& member_name,
165 std::vector<ElementType> default_value,
166 std::vector<ElementType>* value_out) {
167 if (!IsMemberVectorPresent<ElementType>(xml_rpc_value_in, member_name)) {
168 *value_out = default_value;
169 return false;
170 }
171 XmlRpc::XmlRpcValue& xml_rpc_member_array = (*xml_rpc_value_in)[member_name];
172 int array_size = xml_rpc_member_array.size();
173 for (int array_pos = 0; array_pos < array_size; ++array_pos) {
174 value_out->push_back(ElementType(xml_rpc_member_array[array_pos]));
175 }
176 return true;
177 }
178 } // namespace
179
GetXmlRpcValueFromBrilloAnyValue(const brillo::Any & any_value_in,XmlRpc::XmlRpcValue * xml_rpc_value_out)180 void GetXmlRpcValueFromBrilloAnyValue(
181 const brillo::Any& any_value_in,
182 XmlRpc::XmlRpcValue* xml_rpc_value_out) {
183 if (any_value_in.IsTypeCompatible<bool>()) {
184 *xml_rpc_value_out = any_value_in.Get<bool>();
185 return;
186 }
187 if (any_value_in.IsTypeCompatible<uint8_t>()) {
188 *xml_rpc_value_out = any_value_in.Get<uint8_t>();
189 return;
190 }
191 if (any_value_in.IsTypeCompatible<uint16_t>()) {
192 *xml_rpc_value_out = any_value_in.Get<uint16_t>();
193 return;
194 }
195 if (any_value_in.IsTypeCompatible<int>()) {
196 *xml_rpc_value_out = any_value_in.Get<int>();
197 return;
198 }
199 if (any_value_in.IsTypeCompatible<double>()) {
200 *xml_rpc_value_out = any_value_in.Get<double>();
201 return;
202 }
203 if (any_value_in.IsTypeCompatible<std::string>()) {
204 *xml_rpc_value_out = any_value_in.Get<std::string>();
205 return;
206 }
207 if (any_value_in.IsTypeCompatible<dbus::ObjectPath>()) {
208 *xml_rpc_value_out = any_value_in.Get<dbus::ObjectPath>().value();
209 return;
210 }
211 if (any_value_in.IsTypeCompatible<std::vector<bool>>()) {
212 GetXmlRpcArrayFromVector(
213 any_value_in.Get<std::vector<bool>>(), xml_rpc_value_out);
214 return;
215 }
216 if (any_value_in.IsTypeCompatible<std::vector<uint8_t>>()) {
217 GetXmlRpcArrayFromVector(
218 any_value_in.Get<std::vector<uint8_t>>(), xml_rpc_value_out);
219 return;
220 }
221 if (any_value_in.IsTypeCompatible<std::vector<uint16_t>>()) {
222 GetXmlRpcArrayFromVector(
223 any_value_in.Get<std::vector<uint16_t>>(), xml_rpc_value_out);
224 return;
225 }
226 if (any_value_in.IsTypeCompatible<std::vector<int>>()) {
227 GetXmlRpcArrayFromVector(
228 any_value_in.Get<std::vector<int>>(), xml_rpc_value_out);
229 return;
230 }
231 if (any_value_in.IsTypeCompatible<std::vector<double>>()) {
232 GetXmlRpcArrayFromVector(
233 any_value_in.Get<std::vector<double>>(), xml_rpc_value_out);
234 return;
235 }
236 if (any_value_in.IsTypeCompatible<std::vector<std::string>>()) {
237 GetXmlRpcArrayFromVector(
238 any_value_in.Get<std::vector<std::string>>(), xml_rpc_value_out);
239 return;
240 }
241 if (any_value_in.IsTypeCompatible<std::vector<dbus::ObjectPath>>()) {
242 std::vector<std::string> string_vec;
243 for (const auto& object : any_value_in.Get<std::vector<dbus::ObjectPath>>()) {
244 string_vec.push_back(object.value());
245 }
246 GetXmlRpcArrayFromVector(string_vec, xml_rpc_value_out);
247 return;
248 }
249 if (any_value_in.IsTypeCompatible<std::map<std::string, std::string>>()) {
250 GetXmlRpcStructFromStringMap(
251 any_value_in.Get<std::map<std::string, std::string>>(), xml_rpc_value_out);
252 return;
253 }
254 if (any_value_in.IsTypeCompatible<brillo::VariantDictionary>()) {
255 GetXmlRpcStructFromBrilloVariantDictionary(
256 any_value_in.Get<brillo::VariantDictionary>(), xml_rpc_value_out);
257 return;
258 }
259 LOG(FATAL) << __func__ << ". Unhandled type: "
260 << any_value_in.GetUndecoratedTypeName();
261 }
262
GetBrilloAnyValueFromXmlRpcValue(XmlRpc::XmlRpcValue * xml_rpc_value_in,brillo::Any * any_value_out)263 void GetBrilloAnyValueFromXmlRpcValue(
264 XmlRpc::XmlRpcValue* xml_rpc_value_in,
265 brillo::Any* any_value_out) {
266 switch (xml_rpc_value_in->getType()) {
267 case XmlRpc::XmlRpcValue::TypeBoolean:
268 *any_value_out = static_cast<bool>(*xml_rpc_value_in);
269 return;
270 case XmlRpc::XmlRpcValue::TypeInt:
271 *any_value_out = static_cast<int>(*xml_rpc_value_in);
272 return;
273 case XmlRpc::XmlRpcValue::TypeDouble:
274 *any_value_out = static_cast<double>(*xml_rpc_value_in);
275 return;
276 case XmlRpc::XmlRpcValue::TypeString:
277 *any_value_out = static_cast<std::string>(*xml_rpc_value_in);
278 return;
279 case XmlRpc::XmlRpcValue::TypeArray:
280 GetBrilloAnyVectorFromXmlRpcArray(xml_rpc_value_in, any_value_out);
281 return;
282 default:
283 LOG(FATAL) << __func__ << ". Unhandled type: "
284 << xml_rpc_value_in->getType();
285 }
286 }
287
GetBoolValueFromXmlRpcValueStructMember(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name,bool default_value,bool * value_out)288 bool GetBoolValueFromXmlRpcValueStructMember(
289 XmlRpc::XmlRpcValue* xml_rpc_value_in,
290 const std::string& member_name,
291 bool default_value,
292 bool* value_out) {
293 return GetValueFromXmlRpcValueStructMember(
294 xml_rpc_value_in, member_name, default_value, value_out);
295 }
296
GetIntValueFromXmlRpcValueStructMember(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name,int default_value,int * value_out)297 bool GetIntValueFromXmlRpcValueStructMember(
298 XmlRpc::XmlRpcValue* xml_rpc_value_in,
299 const std::string& member_name,
300 int default_value,
301 int* value_out) {
302 return GetValueFromXmlRpcValueStructMember(
303 xml_rpc_value_in, member_name, default_value, value_out);
304 }
305
GetDoubleValueFromXmlRpcValueStructMember(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name,double default_value,double * value_out)306 bool GetDoubleValueFromXmlRpcValueStructMember(
307 XmlRpc::XmlRpcValue* xml_rpc_value_in,
308 const std::string& member_name,
309 double default_value,
310 double* value_out){
311 return GetValueFromXmlRpcValueStructMember(
312 xml_rpc_value_in, member_name, default_value, value_out);
313 }
314
GetStringValueFromXmlRpcValueStructMember(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name,const std::string & default_value,std::string * value_out)315 bool GetStringValueFromXmlRpcValueStructMember(
316 XmlRpc::XmlRpcValue* xml_rpc_value_in,
317 const std::string& member_name,
318 const std::string& default_value,
319 std::string* value_out) {
320 return GetValueFromXmlRpcValueStructMember(
321 xml_rpc_value_in, member_name, default_value, value_out);
322 }
323
GetStringVectorFromXmlRpcValueStructMember(XmlRpc::XmlRpcValue * xml_rpc_value_in,const std::string & member_name,const std::vector<std::string> & default_value,std::vector<std::string> * value_out)324 bool GetStringVectorFromXmlRpcValueStructMember(
325 XmlRpc::XmlRpcValue* xml_rpc_value_in,
326 const std::string& member_name,
327 const std::vector<std::string>& default_value,
328 std::vector<std::string>* value_out) {
329 return GetVectorFromXmlRpcValueStructMember(
330 xml_rpc_value_in, member_name, default_value, value_out);
331 }
332