Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "binary_serialization.h"
00012
00013 #include <opc/ua/protocol/binary/stream.h>
00014 #include <opc/ua/protocol/nodeid.h>
00015
00016 #include <algorithm>
00017 #include <stdexcept>
00018 #include <iostream>
00019
00020 namespace OpcUa
00021 {
00022
00023
00024 NodeId::NodeId(uint32_t integerId, uint16_t index)
00025 {
00026 Encoding = EV_NUMERIC;
00027 NumericData.Identifier = integerId;
00028 NumericData.NamespaceIndex = index;
00029 }
00030
00031 NodeId::NodeId(std::string stringId, uint16_t index)
00032 {
00033 Encoding = EV_STRING;
00034 StringData.Identifier = stringId;
00035 StringData.NamespaceIndex = index;
00036 }
00037
00038 bool NodeId::IsInteger() const
00039 {
00040 const NodeIdEncoding enc = GetEncodingValue();
00041 return enc == EV_TWO_BYTE || enc == EV_FOUR_BYTE || enc == EV_NUMERIC;
00042 }
00043
00044 bool NodeId::IsString() const
00045 {
00046 const NodeIdEncoding enc = GetEncodingValue();
00047 return enc == EV_STRING;
00048 }
00049
00050 bool NodeId::IsBinary() const
00051 {
00052 const NodeIdEncoding enc = GetEncodingValue();
00053 return enc == EV_BYTE_STRING;
00054 }
00055
00056 bool NodeId::IsGuid() const
00057 {
00058 const NodeIdEncoding enc = GetEncodingValue();
00059 return enc == EV_GUId;
00060 }
00061
00062 std::string NodeId::GetStringIdentifier() const
00063 {
00064 if (IsString())
00065 {
00066 return StringData.Identifier;
00067 }
00068 throw std::logic_error("Node id is not in String format.");
00069 }
00070
00071 std::vector<uint8_t> NodeId::GetBinaryIdentifier() const
00072 {
00073 if (IsBinary())
00074 {
00075 return BinaryData.Identifier;
00076 }
00077 throw std::logic_error("Node id is not in String format.");
00078 }
00079
00080 Guid NodeId::GetGuidIdentifier() const
00081 {
00082 if (IsGuid())
00083 {
00084 return GuidData.Identifier;
00085 }
00086 throw std::logic_error("Node id is not in String format.");
00087 }
00088
00089 uint32_t NodeId::GetIntegerIdentifier() const
00090 {
00091 switch (GetEncodingValue())
00092 {
00093 case EV_TWO_BYTE:
00094 {
00095 return TwoByteData.Identifier;
00096 }
00097 case EV_FOUR_BYTE:
00098 {
00099 return FourByteData.Identifier;
00100 }
00101 case EV_NUMERIC:
00102 {
00103 return NumericData.Identifier;
00104 }
00105 default:
00106 {
00107 throw std::logic_error("Cannot get integer identifier from NodeId - it is not in numeric format.");
00108 }
00109 }
00110 }
00111
00112 uint32_t NodeId::GetNamespaceIndex() const
00113 {
00114 switch (GetEncodingValue())
00115 {
00116 case EV_FOUR_BYTE:
00117 return FourByteData.NamespaceIndex;
00118 case EV_NUMERIC:
00119 return NumericData.NamespaceIndex;
00120 case EV_STRING:
00121 return StringData.NamespaceIndex;
00122 case EV_GUId:
00123 return GuidData.NamespaceIndex;
00124 case EV_BYTE_STRING:
00125 return BinaryData.NamespaceIndex;
00126 default:
00127 return 0;
00128 }
00129 }
00130
00131 void NodeId::SetNamespaceIndex(uint32_t ns)
00132 {
00133 switch (GetEncodingValue())
00134 {
00135 case EV_FOUR_BYTE:
00136 FourByteData.NamespaceIndex = ns;
00137 return;
00138 case EV_NUMERIC:
00139 NumericData.NamespaceIndex = ns;
00140 return;
00141 case EV_STRING:
00142 StringData.NamespaceIndex = ns;
00143 return;
00144 case EV_GUId:
00145 GuidData.NamespaceIndex = ns;
00146 return;
00147 case EV_BYTE_STRING:
00148 BinaryData.NamespaceIndex = ns;
00149 return;
00150 default:
00151 return;
00152 }
00153 }
00154
00155 NodeId::NodeId()
00156 : Encoding(EV_TWO_BYTE)
00157 , ServerIndex(0)
00158 {
00159 }
00160
00161 void NodeId::CopyNodeId(const NodeId& node)
00162 {
00163 Encoding = node.Encoding;
00164 const NodeIdEncoding enc = node.GetEncodingValue();
00165 switch (enc)
00166 {
00167 case EV_TWO_BYTE:
00168 {
00169 TwoByteData.Identifier = node.TwoByteData.Identifier;
00170 break;
00171 }
00172 case EV_FOUR_BYTE:
00173 {
00174 FourByteData.NamespaceIndex = node.FourByteData.NamespaceIndex;
00175 FourByteData.Identifier = node.FourByteData.Identifier;
00176 break;
00177 }
00178 case EV_NUMERIC:
00179 {
00180 NumericData.NamespaceIndex = node.NumericData.NamespaceIndex;
00181 NumericData.Identifier = node.NumericData.Identifier;
00182 break;
00183 }
00184 case EV_STRING:
00185 {
00186 StringData.NamespaceIndex = node.StringData.NamespaceIndex;
00187 StringData.Identifier = node.StringData.Identifier;
00188 break;
00189 }
00190 case EV_GUId:
00191 {
00192 GuidData.NamespaceIndex = node.GuidData.NamespaceIndex;
00193 GuidData.Identifier = node.GuidData.Identifier;
00194 break;
00195 }
00196 case EV_BYTE_STRING:
00197 {
00198 BinaryData.NamespaceIndex = node.BinaryData.NamespaceIndex;
00199 BinaryData.Identifier = node.BinaryData.Identifier;
00200 break;
00201 }
00202 default:
00203 {
00204 throw std::logic_error("Invalid Node Id encoding value.");
00205 }
00206 }
00207
00208 if (node.HasServerIndex())
00209 {
00210 ServerIndex = node.ServerIndex;
00211 }
00212 if (node.HasNamespaceURI())
00213 {
00214 NamespaceURI = node.NamespaceURI;
00215 }
00216
00217 }
00218
00219 NodeId::NodeId(const NodeId& node)
00220 {
00221 CopyNodeId(node);
00222 }
00223
00224 NodeId::NodeId(const ExpandedNodeId& node)
00225 {
00226 CopyNodeId(node);
00227 }
00228
00229 NodeId::operator ExpandedNodeId()
00230 {
00231 ExpandedNodeId node;
00232 node.CopyNodeId(*this);
00233
00234 return node;
00235 }
00236
00237 NodeId& NodeId::operator=(const NodeId& node)
00238 {
00239 CopyNodeId(node);
00240 return *this;
00241 }
00242
00243 NodeId& NodeId::operator=(const ExpandedNodeId& node)
00244 {
00245 CopyNodeId(node);
00246 return *this;
00247 }
00248
00249 NodeId::NodeId(MessageId messageId)
00250 : Encoding(EV_FOUR_BYTE)
00251 , ServerIndex(0)
00252 {
00253 FourByteData.Identifier = messageId;
00254 }
00255
00256 NodeId::NodeId(ReferenceId referenceId)
00257 : Encoding(EV_NUMERIC)
00258 , ServerIndex(0)
00259 {
00260 NumericData.Identifier = static_cast<uint32_t>(referenceId);
00261 }
00262
00263 NodeId::NodeId(ObjectId objectId)
00264 : Encoding(EV_NUMERIC)
00265 , ServerIndex(0)
00266 {
00267 NumericData.Identifier = static_cast<uint32_t>(objectId);
00268 }
00269
00270 NodeId::NodeId(ExpandedObjectId objectId)
00271 : Encoding(EV_FOUR_BYTE)
00272 , ServerIndex(0)
00273 {
00274 FourByteData.Identifier = static_cast<uint32_t>(objectId);
00275 }
00276
00277 MessageId GetMessageId(const NodeId& id)
00278 {
00279 return static_cast<MessageId>(id.GetIntegerIdentifier());
00280 }
00281
00282
00283 bool NodeId::operator== (const NodeId& node) const
00284 {
00285 if (GetNamespaceIndex() != node.GetNamespaceIndex())
00286 {
00287 return false;
00288 }
00289 if (IsInteger() && node.IsInteger())
00290 {
00291 return GetIntegerIdentifier() == node.GetIntegerIdentifier();
00292 }
00293 if (IsString() && node.IsString())
00294 {
00295 return GetStringIdentifier() == node.GetStringIdentifier();
00296 }
00297 if (IsBinary() && node.IsBinary())
00298 {
00299 return GetBinaryIdentifier() == node.GetBinaryIdentifier();
00300 }
00301 if (IsGuid() && node.IsGuid())
00302 {
00303 return GetGuidIdentifier() == node.GetGuidIdentifier();
00304 }
00305 return false;
00306 }
00307
00308 bool NodeId::operator < (const NodeId& node) const
00309 {
00310 if (GetNamespaceIndex() != node.GetNamespaceIndex())
00311 {
00312 return GetNamespaceIndex() < node.GetNamespaceIndex();
00313 }
00314 if (IsInteger() && node.IsInteger())
00315 {
00316 return GetIntegerIdentifier() < node.GetIntegerIdentifier();
00317 }
00318 if (IsString() && node.IsString())
00319 {
00320 return GetStringIdentifier() < node.GetStringIdentifier();
00321 }
00322 if (IsBinary() && node.IsBinary())
00323 {
00324 const std::vector<uint8_t>& l = GetBinaryIdentifier();
00325 const std::vector<uint8_t>& r = node.GetBinaryIdentifier();
00326 return std::lexicographical_compare(l.cbegin(), l.cend(), r.cbegin(), r.cend());
00327 }
00328 if (IsGuid() && node.IsGuid())
00329 {
00330 return GetGuidIdentifier() < node.GetGuidIdentifier();
00331 }
00332 return Encoding < node.Encoding;
00333
00334 }
00335
00336 NodeIdEncoding NodeId::GetEncodingValue() const
00337 {
00338 return static_cast<NodeIdEncoding>(Encoding & EV_VALUE_MASK);
00339 }
00340
00341 bool NodeId::IsNull() const
00342 {
00343 switch (GetEncodingValue())
00344 {
00345 case EV_FOUR_BYTE:
00346 if (FourByteData.NamespaceIndex != 0)
00347 return false;
00348 break;
00349 case EV_NUMERIC:
00350 if (NumericData.NamespaceIndex != 0)
00351 return false;
00352 break;
00353 case EV_STRING:
00354 if (StringData.NamespaceIndex != 0)
00355 return false;
00356 break;
00357 case EV_GUId:
00358 if (GuidData.NamespaceIndex != 0)
00359 return false;
00360 break;
00361 case EV_BYTE_STRING:
00362 if (BinaryData.NamespaceIndex != 0)
00363 return false;
00364 break;
00365 default:
00366 {
00367 throw std::logic_error("Invalid Node Id encoding value.");
00368 }
00369 }
00370 return HasNullIdentifier();
00371 }
00372
00373 bool NodeId::HasNullIdentifier() const
00374 {
00375 switch (GetEncodingValue())
00376 {
00377 case EV_FOUR_BYTE:
00378 if (FourByteData.Identifier != 0)
00379 return false;
00380 break;
00381 case EV_NUMERIC:
00382 if (NumericData.Identifier != 0)
00383 return false;
00384 break;
00385 case EV_STRING:
00386 if (not StringData.Identifier.empty())
00387 return false;
00388 break;
00389 case EV_GUId:
00390 if (not (GuidData.Identifier == Guid()))
00391 return false;
00392 break;
00393 case EV_BYTE_STRING:
00394 if (not BinaryData.Identifier.empty())
00395 return false;
00396 break;
00397 default:
00398 {
00399 throw std::logic_error("Invalid Node Id encoding value.");
00400 }
00401 }
00402 return true;
00403 }
00404
00405 bool NodeId::HasNamespaceURI() const
00406 {
00407 return (Encoding & EV_NAMESPACE_URI_FLAG) != 0;
00408 }
00409
00410 bool NodeId::HasServerIndex() const
00411 {
00412 return (Encoding & EV_Server_INDEX_FLAG) != 0;
00413 }
00414
00415 void NodeId::SetNamespaceURI(const std::string& uri)
00416 {
00417 Encoding = static_cast<NodeIdEncoding>(Encoding | EV_NAMESPACE_URI_FLAG);
00418 NamespaceURI = uri;
00419 }
00420
00421 void NodeId::SetServerIndex(uint32_t index)
00422 {
00423 Encoding = static_cast<NodeIdEncoding>(Encoding | EV_Server_INDEX_FLAG);
00424 ServerIndex = index;
00425 }
00426
00427 bool NodeId::operator!= (const NodeId& node) const
00428 {
00429 return !(*this == node);
00430 }
00431
00432 bool NodeId::operator!= (MessageId messageId) const
00433 {
00434 return !(*this == messageId);
00435 }
00436
00437 bool NodeId::operator!= (ReferenceId referenceId) const
00438 {
00439 return !(*this == referenceId);
00440 }
00441
00442 bool NodeId::operator!= (ObjectId objectId) const
00443 {
00444 return !(*this == objectId);
00445 }
00446
00447 bool NodeId::operator!= (ExpandedObjectId objectId) const
00448 {
00449 return !(*this == objectId);
00450 }
00451
00452
00453
00454 bool NodeId::operator== (MessageId messageId) const
00455 {
00456 return *this == NodeId(messageId);
00457 }
00458
00459 bool NodeId::operator== (ReferenceId referenceId) const
00460 {
00461 return *this == NodeId(referenceId);
00462 }
00463
00464 bool NodeId::operator== (ObjectId messageId) const
00465 {
00466 return *this == NodeId(messageId);
00467 }
00468
00469 bool NodeId::operator== (ExpandedObjectId messageId) const
00470 {
00471 return *this == NodeId(messageId);
00472 }
00473
00474
00476 ExpandedNodeId::ExpandedNodeId()
00477 {
00478 Encoding = EV_TWO_BYTE;
00479 ServerIndex = 0;
00480 }
00481
00482 ExpandedNodeId::ExpandedNodeId(uint32_t integerId, uint16_t index)
00483 {
00484 Encoding = EV_NUMERIC;
00485 NumericData.Identifier = integerId;
00486 NumericData.NamespaceIndex = index;
00487 }
00488
00489 ExpandedNodeId::ExpandedNodeId(std::string stringId, uint16_t index)
00490 {
00491 Encoding = EV_STRING;
00492 StringData.Identifier = stringId;
00493 StringData.NamespaceIndex = index;
00494 }
00495
00496 ExpandedNodeId::ExpandedNodeId(const NodeId& node)
00497 {
00498 CopyNodeId(node);
00499 }
00500
00501 ExpandedNodeId::ExpandedNodeId(const ExpandedNodeId& node)
00502 {
00503 CopyNodeId(node);
00504 }
00505
00506
00507 ExpandedNodeId::ExpandedNodeId(MessageId messageId)
00508 {
00509 Encoding = EV_FOUR_BYTE;
00510 ServerIndex = 0;
00511 FourByteData.Identifier = messageId;
00512 }
00513
00514 ExpandedNodeId::ExpandedNodeId(ReferenceId referenceId)
00515 {
00516 Encoding = EV_NUMERIC;
00517 ServerIndex = 0;
00518 NumericData.Identifier = static_cast<uint32_t>(referenceId);
00519 }
00520
00521 ExpandedNodeId::ExpandedNodeId(ObjectId objectId)
00522 {
00523 Encoding = EV_NUMERIC;
00524 ServerIndex = 0;
00525 NumericData.Identifier = static_cast<uint32_t>(objectId);
00526 }
00527
00528 ExpandedNodeId::ExpandedNodeId(ExpandedObjectId objectId)
00529 {
00530 Encoding = EV_FOUR_BYTE;
00531 ServerIndex = 0;
00532 FourByteData.Identifier = static_cast<uint32_t>(objectId);
00533 }
00534
00535
00536 namespace Binary
00537 {
00538 template<>
00539 std::size_t RawSize<NodeIdEncoding>(const NodeIdEncoding&)
00540 {
00541 return 1;
00542 }
00543
00544 template<>
00545 void DataSerializer::Serialize<NodeIdEncoding>(const NodeIdEncoding& value)
00546 {
00547 *this << static_cast<uint8_t>(value);
00548 }
00549
00550 template<>
00551 void DataDeserializer::Deserialize<NodeIdEncoding>(NodeIdEncoding& value)
00552 {
00553 uint8_t tmp = 0;
00554 *this >> tmp;
00555 value = static_cast<NodeIdEncoding>(tmp);
00556 }
00557
00558 template<>
00559 std::size_t RawSize<NodeId>(const NodeId& id)
00560 {
00561 std::size_t size = 0;
00562
00563 switch (id.GetEncodingValue())
00564 {
00565 case EV_TWO_BYTE:
00566 {
00567 size = 2;
00568 break;
00569 }
00570 case EV_FOUR_BYTE:
00571 {
00572 size = 4;
00573 break;
00574 }
00575 case EV_NUMERIC:
00576 {
00577 const std::size_t sizeofEncoding = 1;
00578 const std::size_t sizeofNamespace = 2;
00579 const std::size_t sizeofIdentifier = 4;
00580 size = sizeofEncoding + sizeofNamespace + sizeofIdentifier;
00581 break;
00582 }
00583 case EV_STRING:
00584 {
00585 const std::size_t sizeofEncoding = 1;
00586 const std::size_t sizeofSize = 4;
00587 const std::size_t sizeofNamespace = 2;
00588 size = sizeofEncoding + sizeofNamespace + sizeofSize + id.StringData.Identifier.size();
00589 break;
00590 }
00591 case EV_BYTE_STRING:
00592 {
00593 const std::size_t sizeofEncoding = 1;
00594 const std::size_t sizeofSize = 4;
00595 const std::size_t sizeofNamespace = 2;
00596 size = sizeofEncoding + sizeofNamespace + sizeofSize + id.BinaryData.Identifier.size();
00597 break;
00598 }
00599 case EV_GUId:
00600 {
00601 const std::size_t sizeofEncoding = 1;
00602 const std::size_t sizeofNamespace = 2;
00603 const std::size_t sizeofGuid = 16;
00604 size = sizeofEncoding + sizeofNamespace + sizeofGuid;
00605 break;
00606 }
00607
00608 default:
00609 throw std::logic_error("Unable serialize NodeId. Unknown encoding type.");
00610 };
00611
00612 return size;
00613 }
00614
00615 template<>
00616 void DataSerializer::Serialize<OpcUa::NodeId>(const OpcUa::NodeId& id)
00617 {
00618
00619 uint8_t nodeid_encoding = id.Encoding;
00620 nodeid_encoding &= ~EV_Server_INDEX_FLAG;
00621 nodeid_encoding &= ~EV_NAMESPACE_URI_FLAG;
00622
00623 *this << nodeid_encoding;
00624
00625 switch (id.GetEncodingValue())
00626 {
00627 case EV_TWO_BYTE:
00628 {
00629 *this << id.TwoByteData.Identifier;
00630 break;
00631 }
00632 case EV_FOUR_BYTE:
00633 {
00634 *this << id.FourByteData.NamespaceIndex;
00635 *this << id.FourByteData.Identifier;
00636 break;
00637 }
00638 case EV_NUMERIC:
00639 {
00640 *this << id.NumericData.NamespaceIndex;
00641 *this << id.NumericData.Identifier;
00642 break;
00643 }
00644 case EV_STRING:
00645 {
00646 *this << id.StringData.NamespaceIndex;
00647 *this << id.StringData.Identifier;
00648 break;
00649 }
00650 case EV_BYTE_STRING:
00651 {
00652 *this << id.BinaryData.NamespaceIndex;
00653 *this << id.BinaryData.Identifier;
00654 break;
00655 }
00656 case EV_GUId:
00657 {
00658 *this << id.GuidData.NamespaceIndex;
00659 *this << id.GuidData.Identifier;
00660 break;
00661 }
00662
00663 default:
00664 throw std::logic_error("Unable serialize NodeId. Unknown encoding type.");
00665 };
00666
00667 }
00668
00669 template<>
00670 void DataDeserializer::Deserialize<OpcUa::NodeId>(OpcUa::NodeId& id)
00671 {
00672 *this >> id.Encoding;
00673
00674 switch (id.GetEncodingValue())
00675 {
00676 case EV_TWO_BYTE:
00677 {
00678 *this >> id.TwoByteData.Identifier;
00679 break;
00680 }
00681 case EV_FOUR_BYTE:
00682 {
00683 *this >> id.FourByteData.NamespaceIndex;
00684 *this >> id.FourByteData.Identifier;
00685 break;
00686 }
00687 case EV_NUMERIC:
00688 {
00689 *this >> id.NumericData.NamespaceIndex;
00690 *this >> id.NumericData.Identifier;
00691 break;
00692 }
00693 case EV_STRING:
00694 {
00695 *this >> id.StringData.NamespaceIndex;
00696 *this >> id.StringData.Identifier;
00697 break;
00698 }
00699 case EV_BYTE_STRING:
00700 {
00701 *this >> id.BinaryData.NamespaceIndex;
00702 *this >> id.BinaryData.Identifier;
00703 break;
00704 }
00705 case EV_GUId:
00706 {
00707 *this >> id.GuidData.NamespaceIndex;
00708 *this >> id.GuidData.Identifier;
00709 break;
00710 }
00711
00712 default:
00713 {
00714 throw std::logic_error("Unable to deserialize NodeId. Unknown encoding type received.");
00715 }
00716 };
00717
00718 if (id.HasNamespaceURI())
00719 {
00720 *this >> id.NamespaceURI;
00721 }
00722 if (id.HasServerIndex())
00723 {
00724 *this >> id.ServerIndex;
00725 }
00726 };
00727
00728 template<>
00729 std::size_t RawSize<ExpandedNodeId>(const ExpandedNodeId& id)
00730 {
00731 std::size_t size = RawSize((NodeId)id);
00732
00733 if (id.HasNamespaceURI())
00734 {
00735 const std::size_t sizeofSize = 4;
00736 size += sizeofSize + id.NamespaceURI.size();
00737 }
00738 if (id.HasServerIndex())
00739 {
00740 const std::size_t sizeofServerIndex = 4;
00741 size += sizeofServerIndex;
00742 }
00743 return size;
00744 }
00745
00746 template<>
00747 void DataSerializer::Serialize<OpcUa::ExpandedNodeId>(const OpcUa::ExpandedNodeId& id)
00748 {
00749 *this << id.Encoding;
00750
00751 switch (id.GetEncodingValue())
00752 {
00753 case EV_TWO_BYTE:
00754 {
00755 *this << id.TwoByteData.Identifier;
00756 break;
00757 }
00758 case EV_FOUR_BYTE:
00759 {
00760 *this << id.FourByteData.NamespaceIndex;
00761 *this << id.FourByteData.Identifier;
00762 break;
00763 }
00764 case EV_NUMERIC:
00765 {
00766 *this << id.NumericData.NamespaceIndex;
00767 *this << id.NumericData.Identifier;
00768 break;
00769 }
00770 case EV_STRING:
00771 {
00772 *this << id.StringData.NamespaceIndex;
00773 *this << id.StringData.Identifier;
00774 break;
00775 }
00776 case EV_BYTE_STRING:
00777 {
00778 *this << id.BinaryData.NamespaceIndex;
00779 *this << id.BinaryData.Identifier;
00780 break;
00781 }
00782 case EV_GUId:
00783 {
00784 *this << id.GuidData.NamespaceIndex;
00785 *this << id.GuidData.Identifier;
00786 break;
00787 }
00788
00789 default:
00790 throw std::logic_error("Unable serialize ExpandedNodeId. Unknown encoding type.");
00791 };
00792
00793 if (id.HasNamespaceURI())
00794 {
00795 *this << id.NamespaceURI;
00796 }
00797 if (id.HasServerIndex())
00798 {
00799 *this << id.ServerIndex;
00800 }
00801 }
00802
00803 template<>
00804 void DataDeserializer::Deserialize<OpcUa::ExpandedNodeId>(OpcUa::ExpandedNodeId& id)
00805 {
00806 *this >> *(NodeId*) &id;
00807 };
00808
00809
00810 }
00811 }
00812