summaryrefslogtreecommitdiffstats
path: root/src/plugins/opcua/uacpp/quacpputils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/opcua/uacpp/quacpputils.cpp')
-rw-r--r--src/plugins/opcua/uacpp/quacpputils.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/plugins/opcua/uacpp/quacpputils.cpp b/src/plugins/opcua/uacpp/quacpputils.cpp
new file mode 100644
index 0000000..0b753d2
--- /dev/null
+++ b/src/plugins/opcua/uacpp/quacpputils.cpp
@@ -0,0 +1,170 @@
+/******************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtOpcUa module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "quacpputils.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/QUuid>
+
+#include <uaguid.h>
+#include <cstring>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA_PLUGINS_UACPP)
+
+namespace UACppUtils {
+
+UaNodeId nodeIdFromQString(const QString &name)
+{
+ const int semicolonIndex = name.indexOf(';');
+
+ if (semicolonIndex <= 0) {
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "Unable to split node id string: %s", qUtf8Printable(name));
+ return UaNodeId();
+ }
+
+ QStringRef namespaceString = name.leftRef(semicolonIndex);
+ if (namespaceString.length() <= 3 || !namespaceString.startsWith(QLatin1String("ns="))) {
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "Not a valid index string in node id string: %s", qUtf8Printable(name));
+ return UaNodeId();
+ }
+ namespaceString = namespaceString.mid(3); // Remove "ns="
+
+ QStringRef identifierString = name.midRef(semicolonIndex + 1);
+
+ if (identifierString.length() <= 2) {
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "There is no identifier in node id string: %s", qUtf8Printable(name));
+ return UaNodeId();
+ }
+
+ char identifierType;
+ if (identifierString.startsWith(QLatin1String("s=")))
+ identifierType = 's';
+ else if (identifierString.startsWith(QLatin1String("i=")))
+ identifierType = 'i';
+ else if (identifierString.startsWith(QLatin1String("g=")))
+ identifierType = 'g';
+ else if (identifierString.startsWith(QLatin1String("b=")))
+ identifierType = 'b';
+ else {
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "There is no valid identifier type in node id string: %s", qUtf8Printable(name));
+ return UaNodeId();
+ }
+ identifierString = identifierString.mid(2); // Remove identifier type
+
+ bool ok = false;
+ OpcUa_UInt16 index = static_cast<OpcUa_UInt16>(namespaceString.toUInt(&ok));
+
+ if (!ok) {
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "Not a valid namespace index in node id string: %s", qUtf8Printable(name));
+ return UaNodeId();
+ }
+
+ switch (identifierType) {
+ case 'i': {
+ bool isNumber;
+ OpcUa_UInt32 identifier = static_cast<OpcUa_UInt32>(identifierString.toUInt(&isNumber));
+ if (isNumber)
+ return UaNodeId(identifier, index);
+ else
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "%s does not contain a valid numeric identifier", qUtf8Printable(name));
+ break;
+ }
+ case 's': {
+ if (identifierString.length() > 0)
+ return UaNodeId(UaString(identifierString.toUtf8().constData()), index);
+ else
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "%s does not contain a valid string identifier", qUtf8Printable(name));
+ break;
+ }
+ case 'g': {
+ QUuid uuid(identifierString.toString());
+
+ if (uuid.isNull()) {
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "%s does not contain a valid guid identifier", qUtf8Printable(name));
+ }
+
+ OpcUa_Guid guid;
+ guid.Data1 = uuid.data1;
+ guid.Data2 = uuid.data2;
+ guid.Data3 = uuid.data3;
+ std::memcpy(guid.Data4, uuid.data4, sizeof(uuid.data4));
+ return UaNodeId(guid, index);
+ }
+ case 'b': {
+ QByteArray temp = QByteArray::fromBase64(identifierString.toLocal8Bit());
+ UaByteString bstr((OpcUa_Int32)temp.size(), reinterpret_cast<OpcUa_Byte *>(temp.data()));
+ if (temp.size() > 0) {
+ return UaNodeId(bstr, index);
+ }
+ else
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "%s does not contain a valid byte string identifier", qUtf8Printable(name));
+ break;
+ }
+ default:
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "Could not parse node id: %s", qUtf8Printable(name));
+ }
+ return UaNodeId();
+}
+
+// We only need this for template<> QVariant scalarToQVariant<QString, OpcUa_NodeId>(OpcUa_NodeId *data, QMetaType::Type type)
+// And also only because our unit tests assume that ns=0 has to be included in the string. Even though ns=0
+// can be assumed implicity
+QString nodeIdToQString(const UaNodeId &id)
+{
+ QString result = QString::fromLatin1("ns=%1;").arg(id.namespaceIndex());
+
+ switch (id.identifierType()) {
+ case OpcUa_IdentifierType_Numeric:
+ result.append(QString::fromLatin1("i=%1").arg(id.identifierNumeric()));
+ break;
+ case OpcUa_IdentifierType_String: {
+ result.append(QLatin1String("s="));
+ const UaString identifier(id.identifierString());
+ result.append(QString::fromUtf8(identifier.toUtf8(), identifier.size()));
+ break;
+ }
+ case OpcUa_IdentifierType_Guid: {
+ OpcUa_Guid *uaguid = (*id).Identifier.Guid;
+ const QUuid uuid(uaguid->Data1, uaguid->Data2, uaguid->Data3,
+ uaguid->Data4[0], uaguid->Data4[1], uaguid->Data4[2], uaguid->Data4[3],
+ uaguid->Data4[4], uaguid->Data4[5], uaguid->Data4[6], uaguid->Data4[7]);
+ result.append(QStringLiteral("g=")).append(uuid.toString().midRef(1, 36));
+ break;
+ }
+ case OpcUa_IdentifierType_Opaque: {
+ const OpcUa_ByteString &uabs = (*id).Identifier.ByteString;
+ const QByteArray temp(reinterpret_cast<char *>(uabs.Data), uabs.Length);
+ result.append(QStringLiteral("b=")).append(temp.toBase64());
+ break;
+ }
+ default:
+ qCWarning(QT_OPCUA_PLUGINS_UACPP, "UACpp Utils: Could not convert UA_NodeId to QString");
+ result.clear();
+ }
+ return result;
+}
+
+} // namespace UaCppUtils
+
+QT_END_NAMESPACE