py_opcua_variant.h
Go to the documentation of this file.
1 
11 #pragma once
12 
13 #include <boost/python.hpp>
14 
16 
17 using namespace boost::python;
18 
19 template <typename T>
20 list ToList(const std::vector<T> objects)
21 {
22  list result;
23 
24  for (T obj : objects)
25  {
26  result.append(obj);
27  }
28 
29  return result;
30 }
31 
32 template <typename ResultType, typename SourceType>
33 list ToList(const std::vector<SourceType> objects)
34 {
35  list result;
36 
37  for (auto obj : objects)
38  {
39  result.append(ResultType(obj));
40  }
41 
42  return result;
43 }
44 
45 template <typename T>
46 std::vector<T> ToVector(const object & list)
47 {
48  std::vector<T> result;
49  std::size_t listSize = len(list);
50 
51  for (std::size_t i = 0; i < listSize; ++i)
52  {
53  const object & element = list[i];
54  const T & value = extract<T>(element)();
55  result.push_back(value);
56  }
57 
58  return result;
59 }
60 
62 {
63  object Result;
64 
65  template <typename T>
66  void OnContainer(const T & val)
67  {
68  Result = ToList(val);
69  }
70 
71  template <typename T>
72  void OnScalar(const T & val)
73  {
74  Result = object(val);
75  }
76 };
77 
78 object ToObject(const Variant & var)
79 {
80  if (var.IsNul())
81  {
82  return object();
83  }
84 
85  VariantToPythonObjectConverter objectConverter;
87  var.Visit(visitor);
88  return objectConverter.Result;
89 }
90 
91 Variant ToVariant(const object & obj)
92 {
93  Variant var;
94 
95  if (extract<std::string>(obj).check())
96  {
97  var = extract<std::string>(obj)();
98  }
99 
100  else if (extract<list>(obj).check())
101  {
102 
103  if (len(obj) > 0)
104  {
105  if (extract<long>(obj[0]).check())
106  {
107  var = ToVector<long>(obj);
108  }
109 
110  else if (extract<double>(obj[0]).check())
111  {
112  var = ToVector<double>(obj);
113  }
114 
115  else if (extract<std::vector<std::string>>(obj).check())
116  {
117  var = extract<std::vector<std::string>>(obj)();
118  }
119 
120  else if (extract<std::vector<NodeId>>(obj).check())
121  {
122  var = extract<std::vector<NodeId>>(obj)();
123  }
124 
125  else if (extract<std::vector<DateTime>>(obj).check())
126  {
127  var = extract<std::vector<DateTime>>(obj)();
128  }
129 
130  else
131  {
132  throw std::logic_error("Cannot create variant from python list. Unsupported type.");
133  }
134  }
135  }
136 
137  else if (extract<long>(obj).check())
138  {
139  var = extract<long>(obj)();
140  }
141 
142  else if (extract<double>(obj).check())
143  {
144  var = extract<double>(obj)();
145  }
146 
147  else if (extract<NodeId>(obj).check())
148  {
149  var = extract<NodeId>(obj)();
150  }
151 
152  else if (extract<DateTime>(obj).check())
153  {
154  var = extract<DateTime>(obj)();
155  }
156 
157  else
158  {
159  throw std::logic_error("Cannot create variant from python object. Unsupported type.");
160  }
161 
162  return var;
163 }
164 
165 
166 //similar to ToVariant but gives a hint to what c++ object type the python object should be converted to
167 Variant ToVariant2(const object & obj, VariantType vtype)
168 {
169  Variant var;
170 
171  if (extract<list>(obj).check())
172  {
173 
174  if (len(obj) == 0)
175  {
176  return var;
177  }
178 
179  else
180  {
181  switch (vtype)
182  {
183  case VariantType::BOOLEAN:
184  var = ToVector<bool>(obj);
185  return var;
186 
187  case VariantType::UINT16:
188  case VariantType::UINT32:
189  var = ToVector<uint32_t>(obj);
190  return var;
191 
192  case VariantType::FLOAT:
193  var = ToVector<float>(obj);
194  return var;
195 
196  default:
197  return ToVariant(obj);
198  }
199  }
200  }
201 
202  else
203  {
204  switch (vtype)
205  {
206  case VariantType::BOOLEAN:
207  var = extract<bool>(obj)();
208  return var;
209 
210  case VariantType::UINT16:
211  case VariantType::UINT32:
212  var = extract<uint32_t>(obj)();
213  return var;
214 
215  case VariantType::FLOAT:
216  var = extract<float>(obj)();
217  return var;
218 
219  default:
220  return ToVariant(obj);
221  }
222  }
223 }
224 
225 
227 {
229  {
230  converter::registry::push_back(&convertible, &construct, type_id<Variant>());
231  }
232 
233  static void * convertible(PyObject * obj_ptr)
234  {
235  return obj_ptr; // TODO XXX
236  }
237 
238  static void construct(PyObject * obj_ptr, converter::rvalue_from_python_stage1_data * data)
239  {
240  // Use borrowed to construct the object so that a reference
241  // count will be properly handled.
242  object obj = object(handle<>(borrowed(obj_ptr)));
243 
244  void * storage = ((converter::rvalue_from_python_storage<Variant> *)data)->storage.bytes;
245 
246  new(storage) Variant(ToVariant(obj));
247 
248  data->convertible = storage;
249 
250  }
251 };
252 
253 
255 {
256  static PyObject * convert(Variant const & v)
257  {
258 
259  if (v.IsNul())
260  {
261  Py_INCREF(Py_None);
262  return Py_None;
263  }
264 
265  object obj = ToObject(v);
266 
267  return incref(obj.ptr());
268  }
269 };
270 
ROSCPP_DECL bool check()
Variant ToVariant2(const object &obj, VariantType vtype)
list ToList(const std::vector< T > objects)
object ToObject(const Variant &var)
VariantType
Definition: variant.h:27
objects
Definition: client.py:46
static void * convertible(PyObject *obj_ptr)
Variant ToVariant(const object &obj)
static PyObject * convert(Variant const &v)
static void construct(PyObject *obj_ptr, converter::rvalue_from_python_stage1_data *data)
Python bindings for freeopcua. GNU LGPL.
std::vector< T > ToVector(const object &list)


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Tue Jan 19 2021 03:12:07