1// Copyright (C) 2023 basysKom GmbH, opensource@basyskom.com
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 <QtOpcUa/qopcuastructuredefinition.h>
5#include <QtOpcUa/qopcuagenericstructvalue.h>
6
7#include <QtCore/qdebug.h>
8#include <QtCore/qhash.h>
9#include <QtCore/qstring.h>
10#include <QtCore/qvariant.h>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \class QOpcUaGenericStructValue
16 \inmodule QtOpcUa
17 \since 6.7
18
19 \brief Holds the value of a generic OPC UA structured type.
20
21 This class holds a generic OPC UA struct value which consists of named fields with their values
22 which can be built-in types or their sub types as well as other nested generic structs.
23 Some meta information like the type ID and the structure definition of the type contained in
24 an object of this class is also included.
25
26 It is used as return type for the decoding result and as input type for the encoding method of
27 \l QOpcUaGenericStructHandler.
28
29 For a struct with optional fields, only the fields that were specified are contained in the
30 \a fields() list. To omit an optional field during encoding, it must not appear in the fields()
31 list.
32 For structs derived from the Union type, only one of the fields must be specified.
33 The only entry in the fields() list of a decoded type determines which field (if any) of the
34 type definition was specified.
35
36 Example:
37 \code
38 // Decode an extension object
39 QOpcUaGenericStructValue value = decoder.decode(extensionObject, success);
40
41 // Print the value of a mandatory field
42 qDebug() << value.fields().value("MyField").value<QOpcUaLocalizedText>();
43
44 // Print the value of an optional field
45 if (value.fields().contains("MyOptionalField"))
46 qDebug() << value.fields().value("MyField").value<QOpcUaQualifiedName>();
47
48 // Get a nested struct for a field
49 const auto unionMember = value.fields().value("MyUnionMember").value<QOpcUaGenericStructValue>();
50
51 // Print the specified field
52 if (unionMember.fields().contains("UnionMember1"))
53 qDebug() << unionMember.fields().value("UnionMember1").toInt();
54 else if (unionMember.fields().contains("UnionMember2"))
55 qDebug() << unionMember.fields().value("UnionMember2").toDouble();
56 else
57 qDebug() << "Empty union";
58 \endcode
59*/
60
61class QOpcUaGenericStructValueData : public QSharedData
62{
63public:
64 QOpcUaGenericStructValueData() = default;
65 QOpcUaGenericStructValueData(const QString &typeName, const QString &typeId,
66 const QOpcUaStructureDefinition &definition, const QHash<QString, QVariant> &fields)
67 : typeName(typeName)
68 , typeId(typeId)
69 , structureDefinition(definition)
70 , fields(fields)
71 {}
72 QString typeName;
73 QString typeId;
74 QOpcUaStructureDefinition structureDefinition;
75 QHash<QString, QVariant> fields;
76};
77
78QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QOpcUaGenericStructValueData)
79
80/*!
81 Constructs a generic struct value.
82*/
83QOpcUaGenericStructValue::QOpcUaGenericStructValue()
84 : data(new QOpcUaGenericStructValueData())
85{
86}
87
88/*!
89 Destroys this generic struct value object.
90*/
91QOpcUaGenericStructValue::~QOpcUaGenericStructValue()
92{
93}
94
95/*!
96 Constructs a generic struct value from \a typeName, \a typeId and \a definition.
97*/
98QOpcUaGenericStructValue::QOpcUaGenericStructValue(const QString &typeName, const QString &typeId,
99 const QOpcUaStructureDefinition &definition)
100 : data(new QOpcUaGenericStructValueData(typeName, typeId, definition, {}))
101{
102}
103
104/*!
105 Constructs a generic struct value from \a typeName, \a typeId, \a definition and \a fields.
106*/
107QOpcUaGenericStructValue::QOpcUaGenericStructValue(const QString &typeName, const QString &typeId,
108 const QOpcUaStructureDefinition &definition, const QHash<QString, QVariant> &fields)
109 : data(new QOpcUaGenericStructValueData(typeName, typeId, definition, fields))
110{
111}
112
113/*!
114 Constructs a generic struct value from \a other.
115*/
116QOpcUaGenericStructValue::QOpcUaGenericStructValue(const QOpcUaGenericStructValue &other)
117 : data(other.data)
118{
119}
120
121/*!
122 Sets the value of \a rhs in this generic struct value.
123*/
124QOpcUaGenericStructValue &QOpcUaGenericStructValue::operator=(const QOpcUaGenericStructValue &rhs)
125{
126 if (this != &rhs)
127 this->data = rhs.data;
128
129 return *this;
130}
131
132/*!
133 \fn QOpcUaGenericStructValue::QOpcUaGenericStructValue(QOpcUaGenericStructValue &&other)
134
135 Move-constructs a new generic struct value from \a other.
136
137 \note The moved-from object \a other is placed in a
138 partially-formed state, in which the only valid operations are
139 destruction and assignment of a new value.
140*/
141
142/*!
143 \fn QOpcUaGenericStructValue &QOpcUaGenericStructValue::operator=(QOpcUaGenericStructValue &&other)
144
145 Move-assigns \a other to this QOpcUaGenericStructValue instance.
146
147 \note The moved-from object \a other is placed in a
148 partially-formed state, in which the only valid operations are
149 destruction and assignment of a new value.
150*/
151
152/*!
153 \fn void QOpcUaGenericStructValue::swap(QOpcUaGenericStructValue &other)
154
155 Swaps generic struct value object \a other with this generic struct value
156 object. This operation is very fast and never fails.
157*/
158
159/*!
160 \fn bool QOpcUaGenericStructValue::operator!=(const QOpcUaGenericStructValue &lhs, const QOpcUaGenericStructValue &rhs)
161
162 Returns \c true if \a lhs is not equal to \a rhs.
163*/
164
165/*!
166 \fn bool QOpcUaGenericStructValue::operator==(const QOpcUaGenericStructValue &lhs, const QOpcUaGenericStructValue &rhs)
167
168 Returns \c true if \a lhs is equal to \a rhs.
169*/
170bool comparesEqual(const QOpcUaGenericStructValue &lhs, const QOpcUaGenericStructValue &rhs) noexcept
171{
172 return lhs.typeName() == rhs.typeName() && lhs.typeId() == rhs.typeId() &&
173 lhs.structureDefinition() == rhs.structureDefinition() && lhs.fields() == rhs.fields();
174}
175
176/*!
177 Returns a \l QVariant containing this generic struct value.
178*/
179QOpcUaGenericStructValue::operator QVariant() const
180{
181 return QVariant::fromValue(value: *this);
182}
183
184/*!
185 Returns the type name for this generic struct value.
186*/
187QString QOpcUaGenericStructValue::typeName() const
188{
189 return data->typeName;
190}
191
192/*!
193 Sets the type name for this generic struct value to \a typeName.
194*/
195void QOpcUaGenericStructValue::setTypeName(const QString &typeName)
196{
197 if (typeName != data->typeName) {
198 data.detach();
199 data->typeName = typeName;
200 }
201}
202
203/*!
204 Returns the type node id for this generic struct value.
205*/
206QString QOpcUaGenericStructValue::typeId() const
207{
208 return data->typeId;
209}
210
211/*!
212 Sets the type node id for this generic struct value to \a typeId.
213*/
214void QOpcUaGenericStructValue::setTypeId(const QString &typeId)
215{
216 if (typeId != data->typeId) {
217 data.detach();
218 data->typeId = typeId;
219 }
220}
221
222/*!
223 Returns the structure definition for this generic struct value.
224*/
225QOpcUaStructureDefinition QOpcUaGenericStructValue::structureDefinition() const
226{
227 return data->structureDefinition;
228}
229
230/*!
231 Sets the structure definition for this generic struct value to \a structureDefinition.
232*/
233void QOpcUaGenericStructValue::setStructureDefinition(const QOpcUaStructureDefinition &structureDefinition)
234{
235 if (structureDefinition != data->structureDefinition) {
236 data.detach();
237 data->structureDefinition = structureDefinition;
238 }
239}
240
241/*!
242 Returns the fields of this generic struct value.
243*/
244QHash<QString, QVariant> QOpcUaGenericStructValue::fields() const
245{
246 return data->fields;
247}
248
249/*!
250 Returns a reference to the fields of this generic struct value.
251*/
252QHash<QString, QVariant> &QOpcUaGenericStructValue::fieldsRef()
253{
254 return data->fields;
255}
256
257/*!
258 Sets the fields of this generic struct value to \a fields.
259*/
260void QOpcUaGenericStructValue::setFields(const QHash<QString, QVariant> &fields)
261{
262 if (fields != data->fields) {
263 data.detach();
264 data->fields = fields;
265 }
266}
267
268#ifndef QT_NO_DEBUG_STREAM
269/*!
270 Returns a string representation for this generic struct value.
271 */
272QString QOpcUaGenericStructValue::toString() const
273{
274 QString out;
275 QDebug dbg(&out);
276 dbg.nospace().noquote() << *this;
277 return out;
278}
279
280/*!
281 \fn QDebug QOpcUaGenericStructValue::operator<<(QDebug debug, const QOpcUaGenericStructValue &s)
282 Outputs the string representation of \a s into \a debug.
283 */
284QDebug operator<<(QDebug debug, const QOpcUaGenericStructValue &s)
285{
286 QDebugStateSaver saver(debug);
287
288 QString structType = QStringLiteral("Struct");
289 if (s.structureDefinition().structureType() == QOpcUaStructureDefinition::StructureType::StructureWithOptionalFields)
290 structType = QStringLiteral("StructWithOptionalFields");
291 else if (s.structureDefinition().structureType() == QOpcUaStructureDefinition::StructureType::Union)
292 structType = QStringLiteral("Union");
293
294 debug.noquote().nospace();
295 debug << structType << " " << s.typeName() << " (";
296 for (auto it = s.data->fields.constBegin(); it != s.data->fields.constEnd(); ++it)
297 debug << (it == s.data->fields.constBegin() ? "" : " ") << it.key() << ": " << it.value();
298 debug << ")";
299 return debug;
300}
301#endif
302
303QT_END_NAMESPACE
304

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtopcua/src/opcua/client/qopcuagenericstructvalue.cpp