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
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;
00233 }
00234
00235 static void construct(PyObject * obj_ptr, converter::rvalue_from_python_stage1_data * data)
00236 {
00237
00238
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