/****************************************************************************** ** ** Copyright (C) 2017 Lorenz Haas ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtMqtt module. ** ** $QT_BEGIN_LICENSE:GPL$ ** 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 https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 or (at your option) any later version ** approved by the KDE Free Qt Foundation. The licenses are as published by ** the Free Software Foundation and appearing in the file LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ******************************************************************************/ #include "qmqtttopicname.h" #include QT_BEGIN_NAMESPACE /*! \class QMqttTopicName \inmodule QtMqtt \reentrant \ingroup shared \brief The QMqttTopicName class represents a MQTT topic name. QMqttTopicName is a thin wrapper around a QString providing an expressive data type for MQTT topic names. Beside the benefits of having a strong type preventing unintended misuse, QMqttTopicName provides convenient functions related to topic names like isValid() or levels(). \sa QMqttTopicFilter */ /*! \fn void QMqttTopicName::swap(QMqttTopicName &other) Swaps the MQTT topic name \a other with this MQTT topic name. This operation is very fast and never fails. */ class QMqttTopicNamePrivate : public QSharedData { public: QString name; }; /*! Creates a new MQTT topic name with the specified \a name. */ QMqttTopicName::QMqttTopicName(const QString &name) : d(new QMqttTopicNamePrivate) { d->name = name; } /*! Creates a new MQTT topic name with the specified \a name. */ QMqttTopicName::QMqttTopicName(const QLatin1String &name) : d(new QMqttTopicNamePrivate) { d->name = name; } /*! Creates a new MQTT topic name as a copy of \a name. */ QMqttTopicName::QMqttTopicName(const QMqttTopicName &name) : d(name.d) { } /*! Destroys the QMqttTopicName object. */ QMqttTopicName::~QMqttTopicName() { } /*! Assigns the MQTT topic name \a name to this object, and returns a reference to the copy. */ QMqttTopicName &QMqttTopicName::operator=(const QMqttTopicName &name) { d = name.d; return *this; } /*! Returns the topic name. */ QString QMqttTopicName::name() const { return d->name; } /*! Sets the topic name to \a name. */ void QMqttTopicName::setName(const QString &name) { d.detach(); d->name = name; } /*! Returns \c true if the topic name is valid according to the MQTT standard section 4.7, or \c false otherwise. */ bool QMqttTopicName::isValid() const { const int bytes = d->name.size(); return bytes > 0 // [MQTT-4.7.3-1] && bytes < 65536 // [MQTT-4.7.3-3] && !d->name.contains(QLatin1Char('#')) // [MQTT-4.7.1-1] && !d->name.contains(QLatin1Char('+')) // [MQTT-4.7.1-1] && !d->name.contains(QChar(QChar::Null)); // [MQTT-4.7.3-2] } /*! Returns the total number of topic levels. */ int QMqttTopicName::levelCount() const { return d->name.isEmpty() ? 0 : d->name.count(QLatin1Char('/')) + 1; } /*! Returns the topic levels. */ QStringList QMqttTopicName::levels() const { return d->name.split(QLatin1Char('/'), QString::KeepEmptyParts); } /*! \relates QMqttTopicName Returns \c true if the topic names \a lhs and \a rhs are equal, otherwise returns \c false. */ bool operator==(const QMqttTopicName &lhs, const QMqttTopicName &rhs) Q_DECL_NOTHROW { return (lhs.d == rhs.d) || (lhs.d->name == rhs.d->name); } /*! \fn bool operator!=(const QMqttTopicName &lhs, const QMqttTopicName &rhs) \relates QMqttTopicName Returns \c true if the topic names \a lhs and \a rhs are different, otherwise returns \c false. */ /*! \relates QMqttTopicName Returns \c true if the topic name \a lhs is lexically less than the topic name \a rhs; otherwise returns \c false. */ bool operator<(const QMqttTopicName &lhs, const QMqttTopicName &rhs) Q_DECL_NOTHROW { return lhs.d->name < rhs.d->name; } /*! \relates QHash Returns the hash value for \a name. If specified, \a seed is used to initialize the hash. */ uint qHash(const QMqttTopicName &name, uint seed) Q_DECL_NOTHROW { return qHash(name.d->name, seed); } #ifndef QT_NO_DATASTREAM /*! \relates QMqttTopicName Writes the topic name \a name to the stream \a out and returns a reference to the stream. \sa{Serializing Qt Data Types}{Format of the QDataStream operators} */ QDataStream &operator<<(QDataStream &out, const QMqttTopicName &name) { out << name.name(); return out; } /*! \relates QMqttTopicName Reads a topic name into \a name from the stream \a in and returns a reference to the stream. \sa{Serializing Qt Data Types}{Format of the QDataStream operators} */ QDataStream &operator>>(QDataStream &in, QMqttTopicName &name) { QString n; in >> n; name.setName(n); return in; } #endif // QT_NO_DATASTREAM #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QMqttTopicName &name) { QDebugStateSaver saver(d); d.nospace() << "QMqttTopicName(" << name.name() << ')'; return d; } #endif QT_END_NAMESPACE