| 1 | // Copyright (C) 2017 The Qt Company Ltd. | 
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only | 
| 3 |  | 
| 4 | #include "qopen62541.h" | 
| 5 | #include "qopen62541utils.h" | 
| 6 | #include "qopen62541valueconverter.h" | 
| 7 |  | 
| 8 | #include "qopcuadatavalue.h" | 
| 9 | #include "qopcuamultidimensionalarray.h" | 
| 10 | #include "qopcuastructuredefinition.h" | 
| 11 | #include "qopcuaenumdefinition.h" | 
| 12 |  | 
| 13 | #include <QtOpcUa/qopcuaargument.h> | 
| 14 | #include <QtOpcUa/qopcuaattributeoperand.h> | 
| 15 | #include <QtOpcUa/qopcuaaxisinformation.h> | 
| 16 | #include <QtOpcUa/qopcuacomplexnumber.h> | 
| 17 | #include <QtOpcUa/qopcuadiagnosticinfo.h> | 
| 18 | #include <QtOpcUa/qopcuadoublecomplexnumber.h> | 
| 19 | #include <QtOpcUa/qopcuaelementoperand.h> | 
| 20 | #include <QtOpcUa/qopcuaenumfield.h> | 
| 21 | #include <QtOpcUa/qopcuaeuinformation.h> | 
| 22 | #include <QtOpcUa/qopcualiteraloperand.h> | 
| 23 | #include <QtOpcUa/qopcualocalizedtext.h> | 
| 24 | #include <QtOpcUa/qopcuaqualifiedname.h> | 
| 25 | #include <QtOpcUa/qopcuarange.h> | 
| 26 | #include <QtOpcUa/qopcuastructurefield.h> | 
| 27 | #include <QtOpcUa/qopcuaxvalue.h> | 
| 28 |  | 
| 29 | #include <QtCore/qdatetime.h> | 
| 30 | #include <QtCore/qloggingcategory.h> | 
| 31 | #include <QtCore/qtimezone.h> | 
| 32 | #include <QtCore/quuid.h> | 
| 33 |  | 
| 34 | #include <cstring> | 
| 35 |  | 
| 36 | QT_BEGIN_NAMESPACE | 
| 37 |  | 
| 38 | Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA_PLUGINS_OPEN62541) | 
| 39 |  | 
| 40 | using namespace QOpcUa::NodeIds; | 
| 41 |  | 
| 42 | namespace QOpen62541ValueConverter { | 
| 43 |  | 
| 44 | UA_Variant toOpen62541Variant(const QVariant &value, QOpcUa::Types type) | 
| 45 | { | 
| 46 |     UA_Variant open62541value; | 
| 47 |     UA_Variant_init(p: &open62541value); | 
| 48 |  | 
| 49 |     if (value.canConvert<QOpcUaMultiDimensionalArray>()) { | 
| 50 |         QOpcUaMultiDimensionalArray data = value.value<QOpcUaMultiDimensionalArray>(); | 
| 51 |         UA_Variant result = toOpen62541Variant(value: data.valueArray(), type); | 
| 52 |  | 
| 53 |         const auto &arrayDimensions = data.arrayDimensions(); | 
| 54 |  | 
| 55 |         if (!arrayDimensions.isEmpty()) { | 
| 56 |             // Ensure that the array dimensions size is < UINT32_MAX | 
| 57 |             if (static_cast<quint64>(arrayDimensions.size()) > (std::numeric_limits<quint32>::max)()) | 
| 58 |                 return open62541value; | 
| 59 |             result.arrayDimensionsSize = arrayDimensions.size(); | 
| 60 |             result.arrayDimensions = static_cast<UA_UInt32 *>(UA_Array_new(size: result.arrayDimensionsSize, type: &UA_TYPES[UA_TYPES_UINT32])); | 
| 61 |             std::copy(first: arrayDimensions.constBegin(), last: arrayDimensions.constEnd(), result: result.arrayDimensions); | 
| 62 |         } | 
| 63 |         return result; | 
| 64 |     } | 
| 65 |  | 
| 66 |     if (value.metaType().id() == QMetaType::QVariantList && value.toList().size() == 0) | 
| 67 |         return open62541value; | 
| 68 |  | 
| 69 |     QVariant temp = (value.metaType().id() == QMetaType::QVariantList) ? value.toList().at(i: 0) : value; | 
| 70 |     QOpcUa::Types valueType = type == QOpcUa::Undefined ? | 
| 71 |                 QOpcUa::metaTypeToQOpcUaType(type: static_cast<QMetaType::Type>(temp.metaType().id())) : type; | 
| 72 |  | 
| 73 |     const UA_DataType *dt = toDataType(valueType); | 
| 74 |  | 
| 75 |     switch (valueType) { | 
| 76 |     case QOpcUa::Boolean: | 
| 77 |         return arrayFromQVariant<UA_Boolean, bool>(var: value, type: dt); | 
| 78 |     case QOpcUa::SByte: | 
| 79 |         return arrayFromQVariant<UA_SByte, char>(var: value, type: dt); | 
| 80 |     case QOpcUa::Byte: | 
| 81 |         return arrayFromQVariant<UA_Byte, uchar>(var: value, type: dt); | 
| 82 |     case QOpcUa::Int16: | 
| 83 |         return arrayFromQVariant<UA_Int16, qint16>(var: value, type: dt); | 
| 84 |     case QOpcUa::UInt16: | 
| 85 |         return arrayFromQVariant<UA_UInt16, quint16>(var: value, type: dt); | 
| 86 |     case QOpcUa::Int32: | 
| 87 |         return arrayFromQVariant<UA_Int32, qint32>(var: value, type: dt); | 
| 88 |     case QOpcUa::UInt32: | 
| 89 |         return arrayFromQVariant<UA_UInt32, quint32>(var: value, type: dt); | 
| 90 |     case QOpcUa::Int64: | 
| 91 |         return arrayFromQVariant<UA_Int64, int64_t>(var: value, type: dt); | 
| 92 |     case QOpcUa::UInt64: | 
| 93 |         return arrayFromQVariant<UA_UInt64, uint64_t>(var: value, type: dt); | 
| 94 |     case QOpcUa::Float: | 
| 95 |         return arrayFromQVariant<UA_Float, float>(var: value, type: dt); | 
| 96 |     case QOpcUa::Double: | 
| 97 |         return arrayFromQVariant<UA_Double, double>(var: value, type: dt); | 
| 98 |     case QOpcUa::DateTime: | 
| 99 |         return arrayFromQVariant<UA_DateTime, QDateTime>(var: value, type: dt); | 
| 100 |     case QOpcUa::String: | 
| 101 |         return arrayFromQVariant<UA_String, QString>(var: value, type: dt); | 
| 102 |     case QOpcUa::LocalizedText: | 
| 103 |         return arrayFromQVariant<UA_LocalizedText, QOpcUaLocalizedText>(var: value, type: dt); | 
| 104 |     case QOpcUa::ByteString: | 
| 105 |         return arrayFromQVariant<UA_ByteString, QByteArray>(var: value, type: dt); | 
| 106 |     case QOpcUa::NodeId: | 
| 107 |         return arrayFromQVariant<UA_NodeId, QString>(var: value, type: dt); | 
| 108 |     case QOpcUa::Guid: | 
| 109 |         return arrayFromQVariant<UA_Guid, QUuid>(var: value, type: dt); | 
| 110 |     case QOpcUa::XmlElement: | 
| 111 |         return arrayFromQVariant<UA_XmlElement, QString>(var: value, type: dt); | 
| 112 |     case QOpcUa::QualifiedName: | 
| 113 |         return arrayFromQVariant<UA_QualifiedName, QOpcUaQualifiedName>(var: value, type: dt); | 
| 114 |     case QOpcUa::StatusCode: | 
| 115 |         return arrayFromQVariant<UA_StatusCode, QOpcUa::UaStatusCode>(var: value, type: dt); | 
| 116 |     case QOpcUa::Range: | 
| 117 |         return arrayFromQVariant<UA_Range, QOpcUaRange>(var: value, type: dt); | 
| 118 |     case QOpcUa::EUInformation: | 
| 119 |         return arrayFromQVariant<UA_EUInformation, QOpcUaEUInformation>(var: value, type: dt); | 
| 120 |     case QOpcUa::ComplexNumber: | 
| 121 |         return arrayFromQVariant<UA_ComplexNumberType, QOpcUaComplexNumber>(var: value, type: dt); | 
| 122 |     case QOpcUa::DoubleComplexNumber: | 
| 123 |         return arrayFromQVariant<UA_DoubleComplexNumberType, QOpcUaDoubleComplexNumber>(var: value, type: dt); | 
| 124 |     case QOpcUa::AxisInformation: | 
| 125 |         return arrayFromQVariant<UA_AxisInformation, QOpcUaAxisInformation>(var: value, type: dt); | 
| 126 |     case QOpcUa::XV: | 
| 127 |         return arrayFromQVariant<UA_XVType, QOpcUaXValue>(var: value, type: dt); | 
| 128 |     case QOpcUa::ExpandedNodeId: | 
| 129 |         return arrayFromQVariant<UA_ExpandedNodeId, QOpcUaExpandedNodeId>(var: value, type: dt); | 
| 130 |     case QOpcUa::Argument: | 
| 131 |         return arrayFromQVariant<UA_Argument, QOpcUaArgument>(var: value, type: dt); | 
| 132 |     case QOpcUa::SimpleAttributeOperand: | 
| 133 |         return arrayFromQVariant<UA_SimpleAttributeOperand, QOpcUaSimpleAttributeOperand>(var: value, type: dt); | 
| 134 |     case QOpcUa::AttributeOperand: | 
| 135 |         return arrayFromQVariant<UA_AttributeOperand, QOpcUaAttributeOperand>(var: value, type: dt); | 
| 136 |     case QOpcUa::LiteralOperand: | 
| 137 |         return arrayFromQVariant<UA_LiteralOperand, QOpcUaLiteralOperand>(var: value, type: dt); | 
| 138 |     case QOpcUa::ElementOperand: | 
| 139 |         return arrayFromQVariant<UA_SimpleAttributeOperand, QOpcUaSimpleAttributeOperand>(var: value, type: dt); | 
| 140 |     case QOpcUa::RelativePathElement: | 
| 141 |         return arrayFromQVariant<UA_RelativePathElement, QOpcUaRelativePathElement>(var: value, type: dt); | 
| 142 |     case QOpcUa::ContentFilterElement: | 
| 143 |         return arrayFromQVariant<UA_ContentFilterElement, QOpcUaContentFilterElement>(var: value, type: dt); | 
| 144 |     case QOpcUa::EventFilter: | 
| 145 |         return arrayFromQVariant<UA_EventFilter, QOpcUaMonitoringParameters::EventFilter>(var: value, type: dt); | 
| 146 |     case QOpcUa::ExtensionObject: | 
| 147 |         return arrayFromQVariant<UA_ExtensionObject, QOpcUaExtensionObject>(var: value, type: dt); | 
| 148 |     case QOpcUa::StructureDefinition: | 
| 149 |         return arrayFromQVariant<UA_StructureDefinition, QOpcUaStructureDefinition>(var: value, type: dt); | 
| 150 |     case QOpcUa::StructureField: | 
| 151 |         return arrayFromQVariant<UA_StructureField, QOpcUaStructureField>(var: value, type: dt); | 
| 152 |     case QOpcUa::EnumDefinition: | 
| 153 |         return arrayFromQVariant<UA_EnumDefinition, QOpcUaEnumDefinition>(var: value, type: dt); | 
| 154 |     case QOpcUa::EnumField: | 
| 155 |         return arrayFromQVariant<UA_EnumField, QOpcUaEnumField>(var: value, type: dt); | 
| 156 |     case QOpcUa::DiagnosticInfo: | 
| 157 |         return arrayFromQVariant<UA_DiagnosticInfo, QOpcUaDiagnosticInfo>(var: value, type: dt); | 
| 158 |     default: | 
| 159 |         qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Variant conversion to Open62541 for typeIndex"  << type << " not implemented" ; | 
| 160 |     } | 
| 161 |  | 
| 162 |     return open62541value; | 
| 163 | } | 
| 164 |  | 
| 165 | QVariant toQVariant(const UA_Variant &value) | 
| 166 | { | 
| 167 |     if (value.type == nullptr) { | 
| 168 |         return QVariant(); | 
| 169 |     } | 
| 170 |  | 
| 171 |     if (value.type == &UA_TYPES[UA_TYPES_BOOLEAN]) | 
| 172 |         return arrayToQVariant<bool, UA_Boolean>(var: value, type: QMetaType::Bool); | 
| 173 |     else if (value.type == &UA_TYPES[UA_TYPES_SBYTE]) | 
| 174 |         return arrayToQVariant<signed char, UA_SByte>(var: value, type: QMetaType::SChar); | 
| 175 |     else if (value.type == &UA_TYPES[UA_TYPES_BYTE]) | 
| 176 |         return arrayToQVariant<uchar, UA_Byte>(var: value, type: QMetaType::UChar); | 
| 177 |     else if (value.type == &UA_TYPES[UA_TYPES_INT16]) | 
| 178 |         return arrayToQVariant<qint16, UA_Int16>(var: value, type: QMetaType::Short); | 
| 179 |     else if (value.type == &UA_TYPES[UA_TYPES_UINT16]) | 
| 180 |         return arrayToQVariant<quint16, UA_UInt16>(var: value, type: QMetaType::UShort); | 
| 181 |     else if (value.type == &UA_TYPES[UA_TYPES_INT32]) | 
| 182 |         return arrayToQVariant<qint32, UA_Int32>(var: value, type: QMetaType::Int); | 
| 183 |     else if (value.type == &UA_TYPES[UA_TYPES_UINT32]) | 
| 184 |         return arrayToQVariant<quint32, UA_UInt32>(var: value, type: QMetaType::UInt); | 
| 185 |     else if (value.type == &UA_TYPES[UA_TYPES_INT64]) | 
| 186 |         return arrayToQVariant<int64_t, UA_Int64>(var: value, type: QMetaType::LongLong); | 
| 187 |     else if (value.type == &UA_TYPES[UA_TYPES_UINT64]) | 
| 188 |         return arrayToQVariant<uint64_t, UA_UInt64>(var: value, type: QMetaType::ULongLong); | 
| 189 |     else if (value.type == &UA_TYPES[UA_TYPES_FLOAT]) | 
| 190 |         return arrayToQVariant<float, UA_Float>(var: value, type: QMetaType::Float); | 
| 191 |     else if (value.type == &UA_TYPES[UA_TYPES_DOUBLE]) | 
| 192 |         return arrayToQVariant<double, UA_Double>(var: value, type: QMetaType::Double); | 
| 193 |     else if (value.type == &UA_TYPES[UA_TYPES_STRING]) | 
| 194 |         return arrayToQVariant<QString, UA_String>(var: value, type: QMetaType::QString); | 
| 195 |     else if (value.type == &UA_TYPES[UA_TYPES_BYTESTRING]) | 
| 196 |         return arrayToQVariant<QByteArray, UA_ByteString>(var: value, type: QMetaType::QByteArray); | 
| 197 |     else if (value.type == &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]) | 
| 198 |         return arrayToQVariant<QOpcUaLocalizedText, UA_LocalizedText>(var: value); | 
| 199 |     else if (value.type == &UA_TYPES[UA_TYPES_NODEID]) | 
| 200 |         return arrayToQVariant<QString, UA_NodeId>(var: value, type: QMetaType::QString); | 
| 201 |     else if (value.type == &UA_TYPES[UA_TYPES_DATETIME]) | 
| 202 |         return arrayToQVariant<QDateTime, UA_DateTime>(var: value, type: QMetaType::QDateTime); | 
| 203 |     else if (value.type == &UA_TYPES[UA_TYPES_GUID]) | 
| 204 |         return arrayToQVariant<QUuid, UA_Guid>(var: value, type: QMetaType::QUuid); | 
| 205 |     else if (value.type == &UA_TYPES[UA_TYPES_XMLELEMENT]) | 
| 206 |         return arrayToQVariant<QString, UA_XmlElement>(var: value, type: QMetaType::QString); | 
| 207 |     else if (value.type == &UA_TYPES[UA_TYPES_QUALIFIEDNAME]) | 
| 208 |         return arrayToQVariant<QOpcUaQualifiedName, UA_QualifiedName>(var: value); | 
| 209 |     else if (value.type == &UA_TYPES[UA_TYPES_STATUSCODE]) | 
| 210 |         return arrayToQVariant<QOpcUa::UaStatusCode, UA_StatusCode>(var: value, type: QMetaType::UInt); | 
| 211 |     else if (value.type == &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]) | 
| 212 |         return arrayToQVariant<QVariant, UA_ExtensionObject>(var: value); | 
| 213 |     else if (value.type == &UA_TYPES[UA_TYPES_EXPANDEDNODEID]) | 
| 214 |         return arrayToQVariant<QOpcUaExpandedNodeId, UA_ExpandedNodeId>(var: value); | 
| 215 |     else if (value.type == &UA_TYPES[UA_TYPES_ARGUMENT]) | 
| 216 |         return arrayToQVariant<QOpcUaArgument, UA_Argument>(var: value); | 
| 217 |     else if (value.type == &UA_TYPES[UA_TYPES_RANGE]) | 
| 218 |         return arrayToQVariant<QOpcUaRange, UA_Range>(var: value); | 
| 219 |     else if (value.type == &UA_TYPES[UA_TYPES_EUINFORMATION]) | 
| 220 |         return arrayToQVariant<QOpcUaEUInformation, UA_EUInformation>(var: value); | 
| 221 |     else if (value.type == &UA_TYPES[UA_TYPES_AXISINFORMATION]) | 
| 222 |         return arrayToQVariant<QOpcUaAxisInformation, UA_AxisInformation>(var: value); | 
| 223 |     else if (value.type == &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]) | 
| 224 |         return arrayToQVariant<QOpcUaComplexNumber, UA_ComplexNumberType>(var: value); | 
| 225 |     else if (value.type == &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]) | 
| 226 |         return arrayToQVariant<QOpcUaDoubleComplexNumber, UA_DoubleComplexNumberType>(var: value); | 
| 227 |     else if (value.type == &UA_TYPES[UA_TYPES_XVTYPE]) | 
| 228 |         return arrayToQVariant<QOpcUaXValue, UA_XVType>(var: value); | 
| 229 |     else if (value.type == &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]) | 
| 230 |         return arrayToQVariant<QOpcUaStructureDefinition, UA_StructureDefinition>(var: value); | 
| 231 |     else if (value.type == &UA_TYPES[UA_TYPES_STRUCTUREFIELD]) | 
| 232 |         return arrayToQVariant<QOpcUaStructureField, UA_StructureField>(var: value); | 
| 233 |     else if (value.type == &UA_TYPES[UA_TYPES_ENUMDEFINITION]) | 
| 234 |         return arrayToQVariant<QOpcUaEnumDefinition, UA_EnumDefinition>(var: value); | 
| 235 |     else if (value.type == &UA_TYPES[UA_TYPES_ENUMFIELD]) | 
| 236 |         return arrayToQVariant<QOpcUaEnumField, UA_EnumField>(var: value); | 
| 237 |     else if (value.type == &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]) | 
| 238 |         return arrayToQVariant<QOpcUaDiagnosticInfo, UA_DiagnosticInfo>(var: value); | 
| 239 |     else if (value.type == &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]) | 
| 240 |         return arrayToQVariant<QOpcUaSimpleAttributeOperand, UA_SimpleAttributeOperand>(var: value); | 
| 241 |     else if (value.type == &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]) | 
| 242 |         return arrayToQVariant<QOpcUaSimpleAttributeOperand, UA_SimpleAttributeOperand>(var: value); | 
| 243 |     else if (value.type == &UA_TYPES[UA_TYPES_LITERALOPERAND]) | 
| 244 |         return arrayToQVariant<QOpcUaLiteralOperand, UA_LiteralOperand>(var: value); | 
| 245 |     else if (value.type == &UA_TYPES[UA_TYPES_ELEMENTOPERAND]) | 
| 246 |         return arrayToQVariant<QOpcUaElementOperand, UA_ElementOperand>(var: value); | 
| 247 |     else if (value.type == &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]) | 
| 248 |         return arrayToQVariant<QOpcUaRelativePathElement, UA_RelativePathElement>(var: value); | 
| 249 |     else if (value.type == &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]) | 
| 250 |         return arrayToQVariant<QOpcUaContentFilterElement, UA_ContentFilterElement>(var: value); | 
| 251 |     else if (value.type == &UA_TYPES[UA_TYPES_EVENTFILTER]) | 
| 252 |         return arrayToQVariant<QOpcUaMonitoringParameters::EventFilter, UA_EventFilter>(var: value); | 
| 253 |  | 
| 254 |     return uaVariantToQtExtensionObject(var: value); | 
| 255 | } | 
| 256 |  | 
| 257 | const UA_DataType *toDataType(QOpcUa::Types valueType) | 
| 258 | { | 
| 259 |     switch (valueType) { | 
| 260 |     case QOpcUa::Boolean: | 
| 261 |         return &UA_TYPES[UA_TYPES_BOOLEAN]; | 
| 262 |     case QOpcUa::Int32: | 
| 263 |         return &UA_TYPES[UA_TYPES_INT32]; | 
| 264 |     case QOpcUa::UInt32: | 
| 265 |         return &UA_TYPES[UA_TYPES_UINT32]; | 
| 266 |     case QOpcUa::Double: | 
| 267 |         return &UA_TYPES[UA_TYPES_DOUBLE]; | 
| 268 |     case QOpcUa::Float: | 
| 269 |         return &UA_TYPES[UA_TYPES_FLOAT]; | 
| 270 |     case QOpcUa::String: | 
| 271 |         return &UA_TYPES[UA_TYPES_STRING]; | 
| 272 |     case QOpcUa::LocalizedText: | 
| 273 |         return &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]; | 
| 274 |     case QOpcUa::DateTime: | 
| 275 |         return &UA_TYPES[UA_TYPES_DATETIME]; | 
| 276 |     case QOpcUa::UInt16: | 
| 277 |         return &UA_TYPES[UA_TYPES_UINT16]; | 
| 278 |     case QOpcUa::Int16: | 
| 279 |         return &UA_TYPES[UA_TYPES_INT16]; | 
| 280 |     case QOpcUa::UInt64: | 
| 281 |         return &UA_TYPES[UA_TYPES_UINT64]; | 
| 282 |     case QOpcUa::Int64: | 
| 283 |         return &UA_TYPES[UA_TYPES_INT64]; | 
| 284 |     case QOpcUa::Byte: | 
| 285 |         return &UA_TYPES[UA_TYPES_BYTE]; | 
| 286 |     case QOpcUa::SByte: | 
| 287 |         return &UA_TYPES[UA_TYPES_SBYTE]; | 
| 288 |     case QOpcUa::ByteString: | 
| 289 |         return &UA_TYPES[UA_TYPES_BYTESTRING]; | 
| 290 |     case QOpcUa::XmlElement: | 
| 291 |         return &UA_TYPES[UA_TYPES_XMLELEMENT]; | 
| 292 |     case QOpcUa::NodeId: | 
| 293 |         return &UA_TYPES[UA_TYPES_NODEID]; | 
| 294 |     case QOpcUa::Guid: | 
| 295 |         return &UA_TYPES[UA_TYPES_GUID]; | 
| 296 |     case QOpcUa::QualifiedName: | 
| 297 |         return &UA_TYPES[UA_TYPES_QUALIFIEDNAME]; | 
| 298 |     case QOpcUa::StatusCode: | 
| 299 |         return &UA_TYPES[UA_TYPES_STATUSCODE]; | 
| 300 |     case QOpcUa::Range: | 
| 301 |         return &UA_TYPES[UA_TYPES_RANGE]; | 
| 302 |     case QOpcUa::EUInformation: | 
| 303 |         return &UA_TYPES[UA_TYPES_EUINFORMATION]; | 
| 304 |     case QOpcUa::ComplexNumber: | 
| 305 |         return &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]; | 
| 306 |     case QOpcUa::DoubleComplexNumber: | 
| 307 |         return &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]; | 
| 308 |     case QOpcUa::AxisInformation: | 
| 309 |         return &UA_TYPES[UA_TYPES_AXISINFORMATION]; | 
| 310 |     case QOpcUa::XV: | 
| 311 |         return &UA_TYPES[UA_TYPES_XVTYPE]; | 
| 312 |     case QOpcUa::ExtensionObject: | 
| 313 |         return &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]; | 
| 314 |     case QOpcUa::ExpandedNodeId: | 
| 315 |         return &UA_TYPES[UA_TYPES_EXPANDEDNODEID]; | 
| 316 |     case QOpcUa::Argument: | 
| 317 |         return &UA_TYPES[UA_TYPES_ARGUMENT]; | 
| 318 |     case QOpcUa::StructureDefinition: | 
| 319 |         return &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]; | 
| 320 |     case QOpcUa::StructureField: | 
| 321 |         return &UA_TYPES[UA_TYPES_STRUCTUREFIELD]; | 
| 322 |     case QOpcUa::EnumDefinition: | 
| 323 |         return &UA_TYPES[UA_TYPES_ENUMDEFINITION]; | 
| 324 |     case QOpcUa::EnumField: | 
| 325 |         return &UA_TYPES[UA_TYPES_ENUMFIELD]; | 
| 326 |     case QOpcUa::DiagnosticInfo: | 
| 327 |         return &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]; | 
| 328 |     case QOpcUa::SimpleAttributeOperand: | 
| 329 |         return &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]; | 
| 330 |     case QOpcUa::AttributeOperand: | 
| 331 |         return &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]; | 
| 332 |     case QOpcUa::LiteralOperand: | 
| 333 |         return &UA_TYPES[UA_TYPES_LITERALOPERAND]; | 
| 334 |     case QOpcUa::ElementOperand: | 
| 335 |         return &UA_TYPES[UA_TYPES_ELEMENTOPERAND]; | 
| 336 |     case QOpcUa::RelativePathElement: | 
| 337 |         return &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]; | 
| 338 |     case QOpcUa::ContentFilterElement: | 
| 339 |         return &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]; | 
| 340 |     case QOpcUa::EventFilter: | 
| 341 |         return &UA_TYPES[UA_TYPES_EVENTFILTER]; | 
| 342 |     default: | 
| 343 |         qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Trying to convert undefined type:"  << valueType; | 
| 344 |         return nullptr; | 
| 345 |     } | 
| 346 | } | 
| 347 |  | 
| 348 | template<typename TARGETTYPE, typename UATYPE> | 
| 349 | TARGETTYPE scalarToQt(const UATYPE *data) | 
| 350 | { | 
| 351 |     return *reinterpret_cast<const TARGETTYPE *>(data); | 
| 352 | } | 
| 353 |  | 
| 354 | template<> | 
| 355 | QString scalarToQt<QString, UA_String>(const UA_String *data) | 
| 356 | { | 
| 357 |     return QString::fromUtf8(utf8: reinterpret_cast<const char *>(data->data), size: data->length); | 
| 358 | } | 
| 359 |  | 
| 360 | template<> | 
| 361 | QByteArray scalarToQt<QByteArray, UA_ByteString>(const UA_ByteString *data) | 
| 362 | { | 
| 363 |     return QByteArray(reinterpret_cast<const char *>(data->data), data->length); | 
| 364 | } | 
| 365 |  | 
| 366 | template<> | 
| 367 | QOpcUaLocalizedText scalarToQt<QOpcUaLocalizedText, UA_LocalizedText>(const UA_LocalizedText *data) | 
| 368 | { | 
| 369 |     QOpcUaLocalizedText lt; | 
| 370 |     lt.setLocale(scalarToQt<QString, UA_String>(data: &(data->locale))); | 
| 371 |     lt.setText(scalarToQt<QString, UA_String>(data: &(data->text))); | 
| 372 |     return lt; | 
| 373 | } | 
| 374 |  | 
| 375 | template<> | 
| 376 | QString scalarToQt<QString, UA_NodeId>(const UA_NodeId *data) | 
| 377 | { | 
| 378 |     return Open62541Utils::nodeIdToQString(id: *data); | 
| 379 | } | 
| 380 |  | 
| 381 | template<> | 
| 382 | QDateTime scalarToQt<QDateTime, UA_DateTime>(const UA_DateTime *data) | 
| 383 | { | 
| 384 |     // OPC UA 1.05 part 6, 5.1.4 | 
| 385 |     if (*data == (std::numeric_limits<qint64>::min)() || *data == (std::numeric_limits<qint64>::max)()) | 
| 386 |         return QDateTime(); | 
| 387 |  | 
| 388 |     const QDateTime epochStart(QDate(1601, 1, 1), QTime(0, 0), QTimeZone::UTC); | 
| 389 |     return epochStart.addMSecs(msecs: *data / UA_DATETIME_MSEC).toLocalTime(); | 
| 390 | } | 
| 391 |  | 
| 392 | template<> | 
| 393 | QOpcUaDataValue scalarToQt<QOpcUaDataValue, UA_DataValue>(const UA_DataValue *data) | 
| 394 | { | 
| 395 |     QOpcUaDataValue result; | 
| 396 |     if (data->hasSourceTimestamp) | 
| 397 |         result.setSourceTimestamp(QOpen62541ValueConverter::scalarToQt<QDateTime, UA_DateTime>(data: &data->sourceTimestamp)); | 
| 398 |     if (data->hasServerTimestamp) | 
| 399 |         result.setServerTimestamp(QOpen62541ValueConverter::scalarToQt<QDateTime, UA_DateTime>(data: &data->serverTimestamp)); | 
| 400 |     if (data->hasValue) | 
| 401 |         result.setValue(QOpen62541ValueConverter::toQVariant(value: data->value)); | 
| 402 |     if (data->hasStatus) { | 
| 403 |         result.setStatusCode(QOpen62541ValueConverter::scalarToQt<QOpcUa::UaStatusCode, UA_StatusCode>(data: &data->status)); | 
| 404 |     } else { | 
| 405 |         result.setStatusCode(QOpcUa::UaStatusCode::Good); | 
| 406 |     } | 
| 407 |     if (data->hasServerPicoseconds) | 
| 408 |         result.setServerPicoseconds(data->serverPicoseconds); | 
| 409 |     if (data->hasSourcePicoseconds) | 
| 410 |         result.setSourcePicoseconds(data->sourcePicoseconds); | 
| 411 |  | 
| 412 |     return result; | 
| 413 | } | 
| 414 |  | 
| 415 | template<> | 
| 416 | QUuid scalarToQt<QUuid, UA_Guid>(const UA_Guid *data) | 
| 417 | { | 
| 418 |     return QUuid(data->data1, data->data2, data->data3, data->data4[0], data->data4[1], data->data4[2], | 
| 419 |             data->data4[3], data->data4[4], data->data4[5], data->data4[6], data->data4[7]); | 
| 420 | } | 
| 421 |  | 
| 422 | template<> | 
| 423 | QOpcUaQualifiedName scalarToQt<QOpcUaQualifiedName, UA_QualifiedName>(const UA_QualifiedName *data) | 
| 424 | { | 
| 425 |     QOpcUaQualifiedName temp; | 
| 426 |     temp.setNamespaceIndex(data->namespaceIndex); | 
| 427 |     temp.setName(scalarToQt<QString, UA_String>(data: &(data->name))); | 
| 428 |     return temp; | 
| 429 | } | 
| 430 |  | 
| 431 | template<> | 
| 432 | QOpcUaArgument scalarToQt<QOpcUaArgument, UA_Argument>(const UA_Argument *data) | 
| 433 | { | 
| 434 |     QOpcUaArgument temp; | 
| 435 |     temp.setValueRank(data->valueRank); | 
| 436 |     temp.setDataTypeId(Open62541Utils::nodeIdToQString(id: data->dataType)); | 
| 437 |     temp.setName(scalarToQt<QString, UA_String>(data: &data->name)); | 
| 438 |     temp.setDescription(scalarToQt<QOpcUaLocalizedText, UA_LocalizedText>(data: &data->description)); | 
| 439 |     for (size_t i = 0; i < data->arrayDimensionsSize; ++i) | 
| 440 |         temp.arrayDimensionsRef().append(t: data->arrayDimensions[i]); | 
| 441 |     return temp; | 
| 442 | } | 
| 443 |  | 
| 444 | template<> | 
| 445 | QOpcUaRange scalarToQt<QOpcUaRange, UA_Range>(const UA_Range *data) | 
| 446 | { | 
| 447 |     return QOpcUaRange(data->low, data->high); | 
| 448 | } | 
| 449 |  | 
| 450 | template<> | 
| 451 | QOpcUaEUInformation scalarToQt<QOpcUaEUInformation, UA_EUInformation>(const UA_EUInformation *data) | 
| 452 | { | 
| 453 |     return QOpcUaEUInformation(scalarToQt<QString, UA_String>(data: &data->namespaceUri), | 
| 454 |                              data->unitId, | 
| 455 |                              scalarToQt<QOpcUaLocalizedText, UA_LocalizedText>(data: &data->displayName), | 
| 456 |                              scalarToQt<QOpcUaLocalizedText, UA_LocalizedText>(data: &data->description)); | 
| 457 | } | 
| 458 |  | 
| 459 | template<> | 
| 460 | QOpcUaComplexNumber scalarToQt<QOpcUaComplexNumber, UA_ComplexNumberType>(const UA_ComplexNumberType *data) | 
| 461 | { | 
| 462 |     return QOpcUaComplexNumber(data->real, data->imaginary); | 
| 463 | } | 
| 464 |  | 
| 465 | template<> | 
| 466 | QOpcUaDoubleComplexNumber scalarToQt<QOpcUaDoubleComplexNumber, UA_DoubleComplexNumberType>( | 
| 467 |         const UA_DoubleComplexNumberType *data) | 
| 468 | { | 
| 469 |     return QOpcUaDoubleComplexNumber(data->real, data->imaginary); | 
| 470 | } | 
| 471 |  | 
| 472 | template<> | 
| 473 | QOpcUaAxisInformation scalarToQt<QOpcUaAxisInformation, UA_AxisInformation>(const UA_AxisInformation *data) | 
| 474 | { | 
| 475 |     QList<double> axisSteps; | 
| 476 |  | 
| 477 |     if (data->axisStepsSize) { | 
| 478 |         axisSteps.reserve(asize: data->axisStepsSize); | 
| 479 |         std::copy(first: data->axisSteps, last: data->axisSteps + data->axisStepsSize, result: std::back_inserter(x&: axisSteps)); | 
| 480 |     } | 
| 481 |  | 
| 482 |     return QOpcUaAxisInformation(scalarToQt<QOpcUaEUInformation, UA_EUInformation>(data: &data->engineeringUnits), | 
| 483 |                                  scalarToQt<QOpcUaRange, UA_Range>(data: &data->eURange), | 
| 484 |                                  scalarToQt<QOpcUaLocalizedText, UA_LocalizedText>(data: &data->title), | 
| 485 |                                  static_cast<QOpcUa::AxisScale>(data->axisScaleType), | 
| 486 |                                  axisSteps); | 
| 487 | } | 
| 488 |  | 
| 489 | template<> | 
| 490 | QOpcUaXValue scalarToQt<QOpcUaXValue, UA_XVType>(const UA_XVType *data) | 
| 491 | { | 
| 492 |     return QOpcUaXValue(data->x, data->value); | 
| 493 | } | 
| 494 |  | 
| 495 | template<> | 
| 496 | QOpcUaStructureField scalarToQt<QOpcUaStructureField, UA_StructureField>(const UA_StructureField *data) | 
| 497 | { | 
| 498 |     QOpcUaStructureField temp; | 
| 499 |     temp.setName(scalarToQt<QString, UA_String>(data: &data->name)); | 
| 500 |     temp.setDescription(scalarToQt<QOpcUaLocalizedText, UA_LocalizedText>(data: &data->description)); | 
| 501 |     temp.setDataType(scalarToQt<QString, UA_NodeId>(data: &data->dataType)); | 
| 502 |     temp.setIsOptional(data->isOptional); | 
| 503 |     temp.setMaxStringLength(scalarToQt<quint32, UA_UInt32>(data: &data->maxStringLength)); | 
| 504 |     temp.setValueRank(scalarToQt<qint32, UA_Int32>(data: &data->valueRank)); | 
| 505 |  | 
| 506 |     QList<quint32> dimensions; | 
| 507 |     for (size_t i = 0; i < data->arrayDimensionsSize; ++i) | 
| 508 |         dimensions.append(t: data->arrayDimensions[i]); | 
| 509 |     temp.setArrayDimensions(dimensions); | 
| 510 |     return temp; | 
| 511 | } | 
| 512 |  | 
| 513 | template<> | 
| 514 | QOpcUaStructureDefinition scalarToQt<QOpcUaStructureDefinition, UA_StructureDefinition>(const UA_StructureDefinition *data) | 
| 515 | { | 
| 516 |     QOpcUaStructureDefinition temp; | 
| 517 |     temp.setBaseDataType(scalarToQt<QString, UA_NodeId>(data: &data->baseDataType)); | 
| 518 |     temp.setDefaultEncodingId(scalarToQt<QString, UA_NodeId>(data: &data->defaultEncodingId)); | 
| 519 |     temp.setStructureType(static_cast<QOpcUaStructureDefinition::StructureType>(data->structureType)); | 
| 520 |  | 
| 521 |     QList<QOpcUaStructureField> fields; | 
| 522 |     for (size_t i = 0; i < data->fieldsSize; ++i) | 
| 523 |         fields.append(t: scalarToQt<QOpcUaStructureField, UA_StructureField>(data: &data->fields[i])); | 
| 524 |     temp.setFields(fields); | 
| 525 |     return temp; | 
| 526 | } | 
| 527 |  | 
| 528 | template<> | 
| 529 | QOpcUaEnumField scalarToQt<QOpcUaEnumField, UA_EnumField>(const UA_EnumField *data) | 
| 530 | { | 
| 531 |     QOpcUaEnumField temp; | 
| 532 |     temp.setName(scalarToQt<QString, UA_String>(data: &data->name)); | 
| 533 |     temp.setDisplayName(scalarToQt<QOpcUaLocalizedText, UA_LocalizedText>(data: &data->displayName)); | 
| 534 |     temp.setValue(data->value); | 
| 535 |     temp.setDescription(scalarToQt<QOpcUaLocalizedText, UA_LocalizedText>(data: &data->description)); | 
| 536 |  | 
| 537 |     return temp; | 
| 538 | } | 
| 539 |  | 
| 540 | template<> | 
| 541 | QOpcUaEnumDefinition scalarToQt<QOpcUaEnumDefinition, UA_EnumDefinition>(const UA_EnumDefinition *data) | 
| 542 | { | 
| 543 |     QOpcUaEnumDefinition temp; | 
| 544 |  | 
| 545 |     QList<QOpcUaEnumField> fields; | 
| 546 |     for (size_t i = 0; i < data->fieldsSize; ++i) | 
| 547 |         fields.push_back(t: scalarToQt<QOpcUaEnumField, UA_EnumField>(data: &data->fields[i])); | 
| 548 |     temp.setFields(fields); | 
| 549 |  | 
| 550 |     return temp; | 
| 551 | } | 
| 552 |  | 
| 553 | template<> | 
| 554 | QOpcUaDiagnosticInfo scalarToQt<QOpcUaDiagnosticInfo, UA_DiagnosticInfo>(const UA_DiagnosticInfo *data) | 
| 555 | { | 
| 556 |     QOpcUaDiagnosticInfo temp; | 
| 557 |  | 
| 558 |     if (data->hasSymbolicId) { | 
| 559 |         temp.setHasSymbolicId(true); | 
| 560 |         temp.setSymbolicId(data->symbolicId); | 
| 561 |     } | 
| 562 |  | 
| 563 |     if (data->hasNamespaceUri) { | 
| 564 |         temp.setHasNamespaceUri(true); | 
| 565 |         temp.setNamespaceUri(data->namespaceUri); | 
| 566 |     } | 
| 567 |  | 
| 568 |     if (data->hasLocale) { | 
| 569 |         temp.setHasLocale(true); | 
| 570 |         temp.setLocale(data->locale); | 
| 571 |     } | 
| 572 |  | 
| 573 |     if (data->hasLocalizedText) { | 
| 574 |         temp.setHasLocalizedText(true); | 
| 575 |         temp.setLocalizedText(data->localizedText); | 
| 576 |     } | 
| 577 |  | 
| 578 |     if (data->hasAdditionalInfo) { | 
| 579 |         temp.setHasAdditionalInfo(true); | 
| 580 |         temp.setAdditionalInfo(scalarToQt<QString, UA_String>(data: &data->additionalInfo)); | 
| 581 |     } | 
| 582 |  | 
| 583 |     if (data->hasInnerStatusCode) { | 
| 584 |         temp.setHasInnerStatusCode(true); | 
| 585 |         temp.setInnerStatusCode(scalarToQt<QOpcUa::UaStatusCode, UA_StatusCode>(data: &data->innerStatusCode)); | 
| 586 |     } | 
| 587 |  | 
| 588 |     if (data->hasInnerDiagnosticInfo) { | 
| 589 |         temp.setHasInnerDiagnosticInfo(true); | 
| 590 |         if (data->innerDiagnosticInfo) | 
| 591 |             temp.setInnerDiagnosticInfo(scalarToQt<QOpcUaDiagnosticInfo, UA_DiagnosticInfo>(data: data->innerDiagnosticInfo)); | 
| 592 |     } | 
| 593 |  | 
| 594 |     return temp; | 
| 595 | } | 
| 596 |  | 
| 597 | template<> | 
| 598 | QOpcUaSimpleAttributeOperand scalarToQt<QOpcUaSimpleAttributeOperand, UA_SimpleAttributeOperand>(const UA_SimpleAttributeOperand *data) | 
| 599 | { | 
| 600 |     QOpcUaSimpleAttributeOperand result; | 
| 601 |  | 
| 602 |     result.setAttributeId(toQtAttributeId(attr: static_cast<UA_AttributeId>(data->attributeId))); | 
| 603 |     result.setIndexRange(scalarToQt<QString, UA_String>(data: &data->indexRange)); | 
| 604 |     result.setTypeId(scalarToQt<QString, UA_NodeId>(data: &data->typeDefinitionId)); | 
| 605 |  | 
| 606 |     QList<QOpcUaQualifiedName> browsePath; | 
| 607 |     for (size_t i = 0; i < data->browsePathSize; ++i) | 
| 608 |         browsePath.push_back(t: scalarToQt<QOpcUaQualifiedName, UA_QualifiedName>(data: &data->browsePath[i])); | 
| 609 |  | 
| 610 |     result.setBrowsePath(browsePath); | 
| 611 |  | 
| 612 |     return result; | 
| 613 | } | 
| 614 |  | 
| 615 | template<> | 
| 616 | QOpcUaLiteralOperand scalarToQt<QOpcUaLiteralOperand, UA_LiteralOperand>(const UA_LiteralOperand *data) | 
| 617 | { | 
| 618 |     QOpcUaLiteralOperand result; | 
| 619 |     result.setValue(toQVariant(value: data->value)); | 
| 620 |     result.setType(toQtDataType(type: data->value.type)); | 
| 621 |  | 
| 622 |     return result; | 
| 623 | } | 
| 624 |  | 
| 625 | template<> | 
| 626 | QOpcUaElementOperand scalarToQt<QOpcUaElementOperand, UA_ElementOperand>(const UA_ElementOperand *data) | 
| 627 | { | 
| 628 |     QOpcUaElementOperand result; | 
| 629 |     result.setIndex(data->index); | 
| 630 |  | 
| 631 |     return result; | 
| 632 | } | 
| 633 |  | 
| 634 | template<> | 
| 635 | QOpcUaRelativePathElement scalarToQt<QOpcUaRelativePathElement, UA_RelativePathElement>(const UA_RelativePathElement *data) | 
| 636 | { | 
| 637 |     QOpcUaRelativePathElement result; | 
| 638 |     result.setIncludeSubtypes(data->includeSubtypes); | 
| 639 |     result.setIsInverse(data->isInverse); | 
| 640 |     result.setReferenceTypeId(scalarToQt<QString, UA_NodeId>(data: &data->referenceTypeId)); | 
| 641 |     result.setTargetName(scalarToQt<QOpcUaQualifiedName, UA_QualifiedName>(data: &data->targetName)); | 
| 642 |  | 
| 643 |     return result; | 
| 644 | } | 
| 645 |  | 
| 646 | template<> | 
| 647 | QOpcUaAttributeOperand scalarToQt<QOpcUaAttributeOperand, UA_AttributeOperand>(const UA_AttributeOperand *data) | 
| 648 | { | 
| 649 |     QOpcUaAttributeOperand result; | 
| 650 |     result.setAttributeId(toQtAttributeId(attr: static_cast<UA_AttributeId>(data->attributeId))); | 
| 651 |     result.setNodeId(scalarToQt<QString, UA_NodeId>(data: &data->nodeId)); | 
| 652 |     result.setAlias(scalarToQt<QString, UA_String>(data: &data->alias)); | 
| 653 |     result.setIndexRange(scalarToQt<QString, UA_String>(data: &data->indexRange)); | 
| 654 |  | 
| 655 |     QList<QOpcUaRelativePathElement> browsePath; | 
| 656 |  | 
| 657 |     for (size_t i = 0; i < data->browsePath.elementsSize; ++i) | 
| 658 |         browsePath.push_back(t: scalarToQt<QOpcUaRelativePathElement, UA_RelativePathElement>(data: &data->browsePath.elements[i])); | 
| 659 |  | 
| 660 |     result.setBrowsePath(browsePath); | 
| 661 |  | 
| 662 |     return result; | 
| 663 | } | 
| 664 |  | 
| 665 | template<> | 
| 666 | QOpcUaContentFilterElement scalarToQt<QOpcUaContentFilterElement, UA_ContentFilterElement>(const UA_ContentFilterElement *data) | 
| 667 | { | 
| 668 |     QOpcUaContentFilterElement result; | 
| 669 |  | 
| 670 |     result.setFilterOperator(QOpcUaContentFilterElement::FilterOperator(data->filterOperator)); | 
| 671 |     QVariantList filterOperands; | 
| 672 |  | 
| 673 |     for (size_t i = 0; i < data->filterOperandsSize; ++i) { | 
| 674 |         if (data->filterOperands[i].encoding < UA_EXTENSIONOBJECT_DECODED) { | 
| 675 |             filterOperands.push_back(t: scalarToQt<QOpcUaExtensionObject, UA_ExtensionObject>(data: &data->filterOperands[i])); | 
| 676 |         } else if (data->filterOperands[i].content.decoded.type == &UA_TYPES[UA_TYPES_LITERALOPERAND]) { | 
| 677 |             filterOperands.push_back(t: scalarToQt<QOpcUaLiteralOperand, UA_LiteralOperand>( | 
| 678 |                 data: static_cast<UA_LiteralOperand *>(data->filterOperands[i].content.decoded.data))); | 
| 679 |         } else if (data->filterOperands[i].content.decoded.type == &UA_TYPES[UA_TYPES_ELEMENTOPERAND]) { | 
| 680 |             filterOperands.push_back(t: scalarToQt<QOpcUaElementOperand, UA_ElementOperand>( | 
| 681 |                 data: static_cast<UA_ElementOperand *>(data->filterOperands[i].content.decoded.data))); | 
| 682 |         } else if (data->filterOperands[i].content.decoded.type == &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]) { | 
| 683 |             filterOperands.push_back(t: scalarToQt<QOpcUaAttributeOperand, UA_AttributeOperand>( | 
| 684 |                 data: static_cast<UA_AttributeOperand *>(data->filterOperands[i].content.decoded.data))); | 
| 685 |         } else if (data->filterOperands[i].content.decoded.type == &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]) { | 
| 686 |             filterOperands.push_back(t: scalarToQt<QOpcUaSimpleAttributeOperand, UA_SimpleAttributeOperand>( | 
| 687 |                 data: static_cast<UA_SimpleAttributeOperand *>(data->filterOperands[i].content.decoded.data))); | 
| 688 |         } else { | 
| 689 |             qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Unknown operand in content filter element, unable to convert" ; | 
| 690 |             return {}; | 
| 691 |         } | 
| 692 |     } | 
| 693 |  | 
| 694 |     result.setFilterOperands(filterOperands); | 
| 695 |  | 
| 696 |     return result; | 
| 697 | } | 
| 698 |  | 
| 699 | template<> | 
| 700 | QOpcUaMonitoringParameters::EventFilter scalarToQt<QOpcUaMonitoringParameters::EventFilter, UA_EventFilter>(const UA_EventFilter *data) | 
| 701 | { | 
| 702 |     QOpcUaMonitoringParameters::EventFilter eventFilter; | 
| 703 |  | 
| 704 |     for (size_t i = 0; i < data->selectClausesSize; ++i) { | 
| 705 |         eventFilter << scalarToQt<QOpcUaSimpleAttributeOperand, UA_SimpleAttributeOperand>(data: &data->selectClauses[i]); | 
| 706 |     } | 
| 707 |  | 
| 708 |     for (size_t i = 0; i < data->whereClause.elementsSize; ++i) { | 
| 709 |         eventFilter << scalarToQt<QOpcUaContentFilterElement, UA_ContentFilterElement>(data: &data->whereClause.elements[i]); | 
| 710 |     } | 
| 711 |  | 
| 712 |     return eventFilter; | 
| 713 | } | 
| 714 |  | 
| 715 | template <> | 
| 716 | QVariant scalarToQt<QVariant, UA_ExtensionObject>(const UA_ExtensionObject *data) | 
| 717 | { | 
| 718 |     // OPC UA 1.05 part 6, 5.2.2.15 states that an extension object can have no body, a ByteString encoded body | 
| 719 |     // or an XML encoded body. | 
| 720 |  | 
| 721 |     // Handle extension object without body | 
| 722 |     if (data->encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY) { | 
| 723 |         QOpcUaExtensionObject obj; | 
| 724 |         obj.setEncoding(QOpcUaExtensionObject::Encoding::NoBody); | 
| 725 |         return QVariant::fromValue(value: obj); | 
| 726 |     } | 
| 727 |  | 
| 728 |     // Some types are automatically decoded by open62541. In this case, the encoding is UA_EXTENSIONOBJECT_DECODED | 
| 729 |     if (data->encoding != UA_EXTENSIONOBJECT_ENCODED_XML && data->encoding != UA_EXTENSIONOBJECT_ENCODED_BYTESTRING) { | 
| 730 |  | 
| 731 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_ARGUMENT] && data->content.decoded.data != nullptr) { | 
| 732 |             return scalarToQt<QOpcUaArgument, UA_Argument>(data: reinterpret_cast<UA_Argument *>(data->content.decoded.data)); | 
| 733 |         } | 
| 734 |  | 
| 735 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_RANGE] && data->content.decoded.data != nullptr) { | 
| 736 |             return scalarToQt<QOpcUaRange, UA_Range>(data: reinterpret_cast<UA_Range *>(data->content.decoded.data)); | 
| 737 |         } | 
| 738 |  | 
| 739 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_EUINFORMATION] && data->content.decoded.data) { | 
| 740 |             return scalarToQt<QOpcUaEUInformation, UA_EUInformation> | 
| 741 |                     (data: reinterpret_cast<UA_EUInformation *>(data->content.decoded.data)); | 
| 742 |         } | 
| 743 |  | 
| 744 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE] && data->content.decoded.data) { | 
| 745 |             return scalarToQt<QOpcUaComplexNumber, UA_ComplexNumberType> | 
| 746 |                     (data: reinterpret_cast<UA_ComplexNumberType *>(data->content.decoded.data)); | 
| 747 |         } | 
| 748 |  | 
| 749 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE] && data->content.decoded.data) { | 
| 750 |             return scalarToQt<QOpcUaDoubleComplexNumber, UA_DoubleComplexNumberType> | 
| 751 |                     (data: reinterpret_cast<UA_DoubleComplexNumberType *>(data->content.decoded.data)); | 
| 752 |         } | 
| 753 |  | 
| 754 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_AXISINFORMATION] && data->content.decoded.data) { | 
| 755 |             return scalarToQt<QOpcUaAxisInformation, UA_AxisInformation> | 
| 756 |                     (data: reinterpret_cast<UA_AxisInformation *>(data->content.decoded.data)); | 
| 757 |         } | 
| 758 |  | 
| 759 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_XVTYPE] && data->content.decoded.data) { | 
| 760 |             return scalarToQt<QOpcUaXValue, UA_XVType> | 
| 761 |                     (data: reinterpret_cast<UA_XVType *>(data->content.decoded.data)); | 
| 762 |         } | 
| 763 |  | 
| 764 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]) { | 
| 765 |             return scalarToQt<QOpcUaStructureDefinition, UA_StructureDefinition> | 
| 766 |                     (data: reinterpret_cast<UA_StructureDefinition *>(data->content.decoded.data)); | 
| 767 |         } | 
| 768 |  | 
| 769 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_STRUCTUREFIELD]) { | 
| 770 |             return scalarToQt<QOpcUaStructureField, UA_StructureField> | 
| 771 |                     (data: reinterpret_cast<UA_StructureField *>(data->content.decoded.data)); | 
| 772 |         } | 
| 773 |  | 
| 774 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_ENUMDEFINITION]) { | 
| 775 |             return scalarToQt<QOpcUaEnumDefinition, UA_EnumDefinition> | 
| 776 |                     (data: reinterpret_cast<UA_EnumDefinition *>(data->content.decoded.data)); | 
| 777 |         } | 
| 778 |  | 
| 779 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_ENUMFIELD]) { | 
| 780 |             return scalarToQt<QOpcUaEnumField, UA_EnumField> | 
| 781 |                     (data: reinterpret_cast<UA_EnumField *>(data->content.decoded.data)); | 
| 782 |         } | 
| 783 |  | 
| 784 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND] && data->content.decoded.data) { | 
| 785 |             return scalarToQt<QOpcUaSimpleAttributeOperand, UA_SimpleAttributeOperand> | 
| 786 |                 (data: reinterpret_cast<UA_SimpleAttributeOperand *>(data->content.decoded.data)); | 
| 787 |         } | 
| 788 |  | 
| 789 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND] && data->content.decoded.data) { | 
| 790 |             return scalarToQt<QOpcUaAttributeOperand, UA_AttributeOperand> | 
| 791 |                 (data: reinterpret_cast<UA_AttributeOperand *>(data->content.decoded.data)); | 
| 792 |         } | 
| 793 |  | 
| 794 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_LITERALOPERAND] && data->content.decoded.data) { | 
| 795 |             return scalarToQt<QOpcUaLiteralOperand, UA_LiteralOperand> | 
| 796 |                 (data: reinterpret_cast<UA_LiteralOperand *>(data->content.decoded.data)); | 
| 797 |         } | 
| 798 |  | 
| 799 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_ELEMENTOPERAND] && data->content.decoded.data) { | 
| 800 |             return scalarToQt<QOpcUaElementOperand, UA_ElementOperand> | 
| 801 |                 (data: reinterpret_cast<UA_ElementOperand *>(data->content.decoded.data)); | 
| 802 |         } | 
| 803 |  | 
| 804 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT] && data->content.decoded.data) { | 
| 805 |             return scalarToQt<QOpcUaRelativePathElement, UA_RelativePathElement> | 
| 806 |                 (data: reinterpret_cast<UA_RelativePathElement *>(data->content.decoded.data)); | 
| 807 |         } | 
| 808 |  | 
| 809 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT] && data->content.decoded.data) { | 
| 810 |             return scalarToQt<QOpcUaContentFilterElement, UA_ContentFilterElement> | 
| 811 |                 (data: reinterpret_cast<UA_ContentFilterElement *>(data->content.decoded.data)); | 
| 812 |         } | 
| 813 |  | 
| 814 |         if (data->content.decoded.type == &UA_TYPES[UA_TYPES_EVENTFILTER] && data->content.decoded.data) { | 
| 815 |             return scalarToQt<QOpcUaMonitoringParameters::EventFilter, UA_EventFilter> | 
| 816 |                 (data: reinterpret_cast<UA_EventFilter *>(data->content.decoded.data)); | 
| 817 |         } | 
| 818 |  | 
| 819 |         bool success = false; | 
| 820 |         const auto result = encodeAsBinaryExtensionObject(data: data->content.decoded.data, type: data->content.decoded.type, success: &success); | 
| 821 |         if (success) | 
| 822 |             return result; | 
| 823 |  | 
| 824 |         qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to re-encode decoded extension object, unable to convert"  << data->content.decoded.type->typeName; | 
| 825 |         return {}; | 
| 826 |     } | 
| 827 |  | 
| 828 |     QByteArray buffer = QByteArray::fromRawData(data: reinterpret_cast<const char *>(data->content.encoded.body.data), | 
| 829 |                                                 size: data->content.encoded.body.length); | 
| 830 |  | 
| 831 |     // Return extension objects with binary or XML body as QOpcUaExtensionObject | 
| 832 |     QOpcUaExtensionObject obj; | 
| 833 |     obj.setEncoding(static_cast<QOpcUaExtensionObject::Encoding>(data->encoding)); | 
| 834 |     obj.setEncodingTypeId(Open62541Utils::nodeIdToQString(id: data->content.encoded.typeId)); | 
| 835 |     obj.setEncodedBody(QByteArray(buffer.constData(), buffer.size())); | 
| 836 |     return obj; | 
| 837 | } | 
| 838 |  | 
| 839 | template<> | 
| 840 | QOpcUaExpandedNodeId scalarToQt<QOpcUaExpandedNodeId, UA_ExpandedNodeId>(const UA_ExpandedNodeId *data) | 
| 841 | { | 
| 842 |     QOpcUaExpandedNodeId temp; | 
| 843 |     temp.setServerIndex(data->serverIndex); | 
| 844 |     temp.setNodeId(Open62541Utils::nodeIdToQString(id: data->nodeId)); | 
| 845 |     temp.setNamespaceUri(scalarToQt<QString, UA_String>(data: &data->namespaceUri)); | 
| 846 |     return temp; | 
| 847 | } | 
| 848 |  | 
| 849 | template<typename TARGETTYPE, typename UATYPE> | 
| 850 | QVariant arrayToQVariant(const UA_Variant &var, QMetaType::Type type) | 
| 851 | { | 
| 852 |     UATYPE *temp = static_cast<UATYPE *>(var.data); | 
| 853 |  | 
| 854 |     if (var.arrayLength > 0) { | 
| 855 |         QVariantList list(var.arrayLength); | 
| 856 |         for (size_t i = 0; i < var.arrayLength; ++i) { | 
| 857 |             QVariant tempVar = QVariant::fromValue(scalarToQt<TARGETTYPE, UATYPE>(&temp[i])); | 
| 858 |             if (type != QMetaType::UnknownType && type != static_cast<QMetaType::Type>(tempVar.metaType().id())) | 
| 859 |                 tempVar.convert(type: QMetaType(type)); | 
| 860 |             list[i] = tempVar; | 
| 861 |         } | 
| 862 |  | 
| 863 |         if (var.arrayDimensionsSize > 0) { | 
| 864 |             // Ensure that the array dimensions fit in a QList | 
| 865 |             if (var.arrayDimensionsSize > static_cast<quint64>((std::numeric_limits<int>::max)())) | 
| 866 |                 return QOpcUaMultiDimensionalArray(); | 
| 867 |             QList<quint32> arrayDimensions; | 
| 868 |             std::copy(first: var.arrayDimensions, last: var.arrayDimensions+var.arrayDimensionsSize, result: std::back_inserter(x&: arrayDimensions)); | 
| 869 |             return QOpcUaMultiDimensionalArray(list, arrayDimensions); | 
| 870 |         } | 
| 871 |  | 
| 872 |         if (list.size() == 1) | 
| 873 |             return list.at(i: 0); | 
| 874 |         else | 
| 875 |             return list; | 
| 876 |     } else if (UA_Variant_isScalar(v: &var)) { | 
| 877 |         QVariant tempVar = QVariant::fromValue(scalarToQt<TARGETTYPE, UATYPE>(temp)); | 
| 878 |         if (type != QMetaType::UnknownType && type != static_cast<QMetaType::Type>(tempVar.metaType().id())) | 
| 879 |             tempVar.convert(type: QMetaType(type)); | 
| 880 |         return tempVar; | 
| 881 |     } else if (var.arrayLength == 0 && var.data == UA_EMPTY_ARRAY_SENTINEL) { | 
| 882 |         return QVariantList(); // Return empty QVariantList for empty array | 
| 883 |     } | 
| 884 |  | 
| 885 |     return QVariant(); // Return empty QVariant for empty scalar variant | 
| 886 | } | 
| 887 |  | 
| 888 | template<typename TARGETTYPE, typename QTTYPE> | 
| 889 | void scalarFromQt(const QTTYPE &value, TARGETTYPE *ptr) | 
| 890 | { | 
| 891 |     *ptr = static_cast<TARGETTYPE>(value); | 
| 892 | } | 
| 893 |  | 
| 894 | template<> | 
| 895 | void scalarFromQt<UA_DateTime, QDateTime>(const QDateTime &value, UA_DateTime *ptr) | 
| 896 | { | 
| 897 |     if (!value.isValid()) { | 
| 898 |         *ptr = (std::numeric_limits<qint64>::min)(); | 
| 899 |         return; | 
| 900 |     } | 
| 901 |  | 
| 902 |     // OPC UA 1.05 part 6, 5.1.4 | 
| 903 |     const QDateTime uaEpochStart(QDate(1601, 1, 1), QTime(0, 0), QTimeZone::UTC); | 
| 904 |  | 
| 905 |     *ptr = UA_DATETIME_MSEC * (value.toMSecsSinceEpoch() - uaEpochStart.toMSecsSinceEpoch()); | 
| 906 | } | 
| 907 |  | 
| 908 | template<> | 
| 909 | void scalarFromQt<UA_String, QString>(const QString &value, UA_String *ptr) | 
| 910 | { | 
| 911 |     *ptr = UA_STRING_ALLOC(value.toUtf8().constData()); | 
| 912 | } | 
| 913 |  | 
| 914 | template<> | 
| 915 | void scalarFromQt<UA_LocalizedText, QOpcUaLocalizedText>(const QOpcUaLocalizedText &value, UA_LocalizedText *ptr) | 
| 916 | { | 
| 917 |     scalarFromQt<UA_String, QString>(value: value.locale(), ptr: &(ptr->locale)); | 
| 918 |     scalarFromQt<UA_String, QString>(value: value.text(), ptr: &(ptr->text)); | 
| 919 | } | 
| 920 |  | 
| 921 | template<> | 
| 922 | void scalarFromQt<UA_ByteString, QByteArray>(const QByteArray &value, UA_ByteString *ptr) | 
| 923 | { | 
| 924 |     ptr->length = value.size(); | 
| 925 |     UA_StatusCode success = UA_Array_copy(src: reinterpret_cast<const UA_Byte *>(value.constData()), | 
| 926 |                                           size: value.size(), dst: reinterpret_cast<void **>(&ptr->data), type: &UA_TYPES[UA_TYPES_BYTE]); | 
| 927 |     if (success != UA_STATUSCODE_GOOD) { | 
| 928 |         ptr->length = 0; | 
| 929 |         ptr->data = nullptr; | 
| 930 |     } | 
| 931 | } | 
| 932 |  | 
| 933 | template<> | 
| 934 | void scalarFromQt<UA_NodeId, QString>(const QString &value, UA_NodeId *ptr) | 
| 935 | { | 
| 936 |     *ptr = Open62541Utils::nodeIdFromQString(name: value); | 
| 937 | } | 
| 938 |  | 
| 939 | template<> | 
| 940 | void scalarFromQt<UA_QualifiedName, QOpcUaQualifiedName>(const QOpcUaQualifiedName &value, UA_QualifiedName *ptr) | 
| 941 | { | 
| 942 |     ptr->namespaceIndex = value.namespaceIndex(); | 
| 943 |     scalarFromQt<UA_String, QString>(value: value.name(), ptr: &(ptr->name)); | 
| 944 | } | 
| 945 |  | 
| 946 | template<> | 
| 947 | void scalarFromQt<UA_Guid, QUuid>(const QUuid &value, UA_Guid *ptr) | 
| 948 | { | 
| 949 |     ptr->data1 = value.data1; | 
| 950 |     ptr->data2 = value.data2; | 
| 951 |     ptr->data3 = value.data3; | 
| 952 |     std::memcpy(dest: ptr->data4, src: value.data4, n: sizeof(value.data4)); | 
| 953 | } | 
| 954 |  | 
| 955 | template<> | 
| 956 | void scalarFromQt<UA_Range, QOpcUaRange>(const QOpcUaRange &value, UA_Range *ptr) | 
| 957 | { | 
| 958 |     ptr->low = value.low(); | 
| 959 |     ptr->high = value.high(); | 
| 960 | } | 
| 961 |  | 
| 962 | template<> | 
| 963 | void scalarFromQt<UA_EUInformation, QOpcUaEUInformation>(const QOpcUaEUInformation &value, UA_EUInformation *ptr) | 
| 964 | { | 
| 965 |     scalarFromQt<UA_String, QString>(value: value.namespaceUri(), ptr: &ptr->namespaceUri); | 
| 966 |     scalarFromQt<UA_LocalizedText, QOpcUaLocalizedText>(value: value.description(), ptr: &ptr->description); | 
| 967 |     scalarFromQt<UA_LocalizedText, QOpcUaLocalizedText>(value: value.displayName(), ptr: &ptr->displayName); | 
| 968 |     ptr->unitId = value.unitId(); | 
| 969 | } | 
| 970 |  | 
| 971 | template<> | 
| 972 | void scalarFromQt<UA_ComplexNumberType, QOpcUaComplexNumber>(const QOpcUaComplexNumber &value, UA_ComplexNumberType *ptr) | 
| 973 | { | 
| 974 |     ptr->real = value.real(); | 
| 975 |     ptr->imaginary = value.imaginary(); | 
| 976 | } | 
| 977 |  | 
| 978 | template<> | 
| 979 | void scalarFromQt<UA_DoubleComplexNumberType, QOpcUaDoubleComplexNumber>(const QOpcUaDoubleComplexNumber &value, UA_DoubleComplexNumberType *ptr) | 
| 980 | { | 
| 981 |     ptr->real = value.real(); | 
| 982 |     ptr->imaginary = value.imaginary(); | 
| 983 | } | 
| 984 |  | 
| 985 | template<> | 
| 986 | void scalarFromQt<UA_AxisInformation, QOpcUaAxisInformation>(const QOpcUaAxisInformation &value, UA_AxisInformation *ptr) | 
| 987 | { | 
| 988 |     scalarFromQt<UA_LocalizedText, QOpcUaLocalizedText>(value: value.title(), ptr: &ptr->title); | 
| 989 |     scalarFromQt<UA_EUInformation, QOpcUaEUInformation>(value: value.engineeringUnits(), ptr: &ptr->engineeringUnits); | 
| 990 |     scalarFromQt<UA_Range, QOpcUaRange>(value: value.eURange(), ptr: &ptr->eURange); | 
| 991 |     ptr->axisScaleType = static_cast<UA_AxisScaleEnumeration>(value.axisScaleType()); | 
| 992 |     ptr->axisStepsSize = value.axisSteps().size(); | 
| 993 |     if (ptr->axisStepsSize) { | 
| 994 |         auto res = UA_Array_copy(src: value.axisSteps().constData(), size: ptr->axisStepsSize, dst: reinterpret_cast<void **>(&ptr->axisSteps), | 
| 995 |                       type: &UA_TYPES[UA_TYPES_DOUBLE]); | 
| 996 |  | 
| 997 |         if (res != UA_STATUSCODE_GOOD) | 
| 998 |             qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to copy axis steps" ; | 
| 999 |     } else { | 
| 1000 |         ptr->axisSteps = nullptr; | 
| 1001 |     } | 
| 1002 | } | 
| 1003 |  | 
| 1004 | template<> | 
| 1005 | void scalarFromQt<UA_XVType, QOpcUaXValue>(const QOpcUaXValue &value, UA_XVType *ptr) | 
| 1006 | { | 
| 1007 |     ptr->x = value.x(); | 
| 1008 |     ptr->value = value.value(); | 
| 1009 | } | 
| 1010 |  | 
| 1011 | template<> | 
| 1012 | void scalarFromQt<UA_StructureField, QOpcUaStructureField>(const QOpcUaStructureField &value, UA_StructureField *ptr) | 
| 1013 | { | 
| 1014 |     scalarFromQt<UA_NodeId, QString>(value: value.dataType(), ptr: &ptr->dataType); | 
| 1015 |     ptr->maxStringLength = value.maxStringLength(); | 
| 1016 |     ptr->isOptional = value.isOptional(); | 
| 1017 |     ptr->valueRank = value.valueRank(); | 
| 1018 |     scalarFromQt<UA_String, QString>(value: value.name(), ptr: &ptr->name); | 
| 1019 |     scalarFromQt<UA_LocalizedText, QOpcUaLocalizedText>(value: value.description(), ptr: &ptr->description); | 
| 1020 |  | 
| 1021 |     ptr->arrayDimensionsSize = value.arrayDimensions().size(); | 
| 1022 |     if (ptr->arrayDimensionsSize) { | 
| 1023 |         ptr->arrayDimensions = static_cast<quint32 *>(UA_Array_new(size: ptr->arrayDimensionsSize, type: &UA_TYPES[UA_TYPES_UINT32])); | 
| 1024 |  | 
| 1025 |         for (int i = 0; i < value.arrayDimensions().size(); ++i) | 
| 1026 |             ptr->arrayDimensions[i] = value.arrayDimensions().at(i); | 
| 1027 |     } | 
| 1028 | } | 
| 1029 |  | 
| 1030 | template<> | 
| 1031 | void scalarFromQt<UA_StructureDefinition, QOpcUaStructureDefinition>(const QOpcUaStructureDefinition &value, UA_StructureDefinition *ptr) | 
| 1032 | { | 
| 1033 |     scalarFromQt<UA_NodeId, QString>(value: value.baseDataType(), ptr: &ptr->baseDataType); | 
| 1034 |     scalarFromQt<UA_NodeId, QString>(value: value.defaultEncodingId(), ptr: &ptr->defaultEncodingId); | 
| 1035 |     ptr->structureType = static_cast<UA_StructureType>(value.structureType()); | 
| 1036 |  | 
| 1037 |     if (!value.fields().isEmpty()) { | 
| 1038 |         ptr->fieldsSize = value.fields().size(); | 
| 1039 |         ptr->fields = static_cast<UA_StructureField *>(UA_Array_new(size: ptr->fieldsSize, type: &UA_TYPES[UA_TYPES_STRUCTUREFIELD])); | 
| 1040 |  | 
| 1041 |         for (int i = 0; i < value.fields().size(); ++i) | 
| 1042 |             scalarFromQt<UA_StructureField, QOpcUaStructureField>(value: value.fields().at(i), ptr: &ptr->fields[i]); | 
| 1043 |     } | 
| 1044 | } | 
| 1045 |  | 
| 1046 | template<> | 
| 1047 | void scalarFromQt<UA_EnumField, QOpcUaEnumField>(const QOpcUaEnumField &value, UA_EnumField *ptr) | 
| 1048 | { | 
| 1049 |     scalarFromQt<UA_String, QString>(value: value.name(), ptr: &ptr->name); | 
| 1050 |     scalarFromQt<UA_LocalizedText, QOpcUaLocalizedText>(value: value.description(), ptr: &ptr->description); | 
| 1051 |     scalarFromQt<UA_LocalizedText, QOpcUaLocalizedText>(value: value.displayName(), ptr: &ptr->displayName); | 
| 1052 |     ptr->value = value.value(); | 
| 1053 | } | 
| 1054 |  | 
| 1055 | template<> | 
| 1056 | void scalarFromQt<UA_EnumDefinition, QOpcUaEnumDefinition>(const QOpcUaEnumDefinition &value, UA_EnumDefinition *ptr) | 
| 1057 | { | 
| 1058 |     if (!value.fields().isEmpty()) { | 
| 1059 |         ptr->fieldsSize = value.fields().size(); | 
| 1060 |         ptr->fields = static_cast<UA_EnumField *>(UA_Array_new(size: ptr->fieldsSize, type: &UA_TYPES[UA_TYPES_ENUMFIELD])); | 
| 1061 |  | 
| 1062 |         for (int i = 0; i < value.fields().size(); ++i) | 
| 1063 |             scalarFromQt<UA_EnumField, QOpcUaEnumField>(value: value.fields().at(i), ptr: &ptr->fields[i]); | 
| 1064 |     } | 
| 1065 | } | 
| 1066 |  | 
| 1067 | template<> | 
| 1068 | void scalarFromQt<UA_DiagnosticInfo, QOpcUaDiagnosticInfo>(const QOpcUaDiagnosticInfo &value, UA_DiagnosticInfo *ptr) | 
| 1069 | { | 
| 1070 |     if (value.hasSymbolicId()) { | 
| 1071 |         ptr->hasSymbolicId = true; | 
| 1072 |         ptr->symbolicId = value.symbolicId(); | 
| 1073 |     } | 
| 1074 |  | 
| 1075 |     if (value.hasNamespaceUri()) { | 
| 1076 |         ptr->hasNamespaceUri = true; | 
| 1077 |         ptr->namespaceUri = value.namespaceUri(); | 
| 1078 |     } | 
| 1079 |  | 
| 1080 |     if (value.hasLocale()) { | 
| 1081 |         ptr->hasLocale = true; | 
| 1082 |         ptr->locale = value.locale(); | 
| 1083 |     } | 
| 1084 |  | 
| 1085 |     if (value.hasLocalizedText()) { | 
| 1086 |         ptr->hasLocalizedText = true; | 
| 1087 |         ptr->localizedText = value.localizedText(); | 
| 1088 |     } | 
| 1089 |  | 
| 1090 |     if (value.hasAdditionalInfo()) { | 
| 1091 |         ptr->hasAdditionalInfo = true; | 
| 1092 |         scalarFromQt<UA_String, QString>(value: value.additionalInfo(), ptr: &ptr->additionalInfo); | 
| 1093 |     } | 
| 1094 |  | 
| 1095 |     if (value.hasInnerStatusCode()) { | 
| 1096 |         ptr->hasInnerStatusCode = true; | 
| 1097 |         ptr->innerStatusCode = value.innerStatusCode(); | 
| 1098 |     } | 
| 1099 |  | 
| 1100 |     if (value.hasInnerDiagnosticInfo()) { | 
| 1101 |         ptr->hasInnerDiagnosticInfo = true; | 
| 1102 |         ptr->innerDiagnosticInfo = UA_DiagnosticInfo_new(); | 
| 1103 |         scalarFromQt<UA_DiagnosticInfo, QOpcUaDiagnosticInfo>(value: value.innerDiagnosticInfo(), ptr: ptr->innerDiagnosticInfo); | 
| 1104 |     } | 
| 1105 | } | 
| 1106 |  | 
| 1107 | template<> | 
| 1108 | void scalarFromQt<UA_ExtensionObject, QOpcUaExtensionObject>(const QOpcUaExtensionObject &obj, UA_ExtensionObject *ptr) | 
| 1109 | { | 
| 1110 |     QByteArray temp = obj.encodedBody(); | 
| 1111 |     UA_NodeId encodingId = Open62541Utils::nodeIdFromQString(name: obj.encodingTypeId()); | 
| 1112 |     UaDeleter<UA_NodeId> nodeIdDeleter(&encodingId, UA_NodeId_clear); | 
| 1113 |     createExtensionObject(data&: temp, typeEncodingId: encodingId, ptr, encoding: obj.encoding()); | 
| 1114 | } | 
| 1115 |  | 
| 1116 | template<> | 
| 1117 | void scalarFromQt<UA_ExpandedNodeId, QOpcUaExpandedNodeId>(const QOpcUaExpandedNodeId &value, UA_ExpandedNodeId *ptr) | 
| 1118 | { | 
| 1119 |     ptr->serverIndex = value.serverIndex(); | 
| 1120 |     scalarFromQt<UA_String, QString>(value: value.namespaceUri(), ptr: &ptr->namespaceUri); | 
| 1121 |     ptr->nodeId = Open62541Utils::nodeIdFromQString(name: value.nodeId()); | 
| 1122 | } | 
| 1123 |  | 
| 1124 | template<> | 
| 1125 | void scalarFromQt<UA_Argument, QOpcUaArgument>(const QOpcUaArgument &value, UA_Argument *ptr) | 
| 1126 | { | 
| 1127 |     ptr->valueRank = value.valueRank(); | 
| 1128 |     scalarFromQt<UA_LocalizedText, QOpcUaLocalizedText>(value: value.description(), ptr: &ptr->description); | 
| 1129 |     scalarFromQt<UA_String, QString>(value: value.name(), ptr: &ptr->name); | 
| 1130 |     ptr->dataType = Open62541Utils::nodeIdFromQString(name: value.dataTypeId()); | 
| 1131 |     ptr->arrayDimensionsSize = value.arrayDimensions().size(); | 
| 1132 |     UA_StatusCode res = UA_Array_copy(src: value.arrayDimensions().constData(), size: ptr->arrayDimensionsSize, | 
| 1133 |                   dst: reinterpret_cast<void **>(&ptr->arrayDimensions), type: &UA_TYPES[UA_TYPES_UINT32]); | 
| 1134 |     if (res != UA_STATUSCODE_GOOD) | 
| 1135 |         ptr->arrayDimensionsSize = 0; | 
| 1136 | } | 
| 1137 |  | 
| 1138 | template<> | 
| 1139 | void scalarFromQt<UA_SimpleAttributeOperand, QOpcUaSimpleAttributeOperand>(const QOpcUaSimpleAttributeOperand &value, UA_SimpleAttributeOperand *ptr) | 
| 1140 | { | 
| 1141 |     ptr->attributeId = toUaAttributeId(attr: value.attributeId()); | 
| 1142 |     if (!value.indexRange().isEmpty()) | 
| 1143 |         scalarFromQt<UA_String, QString>(value: value.indexRange(), ptr: &ptr->indexRange); | 
| 1144 |     scalarFromQt<UA_NodeId, QString>(value: value.typeId(), ptr: &ptr->typeDefinitionId); | 
| 1145 |     ptr->browsePathSize = value.browsePath().size(); | 
| 1146 |     if (!value.browsePath().isEmpty()) { | 
| 1147 |         ptr->browsePath = static_cast<UA_QualifiedName *>(UA_Array_new(size: value.browsePath().size(), type: &UA_TYPES[UA_TYPES_QUALIFIEDNAME])); | 
| 1148 |         for (size_t i = 0; i < ptr->browsePathSize; ++i) | 
| 1149 |             scalarFromQt<UA_QualifiedName, QOpcUaQualifiedName>(value: value.browsePath().at(i), ptr: &ptr->browsePath[i]); | 
| 1150 |     } | 
| 1151 | } | 
| 1152 |  | 
| 1153 | template<> | 
| 1154 | void scalarFromQt<UA_LiteralOperand, QOpcUaLiteralOperand>(const QOpcUaLiteralOperand &value, UA_LiteralOperand *ptr) | 
| 1155 | { | 
| 1156 |     ptr->value = toOpen62541Variant(value: value.value(), type: value.type()); | 
| 1157 | } | 
| 1158 |  | 
| 1159 | template<> | 
| 1160 | void scalarFromQt<UA_ElementOperand, QOpcUaElementOperand>(const QOpcUaElementOperand &value, UA_ElementOperand *ptr) | 
| 1161 | { | 
| 1162 |     ptr->index = value.index(); | 
| 1163 | } | 
| 1164 |  | 
| 1165 | template<> | 
| 1166 | void scalarFromQt<UA_RelativePathElement, QOpcUaRelativePathElement>(const QOpcUaRelativePathElement &value, UA_RelativePathElement *ptr) | 
| 1167 | { | 
| 1168 |     ptr->includeSubtypes = value.includeSubtypes(); | 
| 1169 |     ptr->isInverse = value.isInverse(); | 
| 1170 |     scalarFromQt<UA_NodeId, QString>(value: value.referenceTypeId(), ptr: &ptr->referenceTypeId); | 
| 1171 |     scalarFromQt<UA_QualifiedName, QOpcUaQualifiedName>(value: value.targetName(), ptr: &ptr->targetName); | 
| 1172 | } | 
| 1173 |  | 
| 1174 | template<> | 
| 1175 | void scalarFromQt<UA_AttributeOperand, QOpcUaAttributeOperand>(const QOpcUaAttributeOperand &value, UA_AttributeOperand *ptr) | 
| 1176 | { | 
| 1177 |     ptr->attributeId = toUaAttributeId(attr: value.attributeId()); | 
| 1178 |     scalarFromQt<UA_String, QString>(value: value.alias(), ptr: &ptr->alias); | 
| 1179 |     if (!value.indexRange().isEmpty()) | 
| 1180 |         scalarFromQt<UA_String, QString>(value: value.indexRange(), ptr: &ptr->indexRange); | 
| 1181 |     scalarFromQt<UA_NodeId, QString>(value: value.nodeId(), ptr: &ptr->nodeId); | 
| 1182 |     ptr->browsePath.elementsSize = value.browsePath().size(); | 
| 1183 |     if (ptr->browsePath.elementsSize) { | 
| 1184 |         ptr->browsePath.elements = static_cast<UA_RelativePathElement *>(UA_Array_new(size: ptr->browsePath.elementsSize, | 
| 1185 |                                                                                       type: &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT])); | 
| 1186 |         for (size_t i = 0; i < ptr->browsePath.elementsSize; ++i) | 
| 1187 |             scalarFromQt<UA_RelativePathElement, QOpcUaRelativePathElement>(value: value.browsePath().at(i), | 
| 1188 |                                                                             ptr: &ptr->browsePath.elements[i]); | 
| 1189 |     } | 
| 1190 | } | 
| 1191 |  | 
| 1192 | template<> | 
| 1193 | void scalarFromQt<UA_ContentFilterElement, QOpcUaContentFilterElement>(const QOpcUaContentFilterElement &value, UA_ContentFilterElement *ptr) | 
| 1194 | { | 
| 1195 |     ptr->filterOperator = static_cast<UA_FilterOperator>(value.filterOperator()); | 
| 1196 |     ptr->filterOperandsSize = value.filterOperands().size(); | 
| 1197 |     if (ptr->filterOperandsSize) { | 
| 1198 |         ptr->filterOperands = static_cast<UA_ExtensionObject *>(UA_Array_new(size: ptr->filterOperandsSize, type: &UA_TYPES[UA_TYPES_EXTENSIONOBJECT])); | 
| 1199 |  | 
| 1200 |         for (size_t i = 0; i < ptr->filterOperandsSize; ++i) { | 
| 1201 |             if (value.filterOperands().at(i).canConvert<QOpcUaElementOperand>()) { | 
| 1202 |                 const auto operand = UA_ElementOperand_new(); | 
| 1203 |                 scalarFromQt<UA_ElementOperand, QOpcUaElementOperand>(value: value.filterOperands().at(i).value<QOpcUaElementOperand>(), ptr: operand); | 
| 1204 |                 ptr->filterOperands[i].encoding = UA_EXTENSIONOBJECT_DECODED; | 
| 1205 |                 ptr->filterOperands[i].content.decoded.data = operand; | 
| 1206 |                 ptr->filterOperands[i].content.decoded.type = &UA_TYPES[UA_TYPES_ELEMENTOPERAND]; | 
| 1207 |             } else if (value.filterOperands().at(i).canConvert<QOpcUaLiteralOperand>()) { | 
| 1208 |                 const auto operand = UA_LiteralOperand_new(); | 
| 1209 |                 scalarFromQt<UA_LiteralOperand, QOpcUaLiteralOperand>(value: value.filterOperands().at(i).value<QOpcUaLiteralOperand>(), ptr: operand); | 
| 1210 |                 ptr->filterOperands[i].encoding = UA_EXTENSIONOBJECT_DECODED; | 
| 1211 |                 ptr->filterOperands[i].content.decoded.data = operand; | 
| 1212 |                 ptr->filterOperands[i].content.decoded.type = &UA_TYPES[UA_TYPES_LITERALOPERAND]; | 
| 1213 |             } else if (value.filterOperands().at(i).canConvert<QOpcUaAttributeOperand>()) { | 
| 1214 |                 const auto operand = UA_AttributeOperand_new(); | 
| 1215 |                 scalarFromQt<UA_AttributeOperand, QOpcUaAttributeOperand>(value: value.filterOperands().at(i).value<QOpcUaAttributeOperand>(), ptr: operand); | 
| 1216 |                 ptr->filterOperands[i].encoding = UA_EXTENSIONOBJECT_DECODED; | 
| 1217 |                 ptr->filterOperands[i].content.decoded.data = operand; | 
| 1218 |                 ptr->filterOperands[i].content.decoded.type = &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]; | 
| 1219 |             } else if (value.filterOperands().at(i).canConvert<QOpcUaSimpleAttributeOperand>()) { | 
| 1220 |                 const auto operand = UA_SimpleAttributeOperand_new(); | 
| 1221 |                 scalarFromQt<UA_SimpleAttributeOperand, QOpcUaSimpleAttributeOperand>(value: value.filterOperands().at(i).value<QOpcUaSimpleAttributeOperand>(), ptr: operand); | 
| 1222 |                 ptr->filterOperands[i].encoding = UA_EXTENSIONOBJECT_DECODED; | 
| 1223 |                 ptr->filterOperands[i].content.decoded.data = operand; | 
| 1224 |                 ptr->filterOperands[i].content.decoded.type = &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]; | 
| 1225 |             } else { | 
| 1226 |                 qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Unsupported operand type in content filter element, unable to convert" ; | 
| 1227 |                 UA_ContentFilterElement_clear(p: ptr); | 
| 1228 |                 return; | 
| 1229 |             } | 
| 1230 |         } | 
| 1231 |     } | 
| 1232 | } | 
| 1233 |  | 
| 1234 | template<> | 
| 1235 | void scalarFromQt<UA_EventFilter, QOpcUaMonitoringParameters::EventFilter>(const QOpcUaMonitoringParameters::EventFilter &value, UA_EventFilter *ptr) | 
| 1236 | { | 
| 1237 |     ptr->selectClausesSize = value.selectClauses().size(); | 
| 1238 |     if (ptr->selectClausesSize) { | 
| 1239 |         ptr->selectClauses = static_cast<UA_SimpleAttributeOperand *>( | 
| 1240 |             UA_Array_new(size: ptr->selectClausesSize, type: &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND])); | 
| 1241 |  | 
| 1242 |         for (size_t i = 0; i < ptr->selectClausesSize; ++i) | 
| 1243 |             scalarFromQt<UA_SimpleAttributeOperand, QOpcUaSimpleAttributeOperand>(value: value.selectClauses().at(i), | 
| 1244 |                                                                                   ptr: &ptr->selectClauses[i]); | 
| 1245 |     } | 
| 1246 |  | 
| 1247 |     ptr->whereClause.elementsSize = value.whereClause().size(); | 
| 1248 |     if (ptr->whereClause.elementsSize) { | 
| 1249 |         ptr->whereClause.elements = static_cast<UA_ContentFilterElement *>( | 
| 1250 |             UA_Array_new(size: ptr->whereClause.elementsSize, type: &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT])); | 
| 1251 |  | 
| 1252 |         for (size_t i = 0; i < ptr->whereClause.elementsSize; ++i) | 
| 1253 |             scalarFromQt<UA_ContentFilterElement, QOpcUaContentFilterElement>(value: value.whereClause().at(i), | 
| 1254 |                                                                               ptr: &ptr->whereClause.elements[i]); | 
| 1255 |     } | 
| 1256 | } | 
| 1257 |  | 
| 1258 | template<typename TARGETTYPE, typename QTTYPE> | 
| 1259 | UA_Variant arrayFromQVariant(const QVariant &var, const UA_DataType *type) | 
| 1260 | { | 
| 1261 |     UA_Variant open62541value; | 
| 1262 |     UA_Variant_init(p: &open62541value); | 
| 1263 |  | 
| 1264 |     if (type == nullptr) { | 
| 1265 |         qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Unable to convert QVariant to UA_Variant, unknown type" ; | 
| 1266 |         return open62541value; | 
| 1267 |     } | 
| 1268 |  | 
| 1269 |     if (var.metaType().id() == QMetaType::QVariantList) { | 
| 1270 |         const QVariantList list = var.toList(); | 
| 1271 |         if (list.isEmpty()) | 
| 1272 |             return open62541value; | 
| 1273 |  | 
| 1274 |         for (const auto &it : std::as_const(t: list)) { | 
| 1275 |             if (!it.canConvert<QTTYPE>()) { | 
| 1276 |                 qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Value type"  << var.typeName() << | 
| 1277 |                                                          "in the QVariant does not match type parameter"  << type->typeName; | 
| 1278 |                 return open62541value; | 
| 1279 |             } | 
| 1280 |         } | 
| 1281 |  | 
| 1282 |         TARGETTYPE *arr = static_cast<TARGETTYPE *>(UA_Array_new(size: list.size(), type)); | 
| 1283 |  | 
| 1284 |         for (int i = 0; i < list.size(); ++i) | 
| 1285 |             scalarFromQt<TARGETTYPE, QTTYPE>(list[i].value<QTTYPE>(), &arr[i]); | 
| 1286 |  | 
| 1287 |         UA_Variant_setArray(&open62541value, arr, list.size(), type); | 
| 1288 |         return open62541value; | 
| 1289 |     } | 
| 1290 |  | 
| 1291 |     if (!var.canConvert<QTTYPE>()) { | 
| 1292 |         qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Value type"  << var.typeName() << | 
| 1293 |                                                  "in the QVariant does not match type parameter"  << type->typeName; | 
| 1294 |         return open62541value; | 
| 1295 |     } | 
| 1296 |  | 
| 1297 |     TARGETTYPE *temp = static_cast<TARGETTYPE *>(UA_new(type)); | 
| 1298 |     scalarFromQt<TARGETTYPE, QTTYPE>(var.value<QTTYPE>(), temp); | 
| 1299 |     UA_Variant_setScalar(&open62541value, temp, type); | 
| 1300 |     return open62541value; | 
| 1301 | } | 
| 1302 |  | 
| 1303 | void createExtensionObject(QByteArray &data, const UA_NodeId &typeEncodingId, UA_ExtensionObject *ptr, QOpcUaExtensionObject::Encoding encoding) | 
| 1304 | { | 
| 1305 |     UA_ExtensionObject obj; | 
| 1306 |     UA_ExtensionObject_init(p: &obj); | 
| 1307 |  | 
| 1308 |     if (!data.isEmpty() && encoding == QOpcUaExtensionObject::Encoding::NoBody) | 
| 1309 |         qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Data for extension object provided but will not be encoded because encoding format is set to skip the body" ; | 
| 1310 |  | 
| 1311 |     if (encoding != QOpcUaExtensionObject::Encoding::NoBody) { | 
| 1312 |         obj.encoding = static_cast<UA_ExtensionObjectEncoding>(encoding); | 
| 1313 |         obj.content.encoded.body.data = reinterpret_cast<UA_Byte *>(data.data()); | 
| 1314 |         obj.content.encoded.body.length = data.size(); | 
| 1315 |     } | 
| 1316 |     obj.content.encoded.typeId = typeEncodingId; | 
| 1317 |     UA_ExtensionObject_copy(src: &obj, dst: ptr); | 
| 1318 | } | 
| 1319 |  | 
| 1320 | QVariant uaVariantToQtExtensionObject(const UA_Variant &var) | 
| 1321 | { | 
| 1322 |     if (UA_Variant_isScalar(v: &var)) { | 
| 1323 |         bool success = false; | 
| 1324 |         const auto result = encodeAsBinaryExtensionObject(data: var.data, type: var.type, success: &success); | 
| 1325 |         if (success) | 
| 1326 |             return result; | 
| 1327 |  | 
| 1328 |         qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to re-encode decoded extension object, unable to convert"  << var.type->typeName; | 
| 1329 |         return {}; | 
| 1330 |     } else if (var.arrayLength == 0 && var.data == UA_EMPTY_ARRAY_SENTINEL) { | 
| 1331 |         return QVariantList(); // Return empty QVariantList for empty array | 
| 1332 |     } | 
| 1333 |  | 
| 1334 |     // The array case is not handled here because open62541 always decodes arrays of types | 
| 1335 |     // we need to re-encode to extension objects which are handled by a different code path. | 
| 1336 |     // If this behavior should change with an update to open62541, it will be indicated by | 
| 1337 |     // a failing test (Tst_QOpcUaClient::readReencodedExtensionObject). | 
| 1338 |     return QVariant(); | 
| 1339 | } | 
| 1340 |  | 
| 1341 | QOpcUaExtensionObject encodeAsBinaryExtensionObject(const void *data, const UA_DataType *type, bool *success) | 
| 1342 | { | 
| 1343 |     if (!data || !type) { | 
| 1344 |         if (success) | 
| 1345 |             *success = false; | 
| 1346 |         return {}; | 
| 1347 |     } | 
| 1348 |  | 
| 1349 |     UA_ByteString encodedData; | 
| 1350 |     UA_ByteString_init(p: &encodedData); | 
| 1351 |     const auto encodeResult = UA_encodeBinary(p: data, type, outBuf: &encodedData); | 
| 1352 |  | 
| 1353 |     if (encodeResult != UA_STATUSCODE_GOOD) { | 
| 1354 |         if (success) | 
| 1355 |             *success = false; | 
| 1356 |  | 
| 1357 |         return {}; | 
| 1358 |     } | 
| 1359 |  | 
| 1360 |     QOpcUaExtensionObject result; | 
| 1361 |     result.setBinaryEncodedBody(encodedBody: scalarToQt<QByteArray, UA_ByteString>(data: &encodedData), typeId: scalarToQt<QString, UA_NodeId>(data: &type->typeId)); | 
| 1362 |     UA_ByteString_clear(p: &encodedData); | 
| 1363 |     result.setEncodingTypeId(scalarToQt<QString, UA_NodeId>(data: &type->binaryEncodingId)); | 
| 1364 |  | 
| 1365 |     if (success) | 
| 1366 |         *success = true; | 
| 1367 |  | 
| 1368 |     return result; | 
| 1369 | } | 
| 1370 |  | 
| 1371 | QOpcUa::Types toQtDataType(const UA_DataType *type) | 
| 1372 | { | 
| 1373 |     if (type == &UA_TYPES[UA_TYPES_BOOLEAN]) | 
| 1374 |         return QOpcUa::Types::Boolean; | 
| 1375 |     if (type == &UA_TYPES[UA_TYPES_INT32]) | 
| 1376 |         return QOpcUa::Types::Int32; | 
| 1377 |     if (type == &UA_TYPES[UA_TYPES_UINT32]) | 
| 1378 |         return QOpcUa::Types::UInt32; | 
| 1379 |     if (type == &UA_TYPES[UA_TYPES_DOUBLE]) | 
| 1380 |         return QOpcUa::Types::Double; | 
| 1381 |     if (type == &UA_TYPES[UA_TYPES_FLOAT]) | 
| 1382 |         return QOpcUa::Types::Float; | 
| 1383 |     if (type == &UA_TYPES[UA_TYPES_STRING]) | 
| 1384 |         return QOpcUa::Types::String; | 
| 1385 |     if (type == &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]) | 
| 1386 |         return QOpcUa::Types::LocalizedText; | 
| 1387 |     if (type == &UA_TYPES[UA_TYPES_DATETIME]) | 
| 1388 |         return QOpcUa::Types::DateTime; | 
| 1389 |     if (type == &UA_TYPES[UA_TYPES_UINT16]) | 
| 1390 |         return QOpcUa::Types::UInt16; | 
| 1391 |     if (type == &UA_TYPES[UA_TYPES_INT16]) | 
| 1392 |         return QOpcUa::Types::Int16; | 
| 1393 |     if (type == &UA_TYPES[UA_TYPES_UINT64]) | 
| 1394 |         return QOpcUa::Types::UInt64; | 
| 1395 |     if (type == &UA_TYPES[UA_TYPES_INT64]) | 
| 1396 |         return QOpcUa::Types::Int64; | 
| 1397 |     if (type == &UA_TYPES[UA_TYPES_BYTE]) | 
| 1398 |         return QOpcUa::Types::Byte; | 
| 1399 |     if (type == &UA_TYPES[UA_TYPES_SBYTE]) | 
| 1400 |         return QOpcUa::Types::SByte; | 
| 1401 |     if (type == &UA_TYPES[UA_TYPES_BYTESTRING]) | 
| 1402 |         return QOpcUa::Types::ByteString; | 
| 1403 |     if (type == &UA_TYPES[UA_TYPES_XMLELEMENT]) | 
| 1404 |         return QOpcUa::Types::XmlElement; | 
| 1405 |     if (type == &UA_TYPES[UA_TYPES_NODEID]) | 
| 1406 |         return QOpcUa::Types::NodeId; | 
| 1407 |     if (type == &UA_TYPES[UA_TYPES_GUID]) | 
| 1408 |         return QOpcUa::Types::Guid; | 
| 1409 |     if (type == &UA_TYPES[UA_TYPES_QUALIFIEDNAME]) | 
| 1410 |         return QOpcUa::Types::QualifiedName; | 
| 1411 |     if (type == &UA_TYPES[UA_TYPES_STATUSCODE]) | 
| 1412 |         return QOpcUa::Types::StatusCode; | 
| 1413 |     if (type == &UA_TYPES[UA_TYPES_RANGE]) | 
| 1414 |         return QOpcUa::Types::Range; | 
| 1415 |     if (type == &UA_TYPES[UA_TYPES_EUINFORMATION]) | 
| 1416 |         return QOpcUa::Types::EUInformation; | 
| 1417 |     if (type == &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]) | 
| 1418 |         return QOpcUa::Types::ComplexNumber; | 
| 1419 |     if (type == &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]) | 
| 1420 |         return QOpcUa::Types::DoubleComplexNumber; | 
| 1421 |     if (type == &UA_TYPES[UA_TYPES_AXISINFORMATION]) | 
| 1422 |         return QOpcUa::Types::AxisInformation; | 
| 1423 |     if (type == &UA_TYPES[UA_TYPES_XVTYPE]) | 
| 1424 |         return QOpcUa::Types::XV; | 
| 1425 |     if (type == &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]) | 
| 1426 |         return QOpcUa::Types::ExtensionObject; | 
| 1427 |     if (type == &UA_TYPES[UA_TYPES_EXPANDEDNODEID]) | 
| 1428 |         return QOpcUa::Types::ExpandedNodeId; | 
| 1429 |     if (type == &UA_TYPES[UA_TYPES_ARGUMENT]) | 
| 1430 |         return QOpcUa::Types::Argument; | 
| 1431 |     if (type == &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]) | 
| 1432 |         return QOpcUa::Types::StructureDefinition; | 
| 1433 |     if (type == &UA_TYPES[UA_TYPES_STRUCTUREFIELD]) | 
| 1434 |         return QOpcUa::Types::StructureField; | 
| 1435 |     if (type == &UA_TYPES[UA_TYPES_ENUMDEFINITION]) | 
| 1436 |         return QOpcUa::Types::EnumDefinition; | 
| 1437 |     if (type == &UA_TYPES[UA_TYPES_ENUMFIELD]) | 
| 1438 |         return QOpcUa::Types::EnumField; | 
| 1439 |     if (type == &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]) | 
| 1440 |         return QOpcUa::Types::DiagnosticInfo; | 
| 1441 |     if (type == &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]) | 
| 1442 |         return QOpcUa::Types::SimpleAttributeOperand; | 
| 1443 |     if (type == &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]) | 
| 1444 |         return QOpcUa::Types::AttributeOperand; | 
| 1445 |     if (type == &UA_TYPES[UA_TYPES_LITERALOPERAND]) | 
| 1446 |         return QOpcUa::Types::LiteralOperand; | 
| 1447 |     if (type == &UA_TYPES[UA_TYPES_ELEMENTOPERAND]) | 
| 1448 |         return QOpcUa::Types::ElementOperand; | 
| 1449 |     if (type == &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]) | 
| 1450 |         return QOpcUa::Types::RelativePathElement; | 
| 1451 |     if (type == &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]) | 
| 1452 |         return QOpcUa::Types::ContentFilterElement; | 
| 1453 |     if (type == &UA_TYPES[UA_TYPES_EVENTFILTER]) | 
| 1454 |         return QOpcUa::Types::EventFilter; | 
| 1455 |  | 
| 1456 |     qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Trying to convert unhandled type:"  << (type ? type->typeName : "Unknown" ); | 
| 1457 |     return QOpcUa::Types::Undefined; | 
| 1458 | } | 
| 1459 | } | 
| 1460 |  | 
| 1461 | QT_END_NAMESPACE | 
| 1462 |  |