binary_variant.cpp
Go to the documentation of this file.
1 // @author Alexander Rykovanov 2012
10 
11 #include "binary_serialization.h"
12 
14 #include <opc/ua/protocol/nodeid.h>
16 #include <opc/ua/protocol/types.h>
20 
21 #include <algorithm>
22 #include <functional>
23 #include <memory>
24 #include <stdexcept>
25 #include <string>
26 
27 #include <iostream>
28 
29 namespace
30 {
31 
32 using namespace OpcUa;
33 using namespace OpcUa::Binary;
34 
35 template <typename T>
36 bool IsValueArray(const std::vector<T> & t)
37 {
38  return t.size() > 1;
39 }
40 
41 template <typename T>
42 void IsValueArray(const std::vector<T> & t, bool & isArray)
43 {
44  isArray = IsValueArray(t);
45 }
46 
47 template <typename T>
48 bool IsNulValue(const std::vector<T> & t)
49 {
50  return t.empty();
51 }
52 
53 template <typename T>
54 void IsNulValue(const std::vector<T> & t, bool & isNul)
55 {
56  isNul = IsNulValue(t);
57 }
58 
59 template <typename T>
60 void RawValueSizeArray(const std::vector<T> & t, std::size_t & size)
61 {
62  size = RawSizeContainer(t);
63 }
64 
65 
66 template <typename T>
67 void RawValueSize(const std::vector<T> & t, std::size_t & size)
68 {
69  if (IsValueArray(t))
70  {
71  size = RawSizeContainer(t);
72  }
73 
74  else if (!IsNulValue(t))
75  {
76  size = RawSize(t.at(0));
77  }
78 
79  else
80  {
81  size = 0;
82  }
83 }
84 
85 template <typename T>
86 void SerializeValueArray(const std::vector<T> & value, OpcUa::Binary::DataSerializer & stream)
87 {
88  SerializeContainer(stream, value);
89 }
90 
91 template <typename T>
92 void SerializeValue(const std::vector<T> & value, OpcUa::Binary::DataSerializer & stream)
93 {
94  if (IsValueArray(value))
95  {
96  SerializeContainer(stream, value);
97  }
98 
99  else if (!IsNulValue(value))
100  {
101  stream.Serialize(value.at(0));
102  }
103 }
104 
105 template <typename T>
106 void DeserializeContainerValue(std::vector<T> & value, OpcUa::Binary::DataDeserializer & stream)
107 {
108  DeserializeContainer(stream, value);
109 }
110 
111 template <typename T>
112 void DeserializeValue(std::vector<T> & value, OpcUa::Binary::DataDeserializer & stream)
113 {
114  T tmp;
115  stream.Deserialize(tmp);
116  value.push_back(tmp);
117 }
118 
119 struct RawSizeVisitor
120 {
121  size_t Result = 0;
122 
123  template <typename T>
124  void OnContainer(const T & val)
125  {
126  Result = RawSizeContainer(val);
127  }
128 
129  template <typename T>
130  void OnScalar(const T & val)
131  {
132  Result = RawSize(val);
133  }
134 };
135 
136 struct VariantSerializer
137 {
138  DataSerializer * Serializer;
139 
140  explicit VariantSerializer(DataSerializer * serializer)
141  : Serializer(serializer)
142  {
143  }
144 
145  template <typename T>
146  void OnContainer(const T & val)
147  {
148  SerializeContainer(*Serializer, val);
149  }
150 
151  template <typename T>
152  void OnScalar(const T & val)
153  {
154  Serializer->Serialize(val);
155  }
156 };
157 
158 struct VariantDeserializer
159 {
160  DataDeserializer * Deserializer;
161 
162  explicit VariantDeserializer(DataDeserializer * deserializer)
163  : Deserializer(deserializer)
164  {
165 
166  }
167 
168  template <typename T>
169  typename std::enable_if<is_container_not_string<T>::value == true, T>::type get()
170  {
171  T tmp;
172  DeserializeContainer(*Deserializer, tmp);
173  return tmp;
174  }
175 
176  template <typename T>
177  typename std::enable_if<is_container_not_string<T>::value == false, T>::type get()
178  {
179  T tmp;
180  *Deserializer >> tmp;
181  return tmp;
182  }
183 };
184 
185 template<typename T>
186 bool Compare(const Variant & lhs, const Variant & rhs)
187 {
188  return lhs.As<T>() == rhs.As<T>();
189 }
190 }
191 
192 namespace OpcUa
193 {
194 //---------------------------------------------------
195 // Variant
196 //---------------------------------------------------
197 
198 bool Variant::operator== (const Variant & var) const
199 {
200  if (Value.empty() ^ var.Value.empty())
201  {
202  return false;
203  }
204 
205  if (Value.empty() && var.Value.empty())
206  {
207  return true;
208  }
209 
210  if (Value.type() != var.Value.type())
211  {
212  return false;
213  }
214 
215  using namespace boost;
216  const std::type_info & t = Value.type();
217 
218  if (t == typeid(bool))
219  { return Compare<bool>(*this, var); }
220 
221  else if (t == typeid(std::vector<bool>))
222  { return Compare<std::vector<bool>>(*this, var); }
223 
224  else if (t == typeid(int8_t))
225  { return Compare<int8_t>(*this, var); }
226 
227  else if (t == typeid(std::vector<int8_t>))
228  { return Compare<std::vector<int8_t>>(*this, var); }
229 
230  else if (t == typeid(uint8_t))
231  { return Compare<uint8_t>(*this, var); }
232 
233  else if (t == typeid(std::vector<uint8_t>))
234  { return Compare<std::vector<uint8_t>>(*this, var); }
235 
236  else if (t == typeid(int16_t))
237  { return Compare<int16_t>(*this, var); }
238 
239  else if (t == typeid(std::vector<int16_t>))
240  { return Compare<std::vector<int16_t>>(*this, var); }
241 
242  else if (t == typeid(uint16_t))
243  { return Compare<uint16_t>(*this, var); }
244 
245  else if (t == typeid(std::vector<uint16_t>))
246  { return Compare<std::vector<uint16_t>>(*this, var); }
247 
248  else if (t == typeid(int32_t))
249  { return Compare<int32_t>(*this, var); }
250 
251  else if (t == typeid(std::vector<int32_t>))
252  { return Compare<std::vector<int32_t>>(*this, var); }
253 
254  else if (t == typeid(uint32_t))
255  { return Compare<uint32_t>(*this, var); }
256 
257  else if (t == typeid(std::vector<uint32_t>))
258  { return Compare<std::vector<uint32_t>>(*this, var); }
259 
260  else if (t == typeid(int64_t))
261  { return Compare<int64_t>(*this, var); }
262 
263  else if (t == typeid(std::vector<int64_t>))
264  { return Compare<std::vector<int64_t>>(*this, var); }
265 
266  else if (t == typeid(uint64_t))
267  { return Compare<uint64_t>(*this, var); }
268 
269  else if (t == typeid(std::vector<uint64_t>))
270  { return Compare<std::vector<uint64_t>>(*this, var); }
271 
272  else if (t == typeid(float))
273  { return Compare<float>(*this, var); }
274 
275  else if (t == typeid(std::vector<float>))
276  { return Compare<std::vector<float>>(*this, var); }
277 
278  else if (t == typeid(double))
279  { return Compare<double>(*this, var); }
280 
281  else if (t == typeid(std::vector<double>))
282  { return Compare<std::vector<double>>(*this, var); }
283 
284  else if (t == typeid(std::string))
285  { return Compare<std::string>(*this, var); }
286 
287  else if (t == typeid(std::vector<std::string>))
288  { return Compare<std::vector<std::string>>(*this, var); }
289 
290  else if (t == typeid(DateTime))
291  { return Compare<DateTime>(*this, var); }
292 
293  else if (t == typeid(std::vector<DateTime>))
294  { return Compare<std::vector<DateTime>>(*this, var); }
295 
296  else if (t == typeid(Guid))
297  { return Compare<Guid>(*this, var); }
298 
299  else if (t == typeid(std::vector<Guid>))
300  { return Compare<std::vector<Guid>>(*this, var); }
301 
302  else if (t == typeid(ByteString))
303  { return Compare<ByteString>(*this, var); }
304 
305  else if (t == typeid(std::vector<ByteString>))
306  { return Compare<std::vector<ByteString>>(*this, var); }
307 
308  else if (t == typeid(NodeId))
309  { return Compare<NodeId>(*this, var); }
310 
311  else if (t == typeid(std::vector<NodeId>))
312  { return Compare<std::vector<NodeId>>(*this, var); }
313 
314  else if (t == typeid(StatusCode))
315  { return Compare<StatusCode>(*this, var); }
316 
317  else if (t == typeid(std::vector<StatusCode>))
318  { return Compare<std::vector<StatusCode>>(*this, var); }
319 
320  else if (t == typeid(LocalizedText))
321  { return Compare<LocalizedText>(*this, var); }
322 
323  else if (t == typeid(std::vector<LocalizedText>))
324  { return Compare<std::vector<LocalizedText>>(*this, var); }
325 
326  else if (t == typeid(QualifiedName))
327  { return Compare<QualifiedName>(*this, var); }
328 
329  else if (t == typeid(std::vector<QualifiedName>))
330  { return Compare<std::vector<QualifiedName>>(*this, var); }
331 
332  /*
333  else if (t == typeid(DataValue))
334  return Compare<DataValue>(*this, Value);
335  else if (t == typeid(std::vector<DataValue>))
336  return Compare<std::vector<DataValue>>(*this, var);
337  */
338  else if (t == typeid(Variant))
339  { return Compare<Variant>(*this, var); }
340 
341  else if (t == typeid(std::vector<Variant>))
342  { return Compare<std::vector<Variant>>(*this, var); }
343 
344  else if (t == typeid(DiagnosticInfo))
345  { return Compare<DiagnosticInfo>(*this, var); }
346 
347  else if (t == typeid(std::vector<DiagnosticInfo>))
348  { return Compare<std::vector<DiagnosticInfo>>(*this, var); }
349 
350  throw std::logic_error(std::string("Unknown variant type '") + t.name() + std::string("'."));
351 }
352 
353 bool Variant::IsScalar() const
354 {
355  return !IsArray();
356 }
357 
358 bool Variant::IsNul() const
359 {
360  return Value.empty();
361 }
362 
363 bool Variant::IsArray() const
364 {
365  const std::type_info & t = Value.type();
366  return
367  (t == typeid(std::vector<bool>)) ||
368  (t == typeid(std::vector<int8_t>)) ||
369  (t == typeid(std::vector<uint8_t>)) ||
370  (t == typeid(std::vector<int16_t>)) ||
371  (t == typeid(std::vector<uint16_t>)) ||
372  (t == typeid(std::vector<int32_t>)) ||
373  (t == typeid(std::vector<uint32_t>)) ||
374  (t == typeid(std::vector<int64_t>)) ||
375  (t == typeid(std::vector<uint64_t>)) ||
376  (t == typeid(std::vector<float>)) ||
377  (t == typeid(std::vector<double>)) ||
378  (t == typeid(std::vector<std::string>)) ||
379  (t == typeid(std::vector<DateTime>)) ||
380  (t == typeid(std::vector<Guid>)) ||
381  (t == typeid(std::vector<ByteString>)) ||
382  (t == typeid(std::vector<NodeId>)) ||
383  (t == typeid(std::vector<StatusCode>)) ||
384  (t == typeid(std::vector<LocalizedText>)) ||
385  (t == typeid(std::vector<QualifiedName>)) ||
386 // (t == typeid(std::vector<DataValue>)) ||
387  (t == typeid(std::vector<Variant>)) ||
388  (t == typeid(std::vector<DiagnosticInfo>));
389 }
390 
392 {
393  if (Value.empty())
394  { return VariantType::NUL; }
395 
396  const std::type_info & t = Value.type();
397 
398  if (t == typeid(bool) || t == typeid(std::vector<bool>))
399  { return VariantType::BOOLEAN; }
400 
401  else if (t == typeid(int8_t) || t == typeid(std::vector<int8_t>))
402  { return VariantType::SBYTE; }
403 
404  else if (t == typeid(uint8_t) || t == typeid(std::vector<uint8_t>))
405  { return VariantType::BYTE; }
406 
407  else if (t == typeid(int16_t) || t == typeid(std::vector<int16_t>))
408  { return VariantType::INT16; }
409 
410  else if (t == typeid(uint16_t) || t == typeid(std::vector<uint16_t>))
411  { return VariantType::UINT16; }
412 
413  else if (t == typeid(int32_t) || t == typeid(std::vector<int32_t>))
414  { return VariantType::INT32; }
415 
416  else if (t == typeid(uint32_t) || t == typeid(std::vector<uint32_t>))
417  { return VariantType::UINT32; }
418 
419  else if (t == typeid(int64_t) || t == typeid(std::vector<int64_t>))
420  { return VariantType::INT64; }
421 
422  else if (t == typeid(uint64_t) || t == typeid(std::vector<uint64_t>))
423  { return VariantType::UINT64; }
424 
425  else if (t == typeid(float) || t == typeid(std::vector<float>))
426  { return VariantType::FLOAT; }
427 
428  else if (t == typeid(double) || t == typeid(std::vector<double>))
429  { return VariantType::DOUBLE; }
430 
431  else if (t == typeid(std::string) || t == typeid(std::vector<std::string>))
432  { return VariantType::STRING; }
433 
434  else if (t == typeid(DateTime) || t == typeid(std::vector<DateTime>))
435  { return VariantType::DATE_TIME; }
436 
437  else if (t == typeid(Guid) || t == typeid(std::vector<Guid>))
438  { return VariantType::GUId; }
439 
440  else if (t == typeid(ByteString) || t == typeid(std::vector<ByteString>))
441  { return VariantType::BYTE_STRING; }
442 
443  else if (t == typeid(NodeId) || t == typeid(std::vector<NodeId>))
444  { return VariantType::NODE_Id; }
445 
446  else if (t == typeid(StatusCode) || t == typeid(std::vector<StatusCode>))
447  { return VariantType::STATUS_CODE; }
448 
449  else if (t == typeid(LocalizedText) || t == typeid(std::vector<LocalizedText>))
450  { return VariantType::LOCALIZED_TEXT; }
451 
452  else if (t == typeid(QualifiedName) || t == typeid(std::vector<QualifiedName>))
453  { return VariantType::QUALIFIED_NAME; }
454 
455  /*
456  else if (t == typeid(DataValue) || t == typeid(std::vector<DataValue>))
457  return VariantType::DATA_VALUE;
458  */
459  else if (t == typeid(Variant) || t == typeid(std::vector<Variant>))
460  { return VariantType::VARIANT; }
461 
462  else if (t == typeid(DiagnosticInfo) || t == typeid(std::vector<DiagnosticInfo>))
463  { return VariantType::DIAGNOSTIC_INFO; }
464 
465  throw std::runtime_error(std::string("Unknown variant type '") + t.name() + "'.");
466 }
467 
468 
469 void Variant::Visit(VariantVisitor & visitor) const
470 {
471  using namespace boost;
472  const std::type_info & t = Value.type();
473 
474  if (t == typeid(bool))
475  { visitor.Visit(any_cast<bool>(Value)); }
476 
477  else if (t == typeid(std::vector<bool>))
478  { visitor.Visit(any_cast<std::vector<bool>>(Value)); }
479 
480  else if (t == typeid(int8_t))
481  { visitor.Visit(any_cast<int8_t>(Value)); }
482 
483  else if (t == typeid(std::vector<int8_t>))
484  { visitor.Visit(any_cast<std::vector<int8_t>>(Value)); }
485 
486  else if (t == typeid(uint8_t))
487  { visitor.Visit(any_cast<uint8_t>(Value)); }
488 
489  else if (t == typeid(std::vector<uint8_t>))
490  { visitor.Visit(any_cast<std::vector<uint8_t>>(Value)); }
491 
492  else if (t == typeid(int16_t))
493  { visitor.Visit(any_cast<int16_t>(Value)); }
494 
495  else if (t == typeid(std::vector<int16_t>))
496  { visitor.Visit(any_cast<std::vector<int16_t>>(Value)); }
497 
498  else if (t == typeid(uint16_t))
499  { visitor.Visit(any_cast<uint16_t>(Value)); }
500 
501  else if (t == typeid(std::vector<uint16_t>))
502  { visitor.Visit(any_cast<std::vector<uint16_t>>(Value)); }
503 
504  else if (t == typeid(int32_t))
505  { visitor.Visit(any_cast<int32_t>(Value)); }
506 
507  else if (t == typeid(std::vector<int32_t>))
508  { visitor.Visit(any_cast<std::vector<int32_t>>(Value)); }
509 
510  else if (t == typeid(uint32_t))
511  { visitor.Visit(any_cast<uint32_t>(Value)); }
512 
513  else if (t == typeid(std::vector<uint32_t>))
514  { visitor.Visit(any_cast<std::vector<uint32_t>>(Value)); }
515 
516  else if (t == typeid(int64_t))
517  { visitor.Visit(any_cast<int64_t>(Value)); }
518 
519  else if (t == typeid(std::vector<int64_t>))
520  { visitor.Visit(any_cast<std::vector<int64_t>>(Value)); }
521 
522  else if (t == typeid(uint64_t))
523  { visitor.Visit(any_cast<uint64_t>(Value)); }
524 
525  else if (t == typeid(std::vector<uint64_t>))
526  { visitor.Visit(any_cast<std::vector<uint64_t>>(Value)); }
527 
528  else if (t == typeid(float))
529  { visitor.Visit(any_cast<float>(Value)); }
530 
531  else if (t == typeid(std::vector<float>))
532  { visitor.Visit(any_cast<std::vector<float>>(Value)); }
533 
534  else if (t == typeid(double))
535  { visitor.Visit(any_cast<double>(Value)); }
536 
537  else if (t == typeid(std::vector<double>))
538  { visitor.Visit(any_cast<std::vector<double>>(Value)); }
539 
540  else if (t == typeid(std::string))
541  { visitor.Visit(any_cast<std::string>(Value)); }
542 
543  else if (t == typeid(std::vector<std::string>))
544  { visitor.Visit(any_cast<std::vector<std::string>>(Value)); }
545 
546  else if (t == typeid(DateTime))
547  { visitor.Visit(any_cast<DateTime>(Value)); }
548 
549  else if (t == typeid(std::vector<DateTime>))
550  { visitor.Visit(any_cast<std::vector<DateTime>>(Value)); }
551 
552  else if (t == typeid(Guid))
553  { visitor.Visit(any_cast<Guid>(Value)); }
554 
555  else if (t == typeid(std::vector<Guid>))
556  { visitor.Visit(any_cast<std::vector<Guid>>(Value)); }
557 
558  else if (t == typeid(ByteString))
559  { visitor.Visit(any_cast<ByteString>(Value)); }
560 
561  else if (t == typeid(std::vector<ByteString>))
562  { visitor.Visit(any_cast<std::vector<ByteString>>(Value)); }
563 
564  else if (t == typeid(NodeId))
565  { visitor.Visit(any_cast<NodeId>(Value)); }
566 
567  else if (t == typeid(std::vector<NodeId>))
568  { visitor.Visit(any_cast<std::vector<NodeId>>(Value)); }
569 
570  else if (t == typeid(StatusCode))
571  { visitor.Visit(any_cast<StatusCode>(Value)); }
572 
573  else if (t == typeid(std::vector<StatusCode>))
574  { visitor.Visit(any_cast<std::vector<StatusCode>>(Value)); }
575 
576  else if (t == typeid(LocalizedText))
577  { visitor.Visit(any_cast<LocalizedText>(Value)); }
578 
579  else if (t == typeid(std::vector<LocalizedText>))
580  { visitor.Visit(any_cast<std::vector<LocalizedText>>(Value)); }
581 
582  else if (t == typeid(QualifiedName))
583  { visitor.Visit(any_cast<QualifiedName>(Value)); }
584 
585  else if (t == typeid(std::vector<QualifiedName>))
586  { visitor.Visit(any_cast<std::vector<QualifiedName>>(Value)); }
587 
588  /*
589  else if (t == typeid(DataValue))
590  visitor.Visit(any_cast<DataValue>(Value));
591  else if (t == typeid(std::vector<DataValue>))
592  visitor.Visit(any_cast<std::vector<DataValue>>(Value));
593  //Variant of variant is not allowed but variant of an array of variant is OK
594  else if (t == typeid(Variant))
595  visitor.Visit(any_cast<Variant>(Value));
596  */
597  else if (t == typeid(std::vector<Variant>))
598  { visitor.Visit(any_cast<std::vector<Variant>>(Value)); }
599 
600  else if (t == typeid(DiagnosticInfo))
601  { visitor.Visit(any_cast<DiagnosticInfo>(Value)); }
602 
603  else if (t == typeid(std::vector<DiagnosticInfo>))
604  { visitor.Visit(any_cast<std::vector<DiagnosticInfo>>(Value)); }
605 
606  else
607  { throw std::runtime_error(std::string("Unknown variant type '") + t.name() + "'."); }
608 }
609 
611 {
612  switch (vt)
613  {
615  return ObjectId::Boolean;
616 
617  case VariantType::SBYTE:
618  return ObjectId::SByte;
619 
620  case VariantType::BYTE:
621  return ObjectId::Byte;
622 
623  case VariantType::INT16:
624  return ObjectId::Int16;
625 
626  case VariantType::UINT16:
627  return ObjectId::UInt16;
628 
629  case VariantType::INT32:
630  return ObjectId::Int32;
631 
632  case VariantType::UINT32:
633  return ObjectId::UInt32;
634 
635  case VariantType::INT64:
636  return ObjectId::Int64;
637 
638  case VariantType::UINT64:
639  return ObjectId::UInt64;
640 
641  case VariantType::FLOAT:
642  return ObjectId::Float;
643 
644  case VariantType::DOUBLE:
645  return ObjectId::Double;
646 
647  case VariantType::STRING:
648  return ObjectId::String;
649 
651  return ObjectId::DateTime;
652 
653  case VariantType::GUId:
654  return ObjectId::Guid;
655 
657  return ObjectId::ByteString;
658 
660  return ObjectId::XmlElement;
661 
663  return ObjectId::NodeId;
664 
667 
669  return ObjectId::StatusCode;
670 
673 
676 
679 
681  return ObjectId::DataValue;
682 
683  case VariantType::NUL:
684  return ObjectId::Null;
685 
688  default:
689  {
690  throw std::runtime_error("Unknown variant type.");
691  }
692  }
693 }
694 
696 {
697  if (dataType.GetNamespaceIndex())
698  {
699  std::string msg("Cannot convert to variant type: invalid namespace of node ");
700  throw std::runtime_error(msg + ToString(dataType));
701  }
702 
703  switch (static_cast<OpcUa::ObjectId>(dataType.GetIntegerIdentifier()))
704  {
705  case ObjectId::Boolean:
706  return VariantType::BOOLEAN;
707 
708  case ObjectId::SByte:
709  return VariantType::SBYTE;
710 
711  case ObjectId::Byte:
712  return VariantType::BYTE;
713 
714  case ObjectId::Int16:
715  return VariantType::INT16;
716 
717  case ObjectId::UInt16:
718  return VariantType::UINT16;
719 
720  case ObjectId::Int32:
721  return VariantType::INT32;
722 
723  case ObjectId::UInt32:
724  return VariantType::UINT32;
725 
726  case ObjectId::Int64:
727  return VariantType::INT64;
728 
729  case ObjectId::UInt64:
730  return VariantType::UINT64;
731 
732  case ObjectId::Float:
733  return VariantType::FLOAT;
734 
735  case ObjectId::Double:
736  return VariantType::DOUBLE;
737 
738  case ObjectId::String:
739  return VariantType::STRING;
740 
741  case ObjectId::DateTime:
742  return VariantType::DATE_TIME;
743 
744  case ObjectId::Guid:
745  return VariantType::GUId;
746 
749 
752 
753  case ObjectId::NodeId:
754  return VariantType::NODE_Id;
755 
758 
761 
764 
767 
770 
771  case ObjectId::DataValue:
773 
774  case ObjectId::Null:
775  return VariantType::NUL;
776 
777  default:
778  return VariantType::NODE_Id;
779  /*
780  {
781  std::string msg("Unknown type id ");
782  throw std::runtime_error(msg + ToString(dataType));
783  }
784  */
785  }
786 }
787 
789 {
790  if (IsScalar())
791  {
792  std::stringstream str;
793 
794  switch (Type())
795  {
797  str << OpcUa::ToString(boost::any_cast<DateTime> (Value)); //As<DateTime>());
798  break;
799 
800  case VariantType::STRING:
801  str << boost::any_cast<std::string> (Value);
802  break;
803 
805  str << ((boost::any_cast<bool> (Value)) ? "true" : "false");
806  break;
807 
808  case VariantType::BYTE:
809  str << boost::any_cast<unsigned char> (Value);
810  break;
811 
812  case VariantType::SBYTE:
813  str << boost::any_cast<char> (Value);
814  break;
815 
816  case VariantType::DOUBLE:
817  str << boost::any_cast<double> (Value);
818  break;
819 
820  case VariantType::FLOAT:
821  str << boost::any_cast<float> (Value);
822  break;
823 
824  case VariantType::INT16:
825  str << boost::any_cast<int16_t> (Value);
826  break;
827 
828  case VariantType::INT32:
829  str << boost::any_cast<int32_t> (Value);
830  break;
831 
832  case VariantType::INT64:
833  str << boost::any_cast<int64_t> (Value);
834  break;
835 
836  case VariantType::UINT16:
837  str << boost::any_cast<uint16_t> (Value);
838  break;
839 
840  case VariantType::UINT32:
841  str << boost::any_cast<uint32_t> (Value);
842  break;
843 
844  case VariantType::UINT64:
845  str << boost::any_cast<uint64_t> (Value);
846  break;
847 
848  default:
849  str << "conversion to string is not supported";
850  break;
851  }
852 
853  return str.str();
854  }
855 
856  else
857  {
858  return "conversion to string is not supported"; //TODO - add implementation for conversion
859  }
860 }
861 namespace Binary
862 {
863 template<>
864 std::size_t RawSize<Variant>(const Variant & var)
865 {
866  const uint8_t encodingMask = 0;
867  std::size_t size = RawSize(encodingMask);
868 
869  if (var.IsNul())
870  {
871  return size;
872  }
873 
874  RawSizeVisitor rawSizeCalc;
875  TypedVisitor<RawSizeVisitor> visitor(rawSizeCalc);
876  var.Visit(visitor);
877  size += rawSizeCalc.Result;
878 
879  if (!var.Dimensions.empty())
880  {
881  size += RawSizeContainer(var.Dimensions);
882  }
883 
884  return size;
885 }
886 
887 template<>
888 void DataSerializer::Serialize<Variant>(const Variant & var)
889 {
890  uint8_t encodingMask = static_cast<uint8_t>(var.Type());
891 
892  if (var.IsArray())
893  {
894  encodingMask |= HAS_ARRAY_MASK;
895  }
896 
897  if (!var.Dimensions.empty())
898  {
899  encodingMask |= HAS_DIMENSIONS_MASK;
900  }
901 
902  Serialize(encodingMask);
903 
904  if (var.IsNul())
905  {
906  return;
907  }
908 
909  VariantSerializer variantSerializer(this);
910  TypedVisitor<VariantSerializer> visitor(variantSerializer);
911  var.Visit(visitor);
912 
913  if (!var.Dimensions.empty())
914  {
915  SerializeContainer(*this, var.Dimensions);
916  }
917 }
918 
919 template<>
920 void DataDeserializer::Deserialize<Variant>(Variant & var)
921 {
922 
923  uint8_t encoding = 0;
924  Deserialize(encoding);
925 
926  VariantDeserializer deserializer(this);
927 
928  const uint8_t encodingMask = encoding & (~HAS_DIMENSIONS_MASK);
929 
930  // TODO check validity of type value after decoding.
931  if (encodingMask == (uint8_t)VariantType::NUL)
932  ;
933 
934  else if (encodingMask == (uint8_t)VariantType::BOOLEAN)
935  { var = deserializer.get<bool>(); }
936 
937  else if (encodingMask == ((uint8_t)VariantType::BOOLEAN | HAS_ARRAY_MASK))
938  { var = deserializer.get<std::vector<bool>>(); }
939 
940  else if (encodingMask == (uint8_t)VariantType::SBYTE)
941  { var = deserializer.get<int8_t>(); }
942 
943  else if (encodingMask == ((uint8_t)VariantType::SBYTE | HAS_ARRAY_MASK))
944  { var = deserializer.get<std::vector<int8_t>>(); }
945 
946  else if (encodingMask == (uint8_t)VariantType::BYTE)
947  { var = deserializer.get<uint8_t>(); }
948 
949  else if (encodingMask == ((uint8_t)VariantType::BYTE | HAS_ARRAY_MASK))
950  { var = deserializer.get<std::vector<uint8_t>>(); }
951 
952  else if (encodingMask == ((uint8_t)VariantType::INT16))
953  { var = deserializer.get<int16_t>(); }
954 
955  else if (encodingMask == ((uint8_t)VariantType::INT16 | HAS_ARRAY_MASK))
956  { var = deserializer.get<std::vector<int16_t>>(); }
957 
958  else if (encodingMask == ((uint8_t)VariantType::UINT16))
959  { var = deserializer.get<uint16_t>(); }
960 
961  else if (encodingMask == ((uint8_t)VariantType::UINT16 | HAS_ARRAY_MASK))
962  { var = deserializer.get<std::vector<uint16_t>>(); }
963 
964  else if (encodingMask == ((uint8_t)VariantType::INT32))
965  { var = deserializer.get<int32_t>(); }
966 
967  else if (encodingMask == ((uint8_t)VariantType::INT32 | HAS_ARRAY_MASK))
968  { var = deserializer.get<std::vector<int32_t>>(); }
969 
970  else if (encodingMask == ((uint8_t)VariantType::UINT32))
971  { var = deserializer.get<uint32_t>(); }
972 
973  else if (encodingMask == ((uint8_t)VariantType::UINT32 | HAS_ARRAY_MASK))
974  { var = deserializer.get<std::vector<uint32_t>>(); }
975 
976  else if (encodingMask == ((uint8_t)VariantType::INT64))
977  { var = deserializer.get<int64_t>(); }
978 
979  else if (encodingMask == ((uint8_t)VariantType::INT64 | HAS_ARRAY_MASK))
980  { var = deserializer.get<std::vector<int64_t>>(); }
981 
982  else if (encodingMask == ((uint8_t)VariantType::UINT64))
983  { var = deserializer.get<uint64_t>(); }
984 
985  else if (encodingMask == ((uint8_t)VariantType::UINT64 | HAS_ARRAY_MASK))
986  { var = deserializer.get<std::vector<uint64_t>>(); }
987 
988  else if (encodingMask == ((uint8_t)VariantType::FLOAT))
989  { var = deserializer.get<float>(); }
990 
991  else if (encodingMask == ((uint8_t)VariantType::FLOAT | HAS_ARRAY_MASK))
992  { var = deserializer.get<std::vector<float>>(); }
993 
994  else if (encodingMask == ((uint8_t)VariantType::DOUBLE))
995  { var = deserializer.get<double>(); }
996 
997  else if (encodingMask == ((uint8_t)VariantType::DOUBLE | HAS_ARRAY_MASK))
998  { var = deserializer.get<std::vector<double>>(); }
999 
1000  else if (encodingMask == ((uint8_t)VariantType::STRING))
1001  { var = deserializer.get<std::string>(); }
1002 
1003  else if (encodingMask == ((uint8_t)VariantType::STRING | HAS_ARRAY_MASK))
1004  { var = deserializer.get<std::vector<std::string>>(); }
1005 
1006  else if (encodingMask == ((uint8_t)VariantType::DATE_TIME))
1007  { var = deserializer.get<DateTime>(); }
1008 
1009  else if (encodingMask == ((uint8_t)VariantType::DATE_TIME | HAS_ARRAY_MASK))
1010  { var = deserializer.get<std::vector<DateTime>>(); }
1011 
1012  else if (encodingMask == ((uint8_t)VariantType::GUId))
1013  { var = deserializer.get<Guid>(); }
1014 
1015  else if (encodingMask == ((uint8_t)VariantType::GUId | HAS_ARRAY_MASK))
1016  { var = deserializer.get<std::vector<Guid>>(); }
1017 
1018  else if (encodingMask == ((uint8_t)VariantType::BYTE_STRING))
1019  { var = deserializer.get<ByteString>(); }
1020 
1021  else if (encodingMask == ((uint8_t)VariantType::BYTE_STRING | HAS_ARRAY_MASK))
1022  { var = deserializer.get<std::vector<ByteString>>(); }
1023 
1024  else if (encodingMask == ((uint8_t)VariantType::NODE_Id))
1025  { var = deserializer.get<NodeId>(); }
1026 
1027  else if (encodingMask == ((uint8_t)VariantType::NODE_Id | HAS_ARRAY_MASK))
1028  { var = deserializer.get<std::vector<NodeId>>(); }
1029 
1030  else if (encodingMask == ((uint8_t)VariantType::STATUS_CODE))
1031  { var = deserializer.get<StatusCode>(); }
1032 
1033  else if (encodingMask == ((uint8_t)VariantType::STATUS_CODE | HAS_ARRAY_MASK))
1034  { var = deserializer.get<std::vector<StatusCode>>(); }
1035 
1036  else if (encodingMask == ((uint8_t)VariantType::LOCALIZED_TEXT))
1037  { var = deserializer.get<LocalizedText>(); }
1038 
1039  else if (encodingMask == ((uint8_t)VariantType::LOCALIZED_TEXT | HAS_ARRAY_MASK))
1040  { var = deserializer.get<std::vector<LocalizedText>>(); }
1041 
1042  else if (encodingMask == ((uint8_t)VariantType::QUALIFIED_NAME))
1043  { var = deserializer.get<QualifiedName>(); }
1044 
1045  else if (encodingMask == ((uint8_t)VariantType::QUALIFIED_NAME | HAS_ARRAY_MASK))
1046  { var = deserializer.get<std::vector<QualifiedName>>(); }
1047 
1048  /*
1049  if(encodingMask == ((uint8_t)VariantType::DATA_VALUE))
1050  var = deserializer.get<DataValue>();
1051  if(encodingMask == ((uint8_t)VariantType::DATA_VALUE | HAS_ARRAY_MASK))
1052  var = deserializer.get<std::vector<DataValue>>();
1053  */
1054  else if (encodingMask == ((uint8_t)VariantType::VARIANT))
1055  { var = deserializer.get<Variant>(); }
1056 
1057  else if (encodingMask == ((uint8_t)VariantType::VARIANT | HAS_ARRAY_MASK))
1058  { var = deserializer.get<std::vector<Variant>>(); }
1059 
1060  else if (encodingMask == ((uint8_t)VariantType::DIAGNOSTIC_INFO))
1061  { var = deserializer.get<DiagnosticInfo>(); }
1062 
1063  else if (encodingMask == ((uint8_t)VariantType::DIAGNOSTIC_INFO | HAS_ARRAY_MASK))
1064  { var = deserializer.get<std::vector<DiagnosticInfo>>(); }
1065 
1066  else if (encodingMask == ((uint8_t)VariantType::EXTENSION_OBJECT))
1067  { var = deserializer.get<ExtensionObject>(); }
1068 
1069  else if (encodingMask == ((uint8_t)VariantType::EXTENSION_OBJECT | HAS_ARRAY_MASK))
1070  { var = deserializer.get<std::vector<ExtensionObject>>(); }
1071 
1072  else
1073  { throw std::logic_error("Deserialization of VariantType: " + std::to_string(encodingMask) + " is not supported yet."); }
1074 
1075  if (encoding & HAS_DIMENSIONS_MASK)
1076  {
1077  DeserializeContainer(*this, var.Dimensions);
1078  }
1079 }
1080 
1081 template<>
1082 void DataSerializer::Serialize<std::vector<Variant>>(const std::vector<Variant> & targets)
1083 {
1084  SerializeContainer(*this, targets);
1085 }
1086 
1087 template<>
1088 void DataDeserializer::Deserialize<std::vector<Variant>>(std::vector<Variant> & targets)
1089 {
1090  DeserializeContainer(*this, targets);
1091 }
1092 
1093 } // namespace Binary
1094 } // namespace OpcUa
uint32_t GetNamespaceIndex() const
Definition: nodeid.cpp:118
std::size_t RawSize< Variant >(const Variant &var)
Opc Ua computer interface. GNU LGPL.
void SerializeContainer(Stream &out, const Container &c, uint32_t emptySizeValue=~uint32_t())
bool IsNul() const
const uint8_t HAS_DIMENSIONS_MASK
Definition: variant.h:58
boost::any Value
Definition: variant.h:160
void DeserializeContainer(Stream &in, Container &c)
const uint8_t HAS_ARRAY_MASK
Definition: variant.h:59
ObjectId VariantTypeToDataType(VariantType vt)
VariantType
Definition: variant.h:27
uint32_t GetIntegerIdentifier() const
Definition: nodeid.cpp:92
ObjectId
Definition: object_ids.h:12
void Visit(VariantVisitor &visitor) const
void Serialize(const T &value)
VariantType Type() const
bool IsScalar() const
OPC UA Address space part. GNU LGPL.
const char * Binary(const char *input, short n)
bool operator==(const Variant &var) const
VariantType DataTypeToVariantType(const NodeId &dataType)
virtual void Visit(bool val)=0
bool IsArray() const
std::string ToString(const AttributeId &value)
T As() const
Definition: variant.h:271
std::size_t RawSizeContainer(const T &container)
std::size_t RawSize(const T &obj)
std::string ToString() const


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