1// Copyright (C) 2017 Lorenz Haas
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qmqtttopicname.h"
6
7#include <QtCore/QDebug>
8
9QT_BEGIN_NAMESPACE
10
11/*!
12 \class QMqttTopicName
13 \inmodule QtMqtt
14 \reentrant
15 \ingroup shared
16
17 \brief The QMqttTopicName class represents a MQTT topic name.
18
19 QMqttTopicName is a thin wrapper around a QString providing an expressive
20 data type for MQTT topic names. Beside the benefits of having a strong type
21 preventing unintended misuse, QMqttTopicName provides convenient functions
22 related to topic names like isValid() or levels().
23
24 \sa QMqttTopicFilter
25 */
26
27/*!
28 \fn void QMqttTopicName::swap(QMqttTopicName &other)
29 Swaps the MQTT topic name \a other with this MQTT topic name. This
30 operation is very fast and never fails.
31 */
32
33class QMqttTopicNamePrivate : public QSharedData
34{
35public:
36 QString name;
37};
38
39/*!
40 Creates a new MQTT topic name with the specified \a name.
41 */
42QMqttTopicName::QMqttTopicName(const QString &name) : d(new QMqttTopicNamePrivate)
43{
44 d->name = name;
45}
46
47/*!
48 Creates a new MQTT topic name with the specified \a name.
49 */
50QMqttTopicName::QMqttTopicName(const QLatin1String &name) : d(new QMqttTopicNamePrivate)
51{
52 d->name = name;
53}
54
55/*!
56 Creates a new MQTT topic name as a copy of \a name.
57 */
58QMqttTopicName::QMqttTopicName(const QMqttTopicName &name) : d(name.d)
59{
60}
61
62/*!
63 Destroys the QMqttTopicName object.
64 */
65QMqttTopicName::~QMqttTopicName()
66{
67}
68
69/*!
70 Assigns the MQTT topic name \a name to this object, and returns a reference
71 to the copy.
72 */
73QMqttTopicName &QMqttTopicName::operator=(const QMqttTopicName &name)
74{
75 d = name.d;
76 return *this;
77}
78
79/*!
80 Returns the topic name.
81 */
82QString QMqttTopicName::name() const
83{
84 return d->name;
85}
86
87/*!
88 Sets the topic name to \a name.
89 */
90void QMqttTopicName::setName(const QString &name)
91{
92 d.detach();
93 d->name = name;
94}
95
96/*!
97 Returns \c true if the topic name is valid according to the MQTT standard
98 section 4.7, or \c false otherwise.
99 */
100bool QMqttTopicName::isValid() const
101{
102 const int bytes = d->name.size();
103 return bytes > 0 // [MQTT-4.7.3-1]
104 && bytes < 65536 // [MQTT-4.7.3-3]
105 && !d->name.contains(c: QLatin1Char('#')) // [MQTT-4.7.1-1]
106 && !d->name.contains(c: QLatin1Char('+')) // [MQTT-4.7.1-1]
107 && !d->name.contains(c: QChar(QChar::Null)); // [MQTT-4.7.3-2]
108}
109
110/*!
111 Returns the total number of topic levels.
112 */
113int QMqttTopicName::levelCount() const
114{
115 return d->name.isEmpty() ? 0 : d->name.count(c: QLatin1Char('/')) + 1;
116}
117
118/*!
119 Returns the topic levels.
120 */
121QStringList QMqttTopicName::levels() const
122{
123 return d->name.split(sep: QLatin1Char('/'), behavior: Qt::KeepEmptyParts);
124}
125
126/*!
127 //! friend
128 \fn bool QMqttTopicName::operator==(const QMqttTopicName &lhs, const QMqttTopicName &rhs)
129
130 Returns \c true if the topic names \a lhs and \a rhs are equal,
131 otherwise returns \c false.
132 */
133bool operator==(const QMqttTopicName &lhs, const QMqttTopicName &rhs) Q_DECL_NOTHROW
134{
135 return (lhs.d == rhs.d) || (lhs.d->name == rhs.d->name);
136}
137
138/*!
139 //! friend
140 \fn bool QMqttTopicName::operator!=(const QMqttTopicName &lhs, const QMqttTopicName &rhs)
141
142 Returns \c true if the topic names \a lhs and \a rhs are different,
143 otherwise returns \c false.
144 */
145
146/*!
147 //! friend
148 \fn bool QMqttTopicName::operator<(const QMqttTopicName &lhs, const QMqttTopicName &rhs)
149
150 Returns \c true if the topic name \a lhs is lexically less than the topic
151 name \a rhs; otherwise returns \c false.
152 */
153bool operator<(const QMqttTopicName &lhs, const QMqttTopicName &rhs) Q_DECL_NOTHROW
154{
155 return lhs.d->name < rhs.d->name;
156}
157
158/*!
159 \relates QHash
160
161 Returns the hash value for \a name. If specified, \a seed is used to
162 initialize the hash.
163*/
164size_t qHash(const QMqttTopicName &name, size_t seed) Q_DECL_NOTHROW
165{
166 return qHash(key: name.d->name, seed);
167}
168
169#ifndef QT_NO_DATASTREAM
170/*! \relates QMqttTopicName
171
172 Writes the topic name \a name to the stream \a out and returns a reference
173 to the stream.
174
175 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
176*/
177QDataStream &operator<<(QDataStream &out, const QMqttTopicName &name)
178{
179 out << name.name();
180 return out;
181}
182
183/*! \relates QMqttTopicName
184
185 Reads a topic name into \a name from the stream \a in and returns a
186 reference to the stream.
187
188 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
189*/
190QDataStream &operator>>(QDataStream &in, QMqttTopicName &name)
191{
192 QString n;
193 in >> n;
194 name.setName(n);
195 return in;
196}
197#endif // QT_NO_DATASTREAM
198
199#ifndef QT_NO_DEBUG_STREAM
200QDebug operator<<(QDebug d, const QMqttTopicName &name)
201{
202 QDebugStateSaver saver(d);
203 d.nospace() << "QMqttTopicName(" << name.name() << ')';
204 return d;
205}
206#endif
207
208QT_END_NAMESPACE
209

source code of qtmqtt/src/mqtt/qmqtttopicname.cpp