331 lines
11 KiB
C++
331 lines
11 KiB
C++
//
|
|
// 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);
|
|
}
|