00001
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
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
00302
00303
00304
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
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
00403
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
00507
00508
00509
00510
00511
00512
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
00601
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));
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";
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
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
00807
00808
00809
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 }
00845 }