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 { 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 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 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 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 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(); 112 template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<bool>() { 113 return XmlRpc::XmlRpcValue::TypeBoolean; 114 } 115 template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<int>() { 116 return XmlRpc::XmlRpcValue::TypeInt; 117 } 118 template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<double>() { 119 return XmlRpc::XmlRpcValue::TypeDouble; 120 } 121 template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<std::string>() { 122 return XmlRpc::XmlRpcValue::TypeString; 123 } 124 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 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 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 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 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 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 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 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 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 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 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