// // Copyright (C) 2015 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "proxy_util.h" namespace { template<typename VectorType> void GetXmlRpcArrayFromVector( const VectorType& vector_in, XmlRpc::XmlRpcValue* xml_rpc_value_out) { if (vector_in.empty()) { xml_rpc_value_out->setToNil(); return; } int i = 0; for (const auto& value : vector_in) { (*xml_rpc_value_out)[++i] = value; } } void GetXmlRpcStructFromStringMap( const std::map<std::string, std::string>& string_map_in, XmlRpc::XmlRpcValue* xml_rpc_value_out) { if (string_map_in.empty()) { xml_rpc_value_out->setToNil(); return; } for (const auto& value : string_map_in) { (*xml_rpc_value_out)[value.first] = value.second; } } void GetXmlRpcStructFromBrilloVariantDictionary( const brillo::VariantDictionary& var_dict_in, XmlRpc::XmlRpcValue* xml_rpc_value_out) { if (var_dict_in.empty()) { xml_rpc_value_out->setToNil(); return; } for (const auto& value : var_dict_in) { XmlRpc::XmlRpcValue tmp_value; GetXmlRpcValueFromBrilloAnyValue(value.second, &tmp_value); (*xml_rpc_value_out)[value.first] = tmp_value; } } template<typename ElementType> void GetVectorFromXmlRpcArray( XmlRpc::XmlRpcValue* xml_rpc_value_in, std::vector<ElementType>* vector_out) { int array_size = xml_rpc_value_in->size(); for (int i = 0; i < array_size; ++i) { vector_out->push_back(static_cast<ElementType>((*xml_rpc_value_in)[i])); } } void GetBrilloAnyVectorFromXmlRpcArray( XmlRpc::XmlRpcValue* xml_rpc_value_in, brillo::Any* any_value_out) { int array_size = xml_rpc_value_in->size(); if (!array_size) { any_value_out->Clear(); return; } XmlRpc::XmlRpcValue::Type elem_type = (*xml_rpc_value_in)[0].getType(); for (int i = 0; i < array_size; ++i) { CHECK((*xml_rpc_value_in)[i].getType() == elem_type); } switch (elem_type) { case XmlRpc::XmlRpcValue::TypeBoolean: { std::vector<bool> bool_vec; GetVectorFromXmlRpcArray(xml_rpc_value_in, &bool_vec); *any_value_out = bool_vec; return; } case XmlRpc::XmlRpcValue::TypeInt: { std::vector<int> int_vec; GetVectorFromXmlRpcArray(xml_rpc_value_in, &int_vec); *any_value_out = int_vec; return; } case XmlRpc::XmlRpcValue::TypeDouble: { std::vector<double> double_vec; GetVectorFromXmlRpcArray(xml_rpc_value_in, &double_vec); *any_value_out = double_vec; return; } case XmlRpc::XmlRpcValue::TypeString: { std::vector<std::string> string_vec; GetVectorFromXmlRpcArray(xml_rpc_value_in, &string_vec); *any_value_out = string_vec; return; } default: LOG(FATAL) << __func__ << ". Unhandled type: " << (*xml_rpc_value_in)[0].getType(); } } template<typename ValueType> XmlRpc::XmlRpcValue::Type GetXmlRpcType(); template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<bool>() { return XmlRpc::XmlRpcValue::TypeBoolean; } template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<int>() { return XmlRpc::XmlRpcValue::TypeInt; } template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<double>() { return XmlRpc::XmlRpcValue::TypeDouble; } template<> XmlRpc::XmlRpcValue::Type GetXmlRpcType<std::string>() { return XmlRpc::XmlRpcValue::TypeString; } template<typename ValueType> bool IsMemberValuePresent( XmlRpc::XmlRpcValue* xml_rpc_value_in, const std::string& member_name) { if (xml_rpc_value_in->hasMember(member_name) && ((*xml_rpc_value_in)[member_name].getType() == GetXmlRpcType<ValueType>())) { return true; } return false; } template<typename ValueType> bool GetValueFromXmlRpcValueStructMember( XmlRpc::XmlRpcValue* xml_rpc_value_in, const std::string& member_name, ValueType default_value, ValueType* value_out) { if (!IsMemberValuePresent<ValueType>(xml_rpc_value_in, member_name)) { *value_out = default_value; return false; } *value_out = ValueType((*xml_rpc_value_in)[member_name]); return true; } template<typename ElementType> bool IsMemberVectorPresent( XmlRpc::XmlRpcValue* xml_rpc_value_in, const std::string& member_name) { if (xml_rpc_value_in->hasMember(member_name) && ((*xml_rpc_value_in)[member_name].getType() == XmlRpc::XmlRpcValue::TypeArray) && ((*xml_rpc_value_in)[member_name][0].getType() == GetXmlRpcType<ElementType>())) { return true; } return false; } template<typename ElementType> bool GetVectorFromXmlRpcValueStructMember( XmlRpc::XmlRpcValue* xml_rpc_value_in, const std::string& member_name, std::vector<ElementType> default_value, std::vector<ElementType>* value_out) { if (!IsMemberVectorPresent<ElementType>(xml_rpc_value_in, member_name)) { *value_out = default_value; return false; } XmlRpc::XmlRpcValue& xml_rpc_member_array = (*xml_rpc_value_in)[member_name]; int array_size = xml_rpc_member_array.size(); for (int array_pos = 0; array_pos < array_size; ++array_pos) { value_out->push_back(ElementType(xml_rpc_member_array[array_pos])); } return true; } } // namespace void GetXmlRpcValueFromBrilloAnyValue( const brillo::Any& any_value_in, XmlRpc::XmlRpcValue* xml_rpc_value_out) { if (any_value_in.IsTypeCompatible<bool>()) { *xml_rpc_value_out = any_value_in.Get<bool>(); return; } if (any_value_in.IsTypeCompatible<uint8_t>()) { *xml_rpc_value_out = any_value_in.Get<uint8_t>(); return; } if (any_value_in.IsTypeCompatible<uint16_t>()) { *xml_rpc_value_out = any_value_in.Get<uint16_t>(); return; } if (any_value_in.IsTypeCompatible<int>()) { *xml_rpc_value_out = any_value_in.Get<int>(); return; } if (any_value_in.IsTypeCompatible<double>()) { *xml_rpc_value_out = any_value_in.Get<double>(); return; } if (any_value_in.IsTypeCompatible<std::string>()) { *xml_rpc_value_out = any_value_in.Get<std::string>(); return; } if (any_value_in.IsTypeCompatible<dbus::ObjectPath>()) { *xml_rpc_value_out = any_value_in.Get<dbus::ObjectPath>().value(); return; } if (any_value_in.IsTypeCompatible<std::vector<bool>>()) { GetXmlRpcArrayFromVector( any_value_in.Get<std::vector<bool>>(), xml_rpc_value_out); return; } if (any_value_in.IsTypeCompatible<std::vector<uint8_t>>()) { GetXmlRpcArrayFromVector( any_value_in.Get<std::vector<uint8_t>>(), xml_rpc_value_out); return; } if (any_value_in.IsTypeCompatible<std::vector<uint16_t>>()) { GetXmlRpcArrayFromVector( any_value_in.Get<std::vector<uint16_t>>(), xml_rpc_value_out); return; } if (any_value_in.IsTypeCompatible<std::vector<int>>()) { GetXmlRpcArrayFromVector( any_value_in.Get<std::vector<int>>(), xml_rpc_value_out); return; } if (any_value_in.IsTypeCompatible<std::vector<double>>()) { GetXmlRpcArrayFromVector( any_value_in.Get<std::vector<double>>(), xml_rpc_value_out); return; } if (any_value_in.IsTypeCompatible<std::vector<std::string>>()) { GetXmlRpcArrayFromVector( any_value_in.Get<std::vector<std::string>>(), xml_rpc_value_out); return; } if (any_value_in.IsTypeCompatible<std::vector<dbus::ObjectPath>>()) { std::vector<std::string> string_vec; for (const auto& object : any_value_in.Get<std::vector<dbus::ObjectPath>>()) { string_vec.push_back(object.value()); } GetXmlRpcArrayFromVector(string_vec, xml_rpc_value_out); return; } if (any_value_in.IsTypeCompatible<std::map<std::string, std::string>>()) { GetXmlRpcStructFromStringMap( any_value_in.Get<std::map<std::string, std::string>>(), xml_rpc_value_out); return; } if (any_value_in.IsTypeCompatible<brillo::VariantDictionary>()) { GetXmlRpcStructFromBrilloVariantDictionary( any_value_in.Get<brillo::VariantDictionary>(), xml_rpc_value_out); return; } LOG(FATAL) << __func__ << ". Unhandled type: " << any_value_in.GetUndecoratedTypeName(); } void GetBrilloAnyValueFromXmlRpcValue( XmlRpc::XmlRpcValue* xml_rpc_value_in, brillo::Any* any_value_out) { switch (xml_rpc_value_in->getType()) { case XmlRpc::XmlRpcValue::TypeBoolean: *any_value_out = static_cast<bool>(*xml_rpc_value_in); return; case XmlRpc::XmlRpcValue::TypeInt: *any_value_out = static_cast<int>(*xml_rpc_value_in); return; case XmlRpc::XmlRpcValue::TypeDouble: *any_value_out = static_cast<double>(*xml_rpc_value_in); return; case XmlRpc::XmlRpcValue::TypeString: *any_value_out = static_cast<std::string>(*xml_rpc_value_in); return; case XmlRpc::XmlRpcValue::TypeArray: GetBrilloAnyVectorFromXmlRpcArray(xml_rpc_value_in, any_value_out); return; default: LOG(FATAL) << __func__ << ". Unhandled type: " << xml_rpc_value_in->getType(); } } bool GetBoolValueFromXmlRpcValueStructMember( XmlRpc::XmlRpcValue* xml_rpc_value_in, const std::string& member_name, bool default_value, bool* value_out) { return GetValueFromXmlRpcValueStructMember( xml_rpc_value_in, member_name, default_value, value_out); } bool GetIntValueFromXmlRpcValueStructMember( XmlRpc::XmlRpcValue* xml_rpc_value_in, const std::string& member_name, int default_value, int* value_out) { return GetValueFromXmlRpcValueStructMember( xml_rpc_value_in, member_name, default_value, value_out); } bool GetDoubleValueFromXmlRpcValueStructMember( XmlRpc::XmlRpcValue* xml_rpc_value_in, const std::string& member_name, double default_value, double* value_out){ return GetValueFromXmlRpcValueStructMember( xml_rpc_value_in, member_name, default_value, value_out); } bool GetStringValueFromXmlRpcValueStructMember( XmlRpc::XmlRpcValue* xml_rpc_value_in, const std::string& member_name, const std::string& default_value, std::string* value_out) { return GetValueFromXmlRpcValueStructMember( xml_rpc_value_in, member_name, default_value, value_out); } bool 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) { return GetVectorFromXmlRpcValueStructMember( xml_rpc_value_in, member_name, default_value, value_out); }