Home | History | Annotate | Download | only in test-rpc-proxy
      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