binary_variant.cpp
Go to the documentation of this file.
00001 // @author Alexander Rykovanov 2012
00010 
00011 #include "binary_serialization.h"
00012 
00013 #include <opc/ua/protocol/binary/stream.h>
00014 #include <opc/ua/protocol/nodeid.h>
00015 #include <opc/ua/protocol/string_utils.h>
00016 #include <opc/ua/protocol/types.h>
00017 #include <opc/ua/protocol/variant.h>
00018 #include <opc/ua/protocol/variant_visitor.h>
00019 
00020 #include <algorithm>
00021 #include <functional>
00022 #include <memory>
00023 #include <stdexcept>
00024 #include <string>
00025 
00026 #include <iostream>
00027 
00028 namespace
00029 {
00030 
00031   using namespace OpcUa;
00032   using namespace OpcUa::Binary;
00033 
00034   template <typename T>
00035   bool IsValueArray(const std::vector<T>& t)
00036   {
00037     return t.size() > 1;
00038   }
00039 
00040   template <typename T>
00041   void IsValueArray(const std::vector<T>& t, bool& isArray)
00042   {
00043     isArray = IsValueArray(t);
00044   }
00045 
00046   template <typename T>
00047   bool IsNulValue(const std::vector<T>& t)
00048   {
00049     return t.empty();
00050   }
00051 
00052   template <typename T>
00053   void IsNulValue(const std::vector<T>& t, bool& isNul)
00054   {
00055     isNul = IsNulValue(t);
00056   }
00057 
00058   template <typename T>
00059   void RawValueSizeArray(const std::vector<T>& t, std::size_t& size)
00060   {
00061       size = RawSizeContainer(t);
00062   }
00063 
00064 
00065   template <typename T>
00066   void RawValueSize(const std::vector<T>& t, std::size_t& size)
00067   {
00068     if (IsValueArray(t))
00069     {
00070       size = RawSizeContainer(t);
00071     }
00072     else if (!IsNulValue(t))
00073     {
00074       size = RawSize(t.at(0));
00075     }
00076     else
00077     {
00078       size = 0;
00079     }
00080   }
00081 
00082   template <typename T>
00083   void SerializeValueArray(const std::vector<T>& value, OpcUa::Binary::DataSerializer& stream)
00084   {
00085       SerializeContainer(stream, value);
00086   }
00087 
00088   template <typename T>
00089   void SerializeValue(const std::vector<T>& value, OpcUa::Binary::DataSerializer& stream)
00090   {
00091     if (IsValueArray(value))
00092     {
00093       SerializeContainer(stream, value);
00094     }
00095     else if (!IsNulValue(value))
00096     {
00097       stream.Serialize(value.at(0));
00098     }
00099   }
00100 
00101   template <typename T>
00102   void DeserializeContainerValue(std::vector<T>& value, OpcUa::Binary::DataDeserializer& stream)
00103   {
00104     DeserializeContainer(stream, value);
00105   }
00106 
00107   template <typename T>
00108   void DeserializeValue(std::vector<T>& value, OpcUa::Binary::DataDeserializer& stream)
00109   {
00110     T tmp;
00111     stream.Deserialize(tmp);
00112     value.push_back(tmp);
00113   }
00114 
00115   struct RawSizeVisitor
00116   {
00117     size_t Result = 0;
00118 
00119     template <typename T>
00120     void OnContainer(const T& val)
00121     {
00122       Result = RawSizeContainer(val);
00123     }
00124 
00125     template <typename T>
00126     void OnScalar(const T& val)
00127     {
00128       Result = RawSize(val);
00129     }
00130   };
00131 
00132   struct VariantSerializer
00133   {
00134     DataSerializer* Serializer;
00135 
00136     explicit VariantSerializer(DataSerializer* serializer)
00137       : Serializer(serializer)
00138     {
00139     }
00140 
00141     template <typename T>
00142     void OnContainer(const T& val)
00143     {
00144       SerializeContainer(*Serializer, val);
00145     }
00146 
00147     template <typename T>
00148     void OnScalar(const T& val)
00149     {
00150       Serializer->Serialize(val);
00151     }
00152   };
00153 
00154   struct VariantDeserializer
00155   {
00156     DataDeserializer* Deserializer;
00157 
00158     explicit VariantDeserializer(DataDeserializer* deserializer)
00159       : Deserializer(deserializer)
00160     {
00161 
00162     }
00163 
00164     template <typename T>
00165     typename std::enable_if<is_container_not_string<T>::value == true, T>::type get()
00166     {
00167       T tmp;
00168       DeserializeContainer(*Deserializer, tmp);
00169       return tmp;
00170     }
00171 
00172     template <typename T>
00173     typename std::enable_if<is_container_not_string<T>::value == false, T>::type get()
00174     {
00175       T tmp;
00176       *Deserializer >> tmp;
00177       return tmp;
00178     }
00179   };
00180 
00181   template<typename T>
00182   bool Compare(const Variant& lhs, const Variant& rhs)
00183   {
00184     return lhs.As<T>() == rhs.As<T>();
00185   }
00186 }
00187 
00188 namespace OpcUa
00189 {
00190   //---------------------------------------------------
00191   // Variant
00192   //---------------------------------------------------
00193 
00194   bool Variant::operator== (const Variant& var) const
00195   {
00196     if (Value.empty() ^ var.Value.empty())
00197     {
00198       return false;
00199     }
00200 
00201     if (Value.empty() && var.Value.empty())
00202     {
00203       return true;
00204     }
00205 
00206     if (Value.type() != var.Value.type())
00207     {
00208       return false;
00209     }
00210 
00211     using namespace boost;
00212     const std::type_info& t = Value.type();
00213     if (t == typeid(bool))
00214       return Compare<bool>(*this, var);
00215     else if (t == typeid(std::vector<bool>))
00216       return Compare<std::vector<bool>>(*this, var);
00217     else if (t == typeid(int8_t))
00218       return Compare<int8_t>(*this, var);
00219     else if (t == typeid(std::vector<int8_t>))
00220       return Compare<std::vector<int8_t>>(*this, var);
00221     else if (t == typeid(uint8_t))
00222       return Compare<uint8_t>(*this, var);
00223     else if (t == typeid(std::vector<uint8_t>))
00224       return Compare<std::vector<uint8_t>>(*this, var);
00225     else if (t == typeid(int16_t))
00226       return Compare<int16_t>(*this, var);
00227     else if (t == typeid(std::vector<int16_t>))
00228       return Compare<std::vector<int16_t>>(*this, var);
00229     else if (t == typeid(uint16_t))
00230       return Compare<uint16_t>(*this, var);
00231     else if (t == typeid(std::vector<uint16_t>))
00232       return Compare<std::vector<uint16_t>>(*this, var);
00233 
00234     else if (t == typeid(int32_t))
00235       return Compare<int32_t>(*this, var);
00236     else if (t == typeid(std::vector<int32_t>))
00237       return Compare<std::vector<int32_t>>(*this, var);
00238     else if (t == typeid(uint32_t))
00239       return Compare<uint32_t>(*this, var);
00240     else if (t == typeid(std::vector<uint32_t>))
00241       return Compare<std::vector<uint32_t>>(*this, var);
00242     else if (t == typeid(int64_t))
00243       return Compare<int64_t>(*this, var);
00244     else if (t == typeid(std::vector<int64_t>))
00245       return Compare<std::vector<int64_t>>(*this, var);
00246     else if (t == typeid(uint64_t))
00247       return Compare<uint64_t>(*this, var);
00248     else if (t == typeid(std::vector<uint64_t>))
00249       return Compare<std::vector<uint64_t>>(*this, var);
00250 
00251     else if (t == typeid(float))
00252       return Compare<float>(*this, var);
00253     else if (t == typeid(std::vector<float>))
00254       return Compare<std::vector<float>>(*this, var);
00255 
00256     else if (t == typeid(double))
00257       return Compare<double>(*this, var);
00258     else if (t == typeid(std::vector<double>))
00259       return Compare<std::vector<double>>(*this, var);
00260 
00261     else if (t == typeid(std::string))
00262       return Compare<std::string>(*this, var);
00263     else if (t == typeid(std::vector<std::string>))
00264       return Compare<std::vector<std::string>>(*this, var);
00265 
00266     else if (t == typeid(DateTime))
00267       return Compare<DateTime>(*this, var);
00268     else if (t == typeid(std::vector<DateTime>))
00269       return Compare<std::vector<DateTime>>(*this, var);
00270 
00271     else if (t == typeid(Guid))
00272       return Compare<Guid>(*this, var);
00273     else if (t == typeid(std::vector<Guid>))
00274       return Compare<std::vector<Guid>>(*this, var);
00275 
00276     else if (t == typeid(ByteString))
00277       return Compare<ByteString>(*this, var);
00278     else if (t == typeid(std::vector<ByteString>))
00279       return Compare<std::vector<ByteString>>(*this, var);
00280 
00281     else if (t == typeid(NodeId))
00282       return Compare<NodeId>(*this, var);
00283     else if (t == typeid(std::vector<NodeId>))
00284       return Compare<std::vector<NodeId>>(*this, var);
00285 
00286     else if (t == typeid(StatusCode))
00287       return Compare<StatusCode>(*this, var);
00288     else if (t == typeid(std::vector<StatusCode>))
00289       return Compare<std::vector<StatusCode>>(*this, var);
00290 
00291     else if (t == typeid(LocalizedText))
00292       return Compare<LocalizedText>(*this, var);
00293     else if (t == typeid(std::vector<LocalizedText>))
00294       return Compare<std::vector<LocalizedText>>(*this, var);
00295 
00296     else if (t == typeid(QualifiedName))
00297       return Compare<QualifiedName>(*this, var);
00298     else if (t == typeid(std::vector<QualifiedName>))
00299       return Compare<std::vector<QualifiedName>>(*this, var);
00300 /*
00301     else if (t == typeid(DataValue))
00302       return Compare<DataValue>(*this, Value);
00303     else if (t == typeid(std::vector<DataValue>))
00304       return Compare<std::vector<DataValue>>(*this, var);
00305 */
00306     else if (t == typeid(Variant))
00307       return Compare<Variant>(*this, var);
00308     else if (t == typeid(std::vector<Variant>))
00309       return Compare<std::vector<Variant>>(*this, var);
00310 
00311     else if (t == typeid(DiagnosticInfo))
00312       return Compare<DiagnosticInfo>(*this, var);
00313     else if (t == typeid(std::vector<DiagnosticInfo>))
00314       return Compare<std::vector<DiagnosticInfo>>(*this, var);
00315 
00316     throw std::logic_error(std::string("Unknown variant type '") + t.name() + std::string("'."));
00317   }
00318 
00319   bool Variant::IsScalar() const
00320   {
00321     return !IsArray();
00322   }
00323 
00324   bool Variant::IsNul() const
00325   {
00326     return Value.empty();
00327   }
00328 
00329   bool Variant::IsArray() const
00330   {
00331     const std::type_info& t = Value.type();
00332     return
00333     (t == typeid(std::vector<bool>))       ||
00334     (t == typeid(std::vector<int8_t>))     ||
00335     (t == typeid(std::vector<uint8_t>))    ||
00336     (t == typeid(std::vector<int16_t>))    ||
00337     (t == typeid(std::vector<uint16_t>))   ||
00338     (t == typeid(std::vector<int32_t>))    ||
00339     (t == typeid(std::vector<uint32_t>))   ||
00340     (t == typeid(std::vector<int64_t>))    ||
00341     (t == typeid(std::vector<uint64_t>))   ||
00342     (t == typeid(std::vector<float>))      ||
00343     (t == typeid(std::vector<double>))     ||
00344     (t == typeid(std::vector<std::string>))||
00345     (t == typeid(std::vector<DateTime>))   ||
00346     (t == typeid(std::vector<Guid>))       ||
00347     (t == typeid(std::vector<ByteString>)) ||
00348     (t == typeid(std::vector<NodeId>))     ||
00349     (t == typeid(std::vector<StatusCode>)) ||
00350     (t == typeid(std::vector<LocalizedText>)) ||
00351     (t == typeid(std::vector<QualifiedName>)) ||
00352 //    (t == typeid(std::vector<DataValue>))  ||
00353     (t == typeid(std::vector<Variant>))    ||
00354     (t == typeid(std::vector<DiagnosticInfo>));
00355   }
00356 
00357   VariantType Variant::Type() const
00358   {
00359     if (Value.empty())
00360       return VariantType::NUL;
00361 
00362     const std::type_info& t = Value.type();
00363     if (t == typeid(bool) || t == typeid(std::vector<bool>))
00364       return VariantType::BOOLEAN;
00365     else if (t == typeid(int8_t) || t == typeid(std::vector<int8_t>))
00366       return VariantType::SBYTE;
00367     else if (t == typeid(uint8_t) || t == typeid(std::vector<uint8_t>))
00368       return VariantType::BYTE;
00369     else if (t == typeid(int16_t) || t == typeid(std::vector<int16_t>))
00370       return VariantType::INT16;
00371     else if (t == typeid(uint16_t) || t == typeid(std::vector<uint16_t>))
00372       return VariantType::UINT16;
00373     else if (t == typeid(int32_t) || t == typeid(std::vector<int32_t>))
00374       return VariantType::INT32;
00375     else if (t == typeid(uint32_t) || t == typeid(std::vector<uint32_t>))
00376       return VariantType::UINT32;
00377     else if (t == typeid(int64_t) || t == typeid(std::vector<int64_t>))
00378       return VariantType::INT64;
00379     else if (t == typeid(uint64_t) || t == typeid(std::vector<uint64_t>))
00380       return VariantType::UINT64;
00381     else if (t == typeid(float) || t == typeid(std::vector<float>))
00382       return VariantType::FLOAT;
00383     else if (t == typeid(double) || t == typeid(std::vector<double>))
00384       return VariantType::DOUBLE;
00385     else if (t == typeid(std::string) || t == typeid(std::vector<std::string>))
00386       return VariantType::STRING;
00387     else if (t == typeid(DateTime) || t == typeid(std::vector<DateTime>))
00388       return VariantType::DATE_TIME;
00389     else if (t == typeid(Guid) || t == typeid(std::vector<Guid>))
00390       return VariantType::GUId;
00391     else if (t == typeid(ByteString) || t == typeid(std::vector<ByteString>))
00392       return VariantType::BYTE_STRING;
00393     else if (t == typeid(NodeId) || t == typeid(std::vector<NodeId>))
00394       return VariantType::NODE_Id;
00395     else if (t == typeid(StatusCode) || t == typeid(std::vector<StatusCode>))
00396       return VariantType::STATUS_CODE;
00397     else if (t == typeid(LocalizedText) || t == typeid(std::vector<LocalizedText>))
00398       return VariantType::LOCALIZED_TEXT;
00399     else if (t == typeid(QualifiedName) || t == typeid(std::vector<QualifiedName>))
00400       return VariantType::QUALIFIED_NAME;
00401 /*
00402     else if (t == typeid(DataValue) || t == typeid(std::vector<DataValue>))
00403       return VariantType::DATA_VALUE;
00404 */
00405     else if (t == typeid(Variant) || t == typeid(std::vector<Variant>))
00406       return VariantType::VARIANT;
00407     else if (t == typeid(DiagnosticInfo) || t == typeid(std::vector<DiagnosticInfo>))
00408       return VariantType::DIAGNOSTIC_INFO;
00409 
00410     throw std::runtime_error(std::string("Unknown variant type '") + t.name() + "'.");
00411   }
00412 
00413 
00414   void Variant::Visit(VariantVisitor& visitor) const
00415   {
00416     using namespace boost;
00417     const std::type_info& t = Value.type();
00418     if (t == typeid(bool))
00419       visitor.Visit(any_cast<bool>(Value));
00420     else if (t == typeid(std::vector<bool>))
00421       visitor.Visit(any_cast<std::vector<bool>>(Value));
00422     else if (t == typeid(int8_t))
00423       visitor.Visit(any_cast<int8_t>(Value));
00424     else if (t == typeid(std::vector<int8_t>))
00425       visitor.Visit(any_cast<std::vector<int8_t>>(Value));
00426     else if (t == typeid(uint8_t))
00427       visitor.Visit(any_cast<uint8_t>(Value));
00428     else if (t == typeid(std::vector<uint8_t>))
00429       visitor.Visit(any_cast<std::vector<uint8_t>>(Value));
00430     else if (t == typeid(int16_t))
00431       visitor.Visit(any_cast<int16_t>(Value));
00432     else if (t == typeid(std::vector<int16_t>))
00433       visitor.Visit(any_cast<std::vector<int16_t>>(Value));
00434     else if (t == typeid(uint16_t))
00435       visitor.Visit(any_cast<uint16_t>(Value));
00436     else if (t == typeid(std::vector<uint16_t>))
00437       visitor.Visit(any_cast<std::vector<uint16_t>>(Value));
00438 
00439     else if (t == typeid(int32_t))
00440       visitor.Visit(any_cast<int32_t>(Value));
00441     else if (t == typeid(std::vector<int32_t>))
00442       visitor.Visit(any_cast<std::vector<int32_t>>(Value));
00443     else if (t == typeid(uint32_t))
00444       visitor.Visit(any_cast<uint32_t>(Value));
00445     else if (t == typeid(std::vector<uint32_t>))
00446       visitor.Visit(any_cast<std::vector<uint32_t>>(Value));
00447     else if (t == typeid(int64_t))
00448       visitor.Visit(any_cast<int64_t>(Value));
00449     else if (t == typeid(std::vector<int64_t>))
00450       visitor.Visit(any_cast<std::vector<int64_t>>(Value));
00451     else if (t == typeid(uint64_t))
00452       visitor.Visit(any_cast<uint64_t>(Value));
00453     else if (t == typeid(std::vector<uint64_t>))
00454       visitor.Visit(any_cast<std::vector<uint64_t>>(Value));
00455 
00456     else if (t == typeid(float))
00457       visitor.Visit(any_cast<float>(Value));
00458     else if (t == typeid(std::vector<float>))
00459       visitor.Visit(any_cast<std::vector<float>>(Value));
00460 
00461     else if (t == typeid(double))
00462       visitor.Visit(any_cast<double>(Value));
00463     else if (t == typeid(std::vector<double>))
00464       visitor.Visit(any_cast<std::vector<double>>(Value));
00465 
00466     else if (t == typeid(std::string))
00467       visitor.Visit(any_cast<std::string>(Value));
00468     else if (t == typeid(std::vector<std::string>))
00469       visitor.Visit(any_cast<std::vector<std::string>>(Value));
00470 
00471     else if (t == typeid(DateTime))
00472       visitor.Visit(any_cast<DateTime>(Value));
00473     else if (t == typeid(std::vector<DateTime>))
00474       visitor.Visit(any_cast<std::vector<DateTime>>(Value));
00475 
00476     else if (t == typeid(Guid))
00477       visitor.Visit(any_cast<Guid>(Value));
00478     else if (t == typeid(std::vector<Guid>))
00479       visitor.Visit(any_cast<std::vector<Guid>>(Value));
00480 
00481     else if (t == typeid(ByteString))
00482       visitor.Visit(any_cast<ByteString>(Value));
00483     else if (t == typeid(std::vector<ByteString>))
00484       visitor.Visit(any_cast<std::vector<ByteString>>(Value));
00485 
00486     else if (t == typeid(NodeId))
00487       visitor.Visit(any_cast<NodeId>(Value));
00488     else if (t == typeid(std::vector<NodeId>))
00489       visitor.Visit(any_cast<std::vector<NodeId>>(Value));
00490 
00491     else if (t == typeid(StatusCode))
00492       visitor.Visit(any_cast<StatusCode>(Value));
00493     else if (t == typeid(std::vector<StatusCode>))
00494       visitor.Visit(any_cast<std::vector<StatusCode>>(Value));
00495 
00496     else if (t == typeid(LocalizedText))
00497       visitor.Visit(any_cast<LocalizedText>(Value));
00498     else if (t == typeid(std::vector<LocalizedText>))
00499       visitor.Visit(any_cast<std::vector<LocalizedText>>(Value));
00500 
00501     else if (t == typeid(QualifiedName))
00502       visitor.Visit(any_cast<QualifiedName>(Value));
00503     else if (t == typeid(std::vector<QualifiedName>))
00504       visitor.Visit(any_cast<std::vector<QualifiedName>>(Value));
00505 /*
00506     else if (t == typeid(DataValue))
00507       visitor.Visit(any_cast<DataValue>(Value));
00508     else if (t == typeid(std::vector<DataValue>))
00509       visitor.Visit(any_cast<std::vector<DataValue>>(Value));
00510       //Variant of variant is not allowed but variant of an array of variant is OK
00511     else if (t == typeid(Variant))
00512       visitor.Visit(any_cast<Variant>(Value));
00513 */
00514     else if (t == typeid(std::vector<Variant>))
00515       visitor.Visit(any_cast<std::vector<Variant>>(Value));
00516 
00517     else if (t == typeid(DiagnosticInfo))
00518       visitor.Visit(any_cast<DiagnosticInfo>(Value));
00519     else if (t == typeid(std::vector<DiagnosticInfo>))
00520       visitor.Visit(any_cast<std::vector<DiagnosticInfo>>(Value));
00521     else
00522       throw std::runtime_error(std::string("Unknown variant type '") + t.name() + "'.");
00523   }
00524 
00525   ObjectId VariantTypeToDataType(VariantType vt)
00526   {
00527     switch (vt)
00528     {
00529       case VariantType::BOOLEAN:          return ObjectId::Boolean;
00530       case VariantType::SBYTE:            return ObjectId::SByte;
00531       case VariantType::BYTE:             return ObjectId::Byte;
00532       case VariantType::INT16:            return ObjectId::Int16;
00533       case VariantType::UINT16:           return ObjectId::UInt16;
00534       case VariantType::INT32:            return ObjectId::Int32;
00535       case VariantType::UINT32:           return ObjectId::UInt32;
00536       case VariantType::INT64:            return ObjectId::Int64;
00537       case VariantType::UINT64:           return ObjectId::UInt64;
00538       case VariantType::FLOAT:            return ObjectId::Float;
00539       case VariantType::DOUBLE:           return ObjectId::Double;
00540       case VariantType::STRING:           return ObjectId::String;
00541       case VariantType::DATE_TIME:        return ObjectId::DateTime;
00542       case VariantType::GUId:             return ObjectId::Guid;
00543       case VariantType::BYTE_STRING:      return ObjectId::ByteString;
00544       case VariantType::XML_ELEMENT:      return ObjectId::XmlElement;
00545       case VariantType::NODE_Id:          return ObjectId::NodeId;
00546       case VariantType::EXPANDED_NODE_Id: return ObjectId::ExpandedNodeId;
00547       case VariantType::STATUS_CODE:      return ObjectId::StatusCode;
00548       case VariantType::QUALIFIED_NAME:   return ObjectId::QualifiedName;
00549       case VariantType::LOCALIZED_TEXT:   return ObjectId::LocalizedText;
00550       case VariantType::DIAGNOSTIC_INFO:  return ObjectId::DiagnosticInfo;
00551       case VariantType::DATA_VALUE:       return ObjectId::DataValue;
00552       case VariantType::NUL:              return ObjectId::Null;
00553       case VariantType::EXTENSION_OBJECT:
00554       case VariantType::VARIANT:
00555       default:
00556       {
00557         throw std::runtime_error("Unknown variant type.");
00558       }
00559     }
00560   }
00561 
00562   VariantType DataTypeToVariantType(const NodeId& dataType)
00563   {
00564     if (dataType.GetNamespaceIndex())
00565     {
00566       std::string msg("Cannot convert to variant type: invalid namespace of node ");
00567       throw std::runtime_error(msg + ToString(dataType));
00568     }
00569 
00570     switch (static_cast<OpcUa::ObjectId>(dataType.GetIntegerIdentifier()))
00571     {
00572       case ObjectId::Boolean:        return VariantType::BOOLEAN;
00573       case ObjectId::SByte:          return VariantType::SBYTE;
00574       case ObjectId::Byte:           return VariantType::BYTE;
00575       case ObjectId::Int16:          return VariantType::INT16;
00576       case ObjectId::UInt16:         return VariantType::UINT16;
00577       case ObjectId::Int32:          return VariantType::INT32;
00578       case ObjectId::UInt32:         return VariantType::UINT32;
00579       case ObjectId::Int64:          return VariantType::INT64;
00580       case ObjectId::UInt64:         return VariantType::UINT64;
00581       case ObjectId::Float:          return VariantType::FLOAT;
00582       case ObjectId::Double:         return VariantType::DOUBLE;
00583       case ObjectId::String:         return VariantType::STRING;
00584       case ObjectId::DateTime:       return VariantType::DATE_TIME;
00585       case ObjectId::Guid:           return VariantType::GUId;
00586       case ObjectId::ByteString:     return VariantType::BYTE_STRING;
00587       case ObjectId::XmlElement:     return VariantType::XML_ELEMENT;
00588       case ObjectId::NodeId:         return VariantType::NODE_Id;
00589       case ObjectId::ExpandedNodeId: return VariantType::EXPANDED_NODE_Id;
00590       case ObjectId::StatusCode:     return VariantType::STATUS_CODE;
00591       case ObjectId::QualifiedName:  return VariantType::QUALIFIED_NAME;
00592       case ObjectId::LocalizedText:  return VariantType::LOCALIZED_TEXT;
00593       case ObjectId::DiagnosticInfo: return VariantType::DIAGNOSTIC_INFO;
00594       case ObjectId::DataValue:      return VariantType::DATA_VALUE;
00595       case ObjectId::Null:           return VariantType::NUL;
00596       default:
00597         return VariantType::NODE_Id;
00598 /*
00599       {
00600         std::string msg("Unknown type id ");
00601         throw std::runtime_error(msg  + ToString(dataType));
00602       }
00603 */
00604     }
00605   }
00606   
00607   std::string Variant::ToString() const
00608   {
00609           if (IsScalar())
00610           {
00611                   std::stringstream str;
00612                   switch (Type())
00613                   {
00614                   case VariantType::DATE_TIME:
00615                           str << OpcUa::ToString(boost::any_cast<DateTime> (Value)); //As<DateTime>());
00616                           break;
00617                   case VariantType::STRING:
00618                           str << boost::any_cast<std::string> (Value);
00619                           break;
00620                   case VariantType::BOOLEAN:
00621                           str << ((boost::any_cast<bool> (Value)) ? "true" : "false");
00622                           break;
00623                   case VariantType::BYTE:
00624                           str << boost::any_cast<unsigned char> (Value);
00625                           break;
00626                   case VariantType::SBYTE:
00627                           str << boost::any_cast<char> (Value);
00628                           break;
00629                   case VariantType::DOUBLE:
00630                           str << boost::any_cast<double> (Value);
00631                           break;
00632                   case VariantType::FLOAT:
00633                           str << boost::any_cast<float> (Value);
00634                           break;
00635                   case VariantType::INT16:
00636                           str << boost::any_cast<int16_t> (Value);
00637                           break;
00638                   case VariantType::INT32:
00639                           str << boost::any_cast<int32_t> (Value);
00640                           break;
00641                   case VariantType::INT64:
00642                           str << boost::any_cast<int64_t> (Value);
00643                           break;
00644                   case VariantType::UINT16:
00645                           str << boost::any_cast<uint16_t> (Value);
00646                           break;
00647                   case VariantType::UINT32:
00648                           str << boost::any_cast<uint32_t> (Value);
00649                           break;
00650                   case VariantType::UINT64:
00651                           str << boost::any_cast<uint64_t> (Value);
00652                           break;
00653                   default:
00654                           str << "conversion to string is not supported";
00655                           break;
00656                   }
00657                   return str.str();
00658           }
00659           else
00660           {
00661                   return "conversion to string is not supported"; //TODO - add implementation for conversion
00662           }
00663   }
00664   namespace Binary
00665   {
00666     template<>
00667     std::size_t RawSize<Variant>(const Variant& var)
00668     {
00669       const uint8_t encodingMask = 0;
00670       std::size_t size = RawSize(encodingMask);
00671       if (var.IsNul())
00672       {
00673         return size;
00674       }
00675 
00676       RawSizeVisitor rawSizeCalc;
00677       TypedVisitor<RawSizeVisitor> visitor(rawSizeCalc);
00678       var.Visit(visitor);
00679       size += rawSizeCalc.Result;
00680       if (!var.Dimensions.empty())
00681       {
00682         size += RawSizeContainer(var.Dimensions);
00683       }
00684 
00685       return size;
00686     }
00687 
00688     template<>
00689     void DataSerializer::Serialize<Variant>(const Variant& var)
00690     {
00691       uint8_t encodingMask = static_cast<uint8_t>(var.Type());
00692       if (var.IsArray())
00693       {
00694         encodingMask |= HAS_ARRAY_MASK;
00695       }
00696       if (!var.Dimensions.empty())
00697       {
00698         encodingMask |= HAS_DIMENSIONS_MASK;
00699       }
00700       Serialize(encodingMask);
00701       if (var.IsNul())
00702       {
00703         return;
00704       }
00705 
00706       VariantSerializer variantSerializer(this);
00707       TypedVisitor<VariantSerializer> visitor(variantSerializer);
00708       var.Visit(visitor);
00709 
00710       if (!var.Dimensions.empty())
00711       {
00712         SerializeContainer(*this, var.Dimensions);
00713       }
00714     }
00715 
00716     template<>
00717     void DataDeserializer::Deserialize<Variant>(Variant& var)
00718     {
00719 
00720       uint8_t encoding = 0;
00721       Deserialize(encoding);
00722 
00723       VariantDeserializer deserializer(this);
00724 
00725       const uint8_t encodingMask = encoding & (~HAS_DIMENSIONS_MASK);
00726       // TODO check validity of type value after decoding.
00727       if(encodingMask == (uint8_t)VariantType::NUL)
00728          ;
00729       else  if(encodingMask == (uint8_t)VariantType::BOOLEAN)
00730         var = deserializer.get<bool>();
00731       else if(encodingMask == ((uint8_t)VariantType::BOOLEAN | HAS_ARRAY_MASK))
00732         var = deserializer.get<std::vector<bool>>();
00733       else if(encodingMask == (uint8_t)VariantType::SBYTE)
00734         var = deserializer.get<int8_t>();
00735       else if(encodingMask == ((uint8_t)VariantType::SBYTE | HAS_ARRAY_MASK))
00736         var = deserializer.get<std::vector<int8_t>>();
00737       else if(encodingMask == (uint8_t)VariantType::BYTE)
00738         var = deserializer.get<uint8_t>();
00739       else if(encodingMask == ((uint8_t)VariantType::BYTE | HAS_ARRAY_MASK))
00740         var = deserializer.get<std::vector<uint8_t>>();
00741       else if(encodingMask == ((uint8_t)VariantType::INT16))
00742         var = deserializer.get<int16_t>();
00743       else if(encodingMask == ((uint8_t)VariantType::INT16 | HAS_ARRAY_MASK))
00744         var = deserializer.get<std::vector<int16_t>>();
00745       else if(encodingMask == ((uint8_t)VariantType::UINT16))
00746         var = deserializer.get<uint16_t>();
00747       else if(encodingMask == ((uint8_t)VariantType::UINT16 | HAS_ARRAY_MASK))
00748         var = deserializer.get<std::vector<uint16_t>>();
00749       else if(encodingMask == ((uint8_t)VariantType::INT32))
00750         var = deserializer.get<int32_t>();
00751       else if(encodingMask == ((uint8_t)VariantType::INT32 | HAS_ARRAY_MASK))
00752         var = deserializer.get<std::vector<int32_t>>();
00753       else if(encodingMask == ((uint8_t)VariantType::UINT32))
00754         var = deserializer.get<uint32_t>();
00755       else if(encodingMask == ((uint8_t)VariantType::UINT32 | HAS_ARRAY_MASK))
00756         var = deserializer.get<std::vector<uint32_t>>();
00757       else if(encodingMask == ((uint8_t)VariantType::INT64))
00758         var = deserializer.get<int64_t>();
00759       else if(encodingMask == ((uint8_t)VariantType::INT64 | HAS_ARRAY_MASK))
00760         var = deserializer.get<std::vector<int64_t>>();
00761       else if(encodingMask == ((uint8_t)VariantType::UINT64))
00762         var = deserializer.get<uint64_t>();
00763       else if(encodingMask == ((uint8_t)VariantType::UINT64 | HAS_ARRAY_MASK))
00764         var = deserializer.get<std::vector<uint64_t>>();
00765       else if(encodingMask == ((uint8_t)VariantType::FLOAT))
00766         var = deserializer.get<float>();
00767       else if(encodingMask == ((uint8_t)VariantType::FLOAT | HAS_ARRAY_MASK))
00768         var = deserializer.get<std::vector<float>>();
00769       else if(encodingMask == ((uint8_t)VariantType::DOUBLE))
00770         var = deserializer.get<double>();
00771       else if(encodingMask == ((uint8_t)VariantType::DOUBLE | HAS_ARRAY_MASK))
00772         var = deserializer.get<std::vector<double>>();
00773       else if(encodingMask == ((uint8_t)VariantType::STRING))
00774         var = deserializer.get<std::string>();
00775       else if(encodingMask == ((uint8_t)VariantType::STRING | HAS_ARRAY_MASK))
00776         var = deserializer.get<std::vector<std::string>>();
00777       else if(encodingMask == ((uint8_t)VariantType::DATE_TIME))
00778         var = deserializer.get<DateTime>();
00779       else if(encodingMask == ((uint8_t)VariantType::DATE_TIME | HAS_ARRAY_MASK))
00780         var = deserializer.get<std::vector<DateTime>>();
00781       else if(encodingMask == ((uint8_t)VariantType::GUId))
00782         var = deserializer.get<Guid>();
00783       else if(encodingMask == ((uint8_t)VariantType::GUId | HAS_ARRAY_MASK))
00784         var = deserializer.get<std::vector<Guid>>();
00785       else if(encodingMask == ((uint8_t)VariantType::BYTE_STRING))
00786         var = deserializer.get<ByteString>();
00787       else if(encodingMask == ((uint8_t)VariantType::BYTE_STRING | HAS_ARRAY_MASK))
00788         var = deserializer.get<std::vector<ByteString>>();
00789       else if(encodingMask == ((uint8_t)VariantType::NODE_Id))
00790         var = deserializer.get<NodeId>();
00791       else if(encodingMask == ((uint8_t)VariantType::NODE_Id | HAS_ARRAY_MASK))
00792         var = deserializer.get<std::vector<NodeId>>();
00793       else if(encodingMask == ((uint8_t)VariantType::STATUS_CODE))
00794         var = deserializer.get<StatusCode>();
00795       else if(encodingMask == ((uint8_t)VariantType::STATUS_CODE | HAS_ARRAY_MASK))
00796         var = deserializer.get<std::vector<StatusCode>>();
00797       else if(encodingMask == ((uint8_t)VariantType::LOCALIZED_TEXT))
00798         var = deserializer.get<LocalizedText>();
00799       else if(encodingMask == ((uint8_t)VariantType::LOCALIZED_TEXT | HAS_ARRAY_MASK))
00800         var = deserializer.get<std::vector<LocalizedText>>();
00801       else if(encodingMask == ((uint8_t)VariantType::QUALIFIED_NAME))
00802         var = deserializer.get<QualifiedName>();
00803       else if(encodingMask == ((uint8_t)VariantType::QUALIFIED_NAME | HAS_ARRAY_MASK))
00804         var = deserializer.get<std::vector<QualifiedName>>();
00805 /*
00806       if(encodingMask == ((uint8_t)VariantType::DATA_VALUE))
00807         var = deserializer.get<DataValue>();
00808       if(encodingMask == ((uint8_t)VariantType::DATA_VALUE | HAS_ARRAY_MASK))
00809         var = deserializer.get<std::vector<DataValue>>();
00810 */
00811       else if(encodingMask == ((uint8_t)VariantType::VARIANT))
00812         var = deserializer.get<Variant>();
00813       else if(encodingMask == ((uint8_t)VariantType::VARIANT | HAS_ARRAY_MASK))
00814         var = deserializer.get<std::vector<Variant>>();
00815       else if(encodingMask == ((uint8_t)VariantType::DIAGNOSTIC_INFO))
00816         var = deserializer.get<DiagnosticInfo>();
00817       else if(encodingMask == ((uint8_t)VariantType::DIAGNOSTIC_INFO | HAS_ARRAY_MASK))
00818         var = deserializer.get<std::vector<DiagnosticInfo>>();
00819       else if(encodingMask == ((uint8_t)VariantType::EXTENSION_OBJECT))
00820         throw std::logic_error("Deserialization of VariantType::EXTENSION_OBJECT is not supported yet.");
00821       else if(encodingMask == ((uint8_t)VariantType::EXTENSION_OBJECT | HAS_ARRAY_MASK))
00822         throw std::logic_error("Deserialization of VariantType::EXTENSION_OBJECT[] array is not supported yet.");
00823       else
00824         throw std::logic_error("Deserialization of VariantType: " + std::to_string(encodingMask) + " is not supported yet.");
00825 
00826       if (encoding & HAS_DIMENSIONS_MASK)
00827       {
00828         DeserializeContainer(*this, var.Dimensions);
00829       }
00830     }
00831 
00832     template<>
00833     void DataSerializer::Serialize<std::vector<Variant>>(const std::vector<Variant>& targets)
00834     {
00835       SerializeContainer(*this, targets);
00836     }
00837 
00838     template<>
00839     void DataDeserializer::Deserialize<std::vector<Variant>>(std::vector<Variant>& targets)
00840     {
00841       DeserializeContainer(*this, targets);
00842     }
00843 
00844   } // namespace Binary
00845 } // namespace OpcUa


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