py_opcua_variant.h
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #pragma once
00012 
00013 #include <boost/python.hpp>
00014 
00015 #include "opc/ua/protocol/variant_visitor.h"
00016 
00017 using namespace boost::python;
00018 
00019 template <typename T>
00020 list ToList(const std::vector<T> objects)
00021 {
00022   list result;
00023 
00024   for (auto obj : objects)
00025     {
00026       result.append(obj);
00027     }
00028 
00029   return result;
00030 }
00031 
00032 template <typename ResultType, typename SourceType>
00033 list ToList(const std::vector<SourceType> objects)
00034 {
00035   list result;
00036 
00037   for (auto obj : objects)
00038     {
00039       result.append(ResultType(obj));
00040     }
00041 
00042   return result;
00043 }
00044 
00045 template <typename T>
00046 std::vector<T> ToVector(const object & list)
00047 {
00048   std::vector<T> result;
00049   std::size_t listSize = len(list);
00050 
00051   for (std::size_t i = 0; i < listSize; ++i)
00052     {
00053       const object & element = list[i];
00054       const T & value = extract<T>(element)();
00055       result.push_back(value);
00056     }
00057 
00058   return result;
00059 }
00060 
00061 struct VariantToPythonObjectConverter
00062 {
00063   object Result;
00064 
00065   template <typename T>
00066   void OnContainer(const T & val)
00067   {
00068     Result = ToList(val);
00069   }
00070 
00071   template <typename T>
00072   void OnScalar(const T & val)
00073   {
00074     Result = object(val);
00075   }
00076 };
00077 
00078 object ToObject(const Variant & var)
00079 {
00080   if (var.IsNul())
00081     {
00082       return object();
00083     }
00084 
00085   VariantToPythonObjectConverter objectConverter;
00086   OpcUa::TypedVisitor<VariantToPythonObjectConverter> visitor(objectConverter);
00087   var.Visit(visitor);
00088   return objectConverter.Result;
00089 }
00090 
00091 Variant ToVariant(const object & obj)
00092 {
00093   Variant var;
00094 
00095   if (extract<std::string>(obj).check())
00096     {
00097       var = extract<std::string>(obj)();
00098     }
00099 
00100   else if (extract<list>(obj).check())
00101     {
00102 
00103       if (len(obj) > 0)
00104         {
00105           if (extract<long>(obj[0]).check())
00106             {
00107               var = ToVector<long>(obj);
00108             }
00109 
00110           else if (extract<double>(obj[0]).check())
00111             {
00112               var = ToVector<double>(obj);
00113             }
00114 
00115           else if (extract<std::vector<std::string>>(obj).check())
00116             {
00117               var = extract<std::vector<std::string>>(obj)();
00118             }
00119 
00120           else if (extract<std::vector<NodeId>>(obj).check())
00121             {
00122               var = extract<std::vector<NodeId>>(obj)();
00123             }
00124 
00125           else if (extract<std::vector<DateTime>>(obj).check())
00126             {
00127               var = extract<std::vector<DateTime>>(obj)();
00128             }
00129           else
00130             {
00131               throw std::logic_error("Cannot create variant from python list. Unsupported type.");
00132             }
00133         }
00134     }
00135 
00136   else if (extract<long>(obj).check())
00137     {
00138       var = extract<long>(obj)();
00139     }
00140 
00141   else if (extract<double>(obj).check())
00142     {
00143       var = extract<double>(obj)();
00144     }
00145 
00146   else if (extract<NodeId>(obj).check())
00147     {
00148       var = extract<NodeId>(obj)();
00149     }
00150   else if (extract<DateTime>(obj).check())
00151     {
00152       var = extract<DateTime>(obj)();
00153     }
00154   else
00155     {
00156       throw std::logic_error("Cannot create variant from python object. Unsupported type.");
00157     }
00158 
00159   return var;
00160 }
00161 
00162 
00163 //similar to ToVariant but gives a hint to what c++ object type the python object should be converted to
00164 Variant ToVariant2(const object & obj, VariantType vtype)
00165 {
00166   Variant var;
00167 
00168   if (extract<list>(obj).check())
00169     {
00170 
00171       if (len(obj) == 0)
00172         {
00173           return var;
00174         }
00175 
00176       else
00177         {
00178           switch (vtype)
00179             {
00180             case VariantType::BOOLEAN:
00181               var = ToVector<bool>(obj);
00182               return var;
00183 
00184             case VariantType::UINT16:
00185             case VariantType::UINT32:
00186               var = ToVector<uint32_t>(obj);
00187               return var;
00188 
00189             case VariantType::FLOAT:
00190               var = ToVector<float>(obj);
00191               return var;
00192 
00193             default:
00194               return ToVariant(obj);
00195             }
00196         }
00197     }
00198 
00199   else
00200     {
00201       switch (vtype)
00202         {
00203         case VariantType::BOOLEAN:
00204           var = extract<bool>(obj)();
00205           return var;
00206 
00207         case VariantType::UINT16:
00208         case VariantType::UINT32:
00209           var = extract<uint32_t>(obj)();
00210           return var;
00211 
00212         case VariantType::FLOAT:
00213           var = extract<float>(obj)();
00214           return var;
00215 
00216         default:
00217           return ToVariant(obj);
00218         }
00219     }
00220 }
00221 
00222 
00223 struct variant_from_python_converter
00224 {
00225   variant_from_python_converter()
00226   {
00227     converter::registry::push_back(&convertible, &construct, type_id<Variant>());
00228   }
00229 
00230   static void * convertible(PyObject * obj_ptr)
00231   {
00232     return obj_ptr; // TODO XXX
00233   }
00234 
00235   static void construct(PyObject * obj_ptr, converter::rvalue_from_python_stage1_data * data)
00236   {
00237     // Use borrowed to construct the object so that a reference
00238     // count will be properly handled.
00239     object obj = object(handle<>(borrowed(obj_ptr)));
00240 
00241     void * storage = ((converter::rvalue_from_python_storage<Variant> *)data)->storage.bytes;
00242 
00243     new(storage) Variant(ToVariant(obj));
00244 
00245     data->convertible = storage;
00246 
00247   }
00248 };
00249 
00250 
00251 struct variant_to_python_converter
00252 {
00253   static PyObject * convert(Variant const & v)
00254   {
00255 
00256     if (v.IsNul())
00257       {
00258         Py_INCREF(Py_None);
00259         return Py_None;
00260       }
00261 
00262     object obj = ToObject(v);
00263 
00264     return incref(obj.ptr());
00265   }
00266 };
00267 


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Sat Jun 8 2019 18:24:56