Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __OPC_UA_VARIANT_H__
00012 #define __OPC_UA_VARIANT_H__
00013
00014 #include <opc/ua/protocol/datetime.h>
00015 #include <opc/ua/protocol/types.h>
00016 #include <opc/ua/protocol/status_codes.h>
00017
00018 #include <boost/any.hpp>
00019 #include <string>
00020
00021 #include <stdexcept>
00022
00023
00024 namespace OpcUa
00025 {
00026
00027 enum class VariantType : uint8_t
00028 {
00029 NUL = 0,
00030 BOOLEAN = 1,
00031 SBYTE = 2,
00032 BYTE = 3,
00033 INT16 = 4,
00034 UINT16 = 5,
00035 INT32 = 6,
00036 UINT32 = 7,
00037 INT64 = 8,
00038 UINT64 = 9,
00039 FLOAT = 10,
00040 DOUBLE = 11,
00041 STRING = 12,
00042 DATE_TIME = 13,
00043 GUId = 14,
00044 BYTE_STRING = 15,
00045 XML_ELEMENT = 16,
00046 NODE_Id = 17,
00047 EXPANDED_NODE_Id = 18,
00048 STATUS_CODE = 19,
00049 QUALIFIED_NAME = 20,
00050 LOCALIZED_TEXT = 21,
00051 EXTENSION_OBJECT = 22,
00052 DATA_VALUE = 23,
00053 VARIANT = 24,
00054 DIAGNOSTIC_INFO = 25,
00055 };
00056
00057 const uint8_t VALUE_TYPE_MASK = 0x3F;
00058 const uint8_t HAS_DIMENSIONS_MASK = 0x40;
00059 const uint8_t HAS_ARRAY_MASK = 0x80;
00060
00061
00062 template<typename T>
00063 struct has_const_iterator
00064 {
00065 private:
00066 typedef char yes;
00067 typedef struct { char array[2]; } no;
00068
00069 template<typename C> static yes test(typename C::const_iterator*);
00070 template<typename C> static no test(...);
00071 public:
00072 static const bool value = sizeof(test<T>(0)) == sizeof(yes);
00073 typedef T type;
00074 };
00075
00076 template <typename T>
00077 struct has_begin_end
00078 {
00079 template<typename C> static char (&f(typename std::enable_if<
00080 std::is_same<decltype(static_cast<typename C::const_iterator (C::*)() const>(&C::begin)),
00081 typename C::const_iterator(C::*)() const>::value, void>::type*))[1];
00082
00083 template<typename C> static char (&f(...))[2];
00084
00085 template<typename C> static char (&g(typename std::enable_if<
00086 std::is_same<decltype(static_cast<typename C::const_iterator (C::*)() const>(&C::end)),
00087 typename C::const_iterator(C::*)() const>::value, void>::type*))[1];
00088
00089 template<typename C> static char (&g(...))[2];
00090
00091 static bool const beg_value = sizeof(f<T>(0)) == 1;
00092 static bool const end_value = sizeof(g<T>(0)) == 1;
00093 };
00094
00095 template<typename T>
00096 struct is_container_not_string : std::integral_constant<bool, has_const_iterator<T>::value && has_begin_end<T>::beg_value && has_begin_end<T>::end_value>
00097 { };
00098
00099 template<>
00100 struct is_container_not_string<std::string> : std::integral_constant<bool, false> {};
00101
00102
00103 class Variant;
00104
00105
00106
00107 class VariantVisitor
00108 {
00109 public:
00110 typedef void result_type;
00111
00112 public:
00113 virtual void Visit(bool val) = 0;
00114 virtual void Visit(const std::vector<bool>& val) = 0;
00115 virtual void Visit(int8_t val) = 0;
00116 virtual void Visit(const std::vector<int8_t>& val) = 0;
00117 virtual void Visit(uint8_t val) = 0;
00118 virtual void Visit(const std::vector<uint8_t>& val) = 0;
00119 virtual void Visit(int16_t val) = 0;
00120 virtual void Visit(const std::vector<int16_t>& val) = 0;
00121 virtual void Visit(uint16_t val) = 0;
00122 virtual void Visit(const std::vector<uint16_t>& val) = 0;
00123 virtual void Visit(int32_t val) = 0;
00124 virtual void Visit(const std::vector<int32_t>& val) = 0;
00125 virtual void Visit(uint32_t val) = 0;
00126 virtual void Visit(const std::vector<uint32_t>& val) = 0;
00127 virtual void Visit(int64_t val) = 0;
00128 virtual void Visit(const std::vector<int64_t>& val) = 0;
00129 virtual void Visit(uint64_t val) = 0;
00130 virtual void Visit(const std::vector<uint64_t>& val) = 0;
00131 virtual void Visit(float val) = 0;
00132 virtual void Visit(const std::vector<float>& val) = 0;
00133 virtual void Visit(double val) = 0;
00134 virtual void Visit(const std::vector<double>& val) = 0;
00135 virtual void Visit(const std::string& val) = 0;
00136 virtual void Visit(const std::vector<std::string>& val) = 0;
00137 virtual void Visit(const DateTime& val) = 0;
00138 virtual void Visit(const std::vector<DateTime>& val) = 0;
00139 virtual void Visit(const Guid& val) = 0;
00140 virtual void Visit(const std::vector<Guid>& val) = 0;
00141 virtual void Visit(const ByteString& val) = 0;
00142 virtual void Visit(const std::vector<ByteString>& val) = 0;
00143 virtual void Visit(const NodeId& val) = 0;
00144 virtual void Visit(const std::vector<NodeId>& val) = 0;
00145 virtual void Visit(const StatusCode& val) = 0;
00146 virtual void Visit(const std::vector<StatusCode>& val) = 0;
00147 virtual void Visit(const LocalizedText& val) = 0;
00148 virtual void Visit(const std::vector<LocalizedText>& val) = 0;
00149 virtual void Visit(const QualifiedName& val) = 0;
00150 virtual void Visit(const std::vector<QualifiedName>& val) = 0;
00151 virtual void Visit(const Variant& val) = 0;
00152 virtual void Visit(const std::vector<Variant>& val) = 0;
00153 virtual void Visit(const DiagnosticInfo& val) = 0;
00154 virtual void Visit(const std::vector<DiagnosticInfo>& val) = 0;
00155 };
00156
00157
00158 class Variant
00159 {
00160 boost::any Value;
00161
00162 public:
00163 std::vector<uint32_t> Dimensions;
00164
00165 Variant(){}
00166 Variant(const Variant& var)
00167 : Value(var.Value)
00168 {
00169 }
00170
00171 template <typename T>
00172 Variant(const T& value) : Value(value){}
00173 Variant(MessageId id) : Variant(NodeId(id)){}
00174 Variant(ReferenceId id) : Variant(NodeId(id)){}
00175 Variant(ObjectId id) : Variant(NodeId(id)){}
00176 Variant(ExpandedObjectId id) : Variant(NodeId(id)){}
00177 explicit Variant(VariantType);
00178
00179 Variant& operator= (const Variant& variant)
00180 {
00181 this->Value = variant.Value;
00182 return *this;
00183 }
00184
00185 template <typename T>
00186 Variant& operator=(const T& value)
00187 {
00188 Value = value;
00189 return *this;
00190 }
00191
00192 Variant& operator=(MessageId value)
00193 {
00194 Value = NodeId(value);
00195 return *this;
00196 }
00197
00198 Variant& operator=(ReferenceId value)
00199 {
00200 Value = NodeId(value);
00201 return *this;
00202 }
00203
00204 Variant& operator=(ObjectId value)
00205 {
00206 Value = NodeId(value);
00207 return *this;
00208 }
00209
00210 Variant& operator=(ExpandedObjectId value)
00211 {
00212 Value = NodeId(value);
00213 return *this;
00214 }
00215
00216
00217 bool operator== (const Variant& var) const;
00218
00219 template <typename T>
00220 bool operator==(const T& value) const
00221 {
00222 return boost::any_cast<T>(Value) == value;
00223 }
00224
00225 bool operator==(MessageId id) const
00226 {
00227 return *this == NodeId(id);
00228 }
00229
00230 bool operator==(ReferenceId id) const
00231 {
00232 return *this == NodeId(id);
00233 }
00234
00235 bool operator==(ObjectId id) const
00236 {
00237 return *this == NodeId(id);
00238 }
00239
00240 bool operator==(ExpandedObjectId id) const
00241 {
00242 return *this == NodeId(id);
00243 }
00244
00245
00246 template <typename T>
00247 bool operator!= (const T& t) const
00248 {
00249 return !(*this == t);
00250 }
00251
00252 bool IsArray() const;
00253 bool IsScalar() const;
00254 bool IsNul() const;
00255
00256 template <typename T>
00257 T As() const
00258 {
00259 return boost::any_cast<T>(Value);
00260 }
00261
00262 template <typename T>
00263 explicit operator T() const
00264 {
00265 return As<T>();
00266 }
00267
00268 VariantType Type() const;
00269 void Visit(VariantVisitor& visitor) const;
00270 std::string ToString() const;
00271 };
00272
00273 ObjectId VariantTypeToDataType(VariantType vt);
00274 VariantType DataTypeToVariantType(const NodeId& dataType);
00275
00276 }
00277
00278 #endif // __OPC_UA_VARIANT_H__