/**************************************************************************** ** ** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** 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 Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or 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.GPL2 and 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-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qcbormap.h" #include "qcborvalue_p.h" QT_BEGIN_NAMESPACE using namespace QtCbor; /*! \class QCborMap \inmodule QtCore \ingroup cbor \reentrant \since 5.12 \brief The QCborMap class is used to hold an associative container representable in CBOR. This class can be used to hold an associative container in CBOR, a map between a key and a value type. CBOR is the Concise Binary Object Representation, a very compact form of binary data encoding that is a superset of JSON. It was created by the IETF Constrained RESTful Environments (CoRE) WG, which has used it in many new RFCs. It is meant to be used alongside the \l{https://tools.ietf.org/html/rfc7252}{CoAP protocol}. Unlike JSON and \l QVariantMap, CBOR map keys can be of any type, not just strings. For that reason, QCborMap is effectively a map between QCborValue keys to QCborValue value elements. However, for all member functions that take a key parameter, QCborMap provides overloads that will work efficiently with integers and strings. In fact, the use of integer keys is encouraged, since they occupy fewer bytes to transmit and are simpler to encode and decode. Newer protocols designed by the IETF CoRE WG to work specifically with CBOR are known to use them. QCborMap is not sorted, because of that, searching for keys has linear complexity (O(n)). QCborMap actually keeps the elements in the order that they were inserted, which means that it is possible to make sorted QCborMaps by carefully inserting elements in sorted order. CBOR does not require sorting, but recommends it. QCborMap can also be converted to and from QVariantMap and QJsonObject. However, when performing the conversion, any non-string keys will be stringified using a one-way method that the conversion back to QCborMap will not undo. \sa QCborArray, QCborValue, QJsonDocument, QVariantMap */ /*! \typedef QCborMap::value_type The value that is stored in this container: a pair of QCborValues */ /*! \typedef QCborMap::key_type The key type for this map. Since QCborMap keys can be any CBOR type, this is a QCborValue. */ /*! \typedef QCborMap::mapped_type The type that is mapped to (the value), that is, a QCborValue. */ /*! \typedef QCborMap::size_type The type that QCborMap uses for sizes. */ /*! \typedef QCborMap::iterator A synonym for QCborMap::Iterator. */ /*! \typedef QCborMap::const_iterator A synonym for QCborMap::ConstIterator */ /*! \fn QCborMap::iterator QCborMap::begin() Returns a map iterator pointing to the first key-value pair of this map. If this map is empty, the returned iterator will be the same as end(). \sa constBegin(), end() */ /*! \fn QCborMap::const_iterator QCborMap::constBegin() const Returns a map iterator pointing to the first key-value pair of this map. If this map is empty, the returned iterator will be the same as constEnd(). \sa begin(), constEnd() */ /*! \fn QCborMap::const_iterator QCborMap::begin() const Returns a map iterator pointing to the first key-value pair of this map. If this map is empty, the returned iterator will be the same as constEnd(). \sa begin(), constEnd() */ /*! \fn QCborMap::const_iterator QCborMap::cbegin() const Returns a map iterator pointing to the first key-value pair of this map. If this map is empty, the returned iterator will be the same as constEnd(). \sa begin(), constEnd() */ /*! \fn QCborMap::iterator QCborMap::end() Returns a map iterator representing an element just past the last element in the map. \sa begin(), constBegin(), find(), constFind() */ /*! \fn QCborMap::iterator QCborMap::constEnd() const Returns a map iterator representing an element just past the last element in the map. \sa begin(), constBegin(), find(), constFind() */ /*! \fn QCborMap::iterator QCborMap::end() const Returns a map iterator representing an element just past the last element in the map. \sa begin(), constBegin(), find(), constFind() */ /*! \fn QCborMap::iterator QCborMap::cend() const Returns a map iterator representing an element just past the last element in the map. \sa begin(), constBegin(), find(), constFind() */ /*! Constructs an empty CBOR Map object. \sa isEmpty() */ QCborMap::QCborMap() noexcept : d(nullptr) { } /*! Creates a QCborMap object that is a copy of \a other. */ QCborMap::QCborMap(const QCborMap &other) noexcept : d(other.d) { } /*! \fn QCborMap::QCborMap(std::initializer_list args) Constructs a QCborMap with items from a brace-initialization list found in \a args, as in the following example: \code QCborMap map = { {0, "Hello"}, {1, "World"}, {"foo", nullptr}, {"bar", QCborArray{0, 1, 2, 3, 4}} }; \endcode */ /*! Destroys this QCborMap object and frees any associated resources it owns. */ QCborMap::~QCborMap() { } /*! Replaces the contents of this object with a copy of \a other, then returns a reference to this object. */ QCborMap &QCborMap::operator=(const QCborMap &other) noexcept { d = other.d; return *this; } /*! \fn void QCborMap::swap(QCborMap &other) Swaps the contents of this map and \a other. */ /*! \fn QCborValue QCborMap::toCborValue() const Explicitly constructs a \l QCborValue object that represents this map. This function is usually not necessary since QCborValue has a constructor for QCborMap, so the conversion is implicit. Converting QCborMap to QCborValue allows it to be used in any context where QCborValues can be used, including as keys and mapped types in QCborMap, as well as QCborValue::toCbor(). \sa QCborValue::QCborValue(const QCborMap &) */ /*! \fn bool QCborMap::isEmpty() const Returns true if this map is empty (that is, size() is 0). \sa size(), clear() */ /*! Returns the number of elements in this map. \sa isEmpty() */ qsizetype QCborMap::size() const noexcept { return d ? d->elements.size() / 2 : 0; } /*! Empties this map. \sa isEmpty() */ void QCborMap::clear() { d.reset(); } /*! Returns a list of all keys in this map. \sa QMap::keys(), QHash::keys() */ QVector QCborMap::keys() const { QVector result; if (d) { result.reserve(size()); for (qsizetype i = 0; i < d->elements.size(); i += 2) result << d->valueAt(i); } return result; } /*! \fn QCborValue QCborMap::value(qint64 key) const Returns the QCborValue element in this map that corresponds to key \a key, if there is one. CBOR recommends using integer keys, since they occupy less space and are simpler to encode and decode. If the map does not contain key \a key, this function returns a QCborValue containing an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one the return from function will reference. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa operator[](qint64), find(qint64), constFind(qint64), remove(qint64), contains(qint64) value(QLatin1String), value(const QString &), value(const QCborValue &) */ /*! \fn QCborValue QCborMap::operator[](qint64 key) const Returns the QCborValue element in this map that corresponds to key \a key, if there is one. CBOR recommends using integer keys, since they occupy less space and are simpler to encode and decode. If the map does not contain key \a key, this function returns a QCborValue containing an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one this function will return. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(qint64), find(qint64), constFind(qint64), remove(qint64), contains(qint64) operator[](QLatin1String), operator[](const QString &), operator[](const QCborOperator[] &) */ /*! \fn QCborValue QCborMap::take(qint64 key) Removes the key \a key and the corresponding value from the map and returns the value, if it is found. If the map contains no such key, this function does nothing. If the map contains more than one key equal to \a key, it is undefined which one this function will remove. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(qint64), operator[](qint64), find(qint64), contains(qint64), take(QLatin1String), take(const QString &), take(const QCborValue &), insert() */ /*! \fn void QCborMap::remove(qint64 key) Removes the key \a key and the corresponding value from the map, if it is found. If the map contains no such key, this function does nothing. If the map contains more than one key equal to \a key, it is undefined which one this function will remove. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(qint64), operator[](qint64), find(qint64), contains(qint64) remove(QLatin1String), remove(const QString &), remove(const QCborValue &) */ /*! \fn bool QCborMap::contains(qint64 key) const Returns true if this map contains a key-value pair identified by key \a key. CBOR recommends using integer keys, since they occupy less space and are simpler to encode and decode. \sa value(qint64), operator[](qint64), find(qint64), remove(qint64), contains(QLatin1String), remove(const QString &), remove(const QCborValue &) */ /*! Returns a QCborValueRef to the value in this map that corresponds to key \a key. CBOR recommends using integer keys, since they occupy less space and are simpler to encode and decode. QCborValueRef has the exact same API as \l QCborValue, with one important difference: if you assign new values to it, this map will be updated with that new value. If the map did not have a key equal to \a key, one is inserted and this function returns a reference to the new value, which will be a QCborValue with an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one the return will reference. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(qint64), find(qint64), contains(qint64), remove(qint64), operator[](QLatin1String), operator[](const QString &), operator[](const QCborValue &) */ QCborValueRef QCborMap::operator[](qint64 key) { auto it = find(key); if (it == constEnd()) { // insert element detach(it.item.i + 2); d->append(key); d->append(Undefined{}); } return { d.data(), it.item.i }; } /*! \fn QCborValue QCborMap::value(QLatin1String key) const \overload Returns the QCborValue element in this map that corresponds to key \a key, if there is one. If the map does not contain key \a key, this function returns a QCborValue containing an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one this function will return. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa operator[](QLatin1String), find(QLatin1String), constFind(QLatin1String), remove(QLatin1String), contains(QLatin1String) value(qint64), value(const QString &), value(const QCborValue &) */ /*! \fn QCborValue QCborMap::operator[](QLatin1String key) const \overload Returns the QCborValue element in this map that corresponds to key \a key, if there is one. If the map does not contain key \a key, this function returns a QCborValue containing an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one this function will return. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(QLatin1String), find(QLatin1String), constFind(QLatin1String), remove(QLatin1String), contains(QLatin1String) operator[](qint64), operator[](const QString &), operator[](const QCborOperator[] &) */ /*! \fn QCborValue QCborMap::take(QLatin1String key) Removes the key \a key and the corresponding value from the map and returns the value, if it is found. If the map contains no such key, this function does nothing. If the map contains more than one key equal to \a key, it is undefined which one this function will remove. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(QLatin1String), operator[](QLatin1String), find(QLatin1String), contains(QLatin1String), take(qint64), take(const QString &), take(const QCborValue &), insert() */ /*! \fn void QCborMap::remove(QLatin1String key) \overload Removes the key \a key and the corresponding value from the map, if it is found. If the map contains no such key, this function does nothing. If the map contains more than one key equal to \a key, it is undefined which one this function will remove. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(QLatin1String), operator[](QLatin1String), find(QLatin1String), contains(QLatin1String) remove(qint64), remove(const QString &), remove(const QCborValue &) */ /*! \fn bool QCborMap::contains(QLatin1String key) const \overload Returns true if this map contains a key-value pair identified by key \a key. \sa value(QLatin1String), operator[](QLatin1String), find(QLatin1String), remove(QLatin1String), contains(qint64), remove(const QString &), remove(const QCborValue &) */ /*! \overload Returns a QCborValueRef to the value in this map that corresponds to key \a key. QCborValueRef has the exact same API as \l QCborValue, with one important difference: if you assign new values to it, this map will be updated with that new value. If the map did not have a key equal to \a key, one is inserted and this function returns a reference to the new value, which will be a QCborValue with an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one the return will reference. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(QLatin1String), find(QLatin1String), contains(QLatin1String), remove(QLatin1String), operator[](qint64), operator[](const QString &), operator[](const QCborValue &) */ QCborValueRef QCborMap::operator[](QLatin1String key) { auto it = find(key); if (it == constEnd()) { // insert element detach(it.item.i + 2); d->append(key); d->append(Undefined{}); } return { d.data(), it.item.i }; } /*! \fn QCborValue QCborMap::value(const QString &key) const \overload Returns the QCborValue element in this map that corresponds to key \a key, if there is one. If the map does not contain key \a key, this function returns a QCborValue containing an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one this function will return. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa operator[](const QString &), find(const QString &), constFind(const QString &), remove(const QString &), contains(const QString &) value(qint64), value(QLatin1String), value(const QCborValue &) */ /*! \fn QCborValue QCborMap::operator[](const QString &key) const \overload Returns the QCborValue element in this map that corresponds to key \a key, if there is one. If the map does not contain key \a key, this function returns a QCborValue containing an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one this function will return. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QString &), find(const QString &), constFind(const QString &), remove(const QString &), contains(const QString &) operator[](qint64), operator[](QLatin1String), operator[](const QCborOperator[] &) */ /*! \fn QCborValue QCborMap::take(const QString &key) Removes the key \a key and the corresponding value from the map and returns the value, if it is found. If the map contains no such key, this function does nothing. If the map contains more than one key equal to \a key, it is undefined which one this function will remove. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QString &), operator[](const QString &), find(const QString &), contains(const QString &), take(QLatin1String), take(qint64), take(const QCborValue &), insert() */ /*! \fn void QCborMap::remove(const QString &key) \overload Removes the key \a key and the corresponding value from the map, if it is found. If the map contains no such key, this function does nothing. If the map contains more than one key equal to \a key, it is undefined which one this function will remove. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QString &), operator[](const QString &), find(const QString &), contains(const QString &) remove(qint64), remove(QLatin1String), remove(const QCborValue &) */ /*! \fn bool QCborMap::contains(const QString &key) const \overload Returns true if this map contains a key-value pair identified by key \a key. \sa value(const QString &), operator[](const QString &), find(const QString &), remove(const QString &), contains(qint64), remove(QLatin1String), remove(const QCborValue &) */ /*! \overload Returns a QCborValueRef to the value in this map that corresponds to key \a key. QCborValueRef has the exact same API as \l QCborValue, with one important difference: if you assign new values to it, this map will be updated with that new value. If the map did not have a key equal to \a key, one is inserted and this function returns a reference to the new value, which will be a QCborValue with an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one the return will reference. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QString &), find(const QString &), contains(const QString &), remove(const QString &), operator[](qint64), operator[](QLatin1String), operator[](const QCborValue &) */ QCborValueRef QCborMap::operator[](const QString & key) { auto it = find(key); if (it == constEnd()) { // insert element detach(it.item.i + 2); d->append(key); d->append(Undefined{}); } return { d.data(), it.item.i }; } /*! \fn QCborValue QCborMap::value(const QCborValue &key) const Returns the QCborValue element in this map that corresponds to key \a key, if there is one. If the map does not contain key \a key, this function returns a QCborValue containing an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one this function will return. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa operator[](const QCborValue &), find(const QCborValue &), constFind(const QCborValue &), remove(const QCborValue &), contains(const QCborValue &) value(qint64), value(QLatin1String), value(const QString &) */ /*! \fn QCborValue QCborMap::operator[](const QCborValue &key) const Returns the QCborValue element in this map that corresponds to key \a key, if there is one. If the map does not contain key \a key, this function returns a QCborValue containing an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one this function will return. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QCborValue &), find(const QCborValue &), constFind(const QCborValue &), remove(const QCborValue &), contains(const QCborValue &) operator[](qint64), operator[](QLatin1String), operator[](const QCborOperator[] &) */ /*! \fn QCborValue QCborMap::take(const QCborValue &key) Removes the key \a key and the corresponding value from the map and returns the value, if it is found. If the map contains no such key, this function does nothing. If the map contains more than one key equal to \a key, it is undefined which one this function will remove. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &), contains(const QCborValue &), take(QLatin1String), take(const QString &), take(qint64), insert() */ /*! \fn void QCborMap::remove(const QCborValue &key) Removes the key \a key and the corresponding value from the map, if it is found. If the map contains no such key, this function does nothing. If the map contains more than one key equal to \a key, it is undefined which one this function will remove. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &), contains(const QCborValue &) remove(qint64), remove(QLatin1String), remove(const QString &) */ /*! \fn bool QCborMap::contains(const QCborValue &key) const Returns true if this map contains a key-value pair identified by key \a key. \sa value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &), remove(const QCborValue &), contains(qint64), remove(QLatin1String), remove(const QString &) */ /*! \overload Returns a QCborValueRef to the value in this map that corresponds to key \a key. QCborValueRef has the exact same API as \l QCborValue, with one important difference: if you assign new values to it, this map will be updated with that new value. If the map did not have a key equal to \a key, one is inserted and this function returns a reference to the new value, which will be a QCborValue with an undefined value. For that reason, it is not possible with this function to tell apart the situation where the key was not present from the situation where the key was mapped to an undefined value. If the map contains more than one key equal to \a key, it is undefined which one the return will reference. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QCborValue &), find(const QCborValue &), contains(const QCborValue &), remove(const QCborValue &), operator[](qint64), operator[](QLatin1String), operator[](const QString &) */ QCborValueRef QCborMap::operator[](const QCborValue &key) { auto it = find(key); if (it == constEnd()) { // insert element detach(it.item.i + 2); d->append(key); d->append(Undefined{}); } return { d.data(), it.item.i }; } /*! \fn QCborMap::iterator QCborMap::find(qint64 key) \fn QCborMap::const_iterator QCborMap::find(qint64 key) const Returns a map iterator to the key-value pair whose key is \a key, if the map contains such a pair. If it doesn't, this function returns end(). CBOR recommends using integer keys, since they occupy less space and are simpler to encode and decode. If the map contains more than one key equal to \a key, it is undefined which one this function will find. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(qint64), operator[](qint64), constFind(qint64), remove(qint64), contains(qint64) value(QLatin1String), value(const QString &), value(const QCborValue &) */ QCborMap::iterator QCborMap::find(qint64 key) { auto it = constFind(key); if (it != constEnd()) detach(); return { d.data(), it.item.i }; } /*! \fn QCborMap::iterator QCborMap::find(QLatin1String key) \fn QCborMap::const_iterator QCborMap::find(QLatin1String key) const \overload Returns a map iterator to the key-value pair whose key is \a key, if the map contains such a pair. If it doesn't, this function returns end(). If the map contains more than one key equal to \a key, it is undefined which one this function will find. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(QLatin1String), operator[](QLatin1String), constFind(QLatin1String), remove(QLatin1String), contains(QLatin1String) value(qint64), value(const QString &), value(const QCborValue &) */ QCborMap::iterator QCborMap::find(QLatin1String key) { auto it = constFind(key); if (it != constEnd()) detach(); return { d.data(), it.item.i }; } /*! \fn QCborMap::iterator QCborMap::find(const QString & key) \fn QCborMap::const_iterator QCborMap::find(const QString & key) const \overload Returns a map iterator to the key-value pair whose key is \a key, if the map contains such a pair. If it doesn't, this function returns end(). If the map contains more than one key equal to \a key, it is undefined which one this function will find. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QString &), operator[](const QString &), constFind(const QString &), remove(const QString &), contains(const QString &) value(qint64), value(QLatin1String), value(const QCborValue &) */ QCborMap::iterator QCborMap::find(const QString & key) { auto it = constFind(key); if (it != constEnd()) detach(); return { d.data(), it.item.i }; } /*! \fn QCborMap::iterator QCborMap::find(const QCborValue &key) \fn QCborMap::const_iterator QCborMap::find(const QCborValue &key) const \overload Returns a map iterator to the key-value pair whose key is \a key, if the map contains such a pair. If it doesn't, this function returns end(). If the map contains more than one key equal to \a key, it is undefined which one this function will find. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QCborValue &), operator[](const QCborValue &), constFind(const QCborValue &), remove(const QCborValue &), contains(const QCborValue &) value(qint64), value(QLatin1String), value(const QString &) */ QCborMap::iterator QCborMap::find(const QCborValue &key) { auto it = constFind(key); if (it != constEnd()) detach(); return { d.data(), it.item.i }; } /*! Returns a map iterator to the key-value pair whose key is \a key, if the map contains such a pair. If it doesn't, this function returns constEnd(). CBOR recommends using integer keys, since they occupy less space and are simpler to encode and decode. If the map contains more than one key equal to \a key, it is undefined which one this function will find. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(qint64), operator[](qint64), find(qint64), remove(qint64), contains(qint64) value(QLatin1String), value(const QString &), value(const QCborValue &) */ QCborMap::const_iterator QCborMap::constFind(qint64 key) const { for (qsizetype i = 0; i < 2 * size(); i += 2) { const auto &e = d->elements.at(i); if (e.type == QCborValue::Integer && e.value == key) return { d.data(), i + 1 }; } return constEnd(); } /*! \overload Returns a map iterator to the key-value pair whose key is \a key, if the map contains such a pair. If it doesn't, this function returns constEnd(). If the map contains more than one key equal to \a key, it is undefined which one this function will find. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(QLatin1String), operator[](QLatin1String), find(QLatin1String), remove(QLatin1String), contains(QLatin1String) value(qint64), value(const QString &), value(const QCborValue &) */ QCborMap::const_iterator QCborMap::constFind(QLatin1String key) const { for (qsizetype i = 0; i < 2 * size(); i += 2) { if (d->stringEqualsElement(i, key)) return { d.data(), i + 1 }; } return constEnd(); } /*! \overload Returns a map iterator to the key-value pair whose key is \a key, if the map contains such a pair. If it doesn't, this function returns constEnd(). If the map contains more than one key equal to \a key, it is undefined which one this function will find. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QString &), operator[](const QString &), find(const QString &), remove(const QString &), contains(const QString &) value(qint64), value(QLatin1String), value(const QCborValue &) */ QCborMap::const_iterator QCborMap::constFind(const QString & key) const { for (qsizetype i = 0; i < 2 * size(); i += 2) { if (d->stringEqualsElement(i, key)) return { d.data(), i + 1 }; } return constEnd(); } /*! \overload Returns a map iterator to the key-value pair whose key is \a key, if the map contains such a pair. If it doesn't, this function returns constEnd(). If the map contains more than one key equal to \a key, it is undefined which one this function will find. QCborMap does not allow inserting duplicate keys, but it is possible to create such a map by decoding a CBOR stream with them. They are usually not permitted and having duplicate keys is usually an indication of a problem in the sender. \sa value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &), remove(const QCborValue &), contains(const QCborValue &), value(qint64), value(QLatin1String), value(const QString &) */ QCborMap::const_iterator QCborMap::constFind(const QCborValue &key) const { for (qsizetype i = 0; i < 2 * size(); i += 2) { int cmp = d->compareElement(i, key); if (cmp == 0) return { d.data(), i + 1 }; } return constEnd(); } /*! \fn QCborMap::iterator QCborMap::insert(qint64 key, const QCborValue &value) \overload Inserts the key \a key and value \a value into this map and returns a map iterator pointing to the newly inserted pair. If the map already had a key equal to \a key, its value will be overwritten by \a value. \sa erase(), remove(qint64), value(qint64), operator[](qint64), find(qint64), contains(qint64), take(qint64), extract() */ /*! \fn QCborMap::iterator QCborMap::insert(QLatin1String key, const QCborValue &value) \overload Inserts the key \a key and value \a value into this map and returns a map iterator pointing to the newly inserted pair. If the map already had a key equal to \a key, its value will be overwritten by \a value. \sa erase(), remove(QLatin1String), value(QLatin1String), operator[](QLatin1String), find(QLatin1String), contains(QLatin1String), take(QLatin1String), extract() */ /*! \fn QCborMap::iterator QCborMap::insert(const QString &key, const QCborValue &value) \overload Inserts the key \a key and value \a value into this map and returns a map iterator pointing to the newly inserted pair. If the map already had a key equal to \a key, its value will be overwritten by \a value. \sa erase(), remove(const QString &), value(const QString &), operator[](const QString &), find(const QString &), contains(const QString &), take(const QString &), extract() */ /*! \fn QCborMap::iterator QCborMap::insert(const QCborValue &key, const QCborValue &value) \overload Inserts the key \a key and value \a value into this map and returns a map iterator pointing to the newly inserted pair. If the map already had a key equal to \a key, its value will be overwritten by \a value. \sa erase(), remove(const QCborValue &), value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &), contains(const QCborValue &), take(const QCborValue &), extract() */ /*! \fn QCborMap::iterator QCborMap::insert(value_type v) \overload Inserts the key-value pair in \a v into this map and returns a map iterator pointing to the newly inserted pair. If the map already had a key equal to \c{v.first}, its value will be overwritten by \c{v.second}. \sa operator[], erase(), extract() */ /*! \fn QCborMap::iterator QCborMap::erase(const_iterator it) Removes the key-value pair pointed to by the map iterator \a it and returns a pointer to the next element, after removal. \sa remove(), begin(), end(), insert(), extract() */ /*! \overload Removes the key-value pair pointed to by the map iterator \a it and returns a pointer to the next element, after removal. \sa remove(), begin(), end(), insert() */ QCborMap::iterator QCborMap::erase(QCborMap::iterator it) { detach(); // remove both key and value // ### optimize? d->removeAt(it.item.i - 1); d->removeAt(it.item.i - 1); return it; } /*! \fn QCborValue QCborMap::extract(iterator it) \fn QCborValue QCborMap::extract(const_iterator it) Extracts a value from the map at the position indicated by iterator \a it and returns the value so extracted. \sa insert(), erase(), take(), remove() */ QCborValue QCborMap::extract(iterator it) { detach(); QCborValue v = d->extractAt(it.item.i); // remove both key and value // ### optimize? d->removeAt(it.item.i - 1); d->removeAt(it.item.i - 1); return v; } /*! \fn bool QCborMap::empty() const Synonym for isEmpty(). This function is provided for compatibility with generic code that uses the Standard Library API. Returns true if this map is empty (size() == 0). \sa isEmpty(), size() */ /*! \fn int QCborMap::compare(const QCborMap &other) const Compares this map and \a other, comparing each element in sequence, and returns an integer that indicates whether this map should be sorted prior to (if the result is negative) or after \a other (if the result is positive). If this function returns 0, the two maps are equal and contain the same elements. Note that CBOR maps are unordered, which means that two maps containing the very same pairs but in different order will still compare differently. To avoid this, it is recommended to insert elements into the map in a predictable order, such as by ascending key value. In fact, maps with keys in sorted order are required for Canonical CBOR representation. For more information on CBOR sorting order, see QCborValue::compare(). \sa QCborValue::compare(), QCborArray::compare(), operator==() */ /*! \fn bool QCborMap::operator==(const QCborMap &other) const Compares this map and \a other, comparing each element in sequence, and returns true if the two maps contains the same elements in the same order, false otherwise. Note that CBOR maps are unordered, which means that two maps containing the very same pairs but in different order will still compare differently. To avoid this, it is recommended to insert elements into the map in a predictable order, such as by ascending key value. In fact, maps with keys in sorted order are required for Canonical CBOR representation. For more information on CBOR equality in Qt, see, QCborValue::compare(). \sa compare(), QCborValue::operator==(), QCborMap::operator==(), operator!=(), operator<() */ /*! \fn bool QCborMap::operator!=(const QCborMap &other) const Compares this map and \a other, comparing each element in sequence, and returns true if the two maps contains any different elements or elements in different orders, false otherwise. Note that CBOR maps are unordered, which means that two maps containing the very same pairs but in different order will still compare differently. To avoid this, it is recommended to insert elements into the map in a predictable order, such as by ascending key value. In fact, maps with keys in sorted order are required for Canonical CBOR representation. For more information on CBOR equality in Qt, see, QCborValue::compare(). \sa compare(), QCborValue::operator==(), QCborMap::operator==(), operator==(), operator<() */ /*! \fn bool QCborMap::operator<(const QCborMap &other) const Compares this map and \a other, comparing each element in sequence, and returns true if this map should be sorted before \a other, false otherwise. Note that CBOR maps are unordered, which means that two maps containing the very same pairs but in different order will still compare differently. To avoid this, it is recommended to insert elements into the map in a predictable order, such as by ascending key value. In fact, maps with keys in sorted order are required for Canonical CBOR representation. For more information on CBOR sorting order, see QCborValue::compare(). \sa compare(), QCborValue::operator==(), QCborMap::operator==(), operator==(), operator!=() */ void QCborMap::detach(qsizetype reserved) { d = QCborContainerPrivate::detach(d.data(), reserved ? reserved : size() * 2); } /*! \class QCborMap::Iterator \inmodule QtCore \ingroup cbor \reentrant \since 5.12 \brief The QCborMap::Iterator class provides an STL-style non-const iterator for QCborMap. QCborMap::Iterator allows you to iterate over a QCborMap and to modify the value (but not the key) stored under a particular key. If you want to iterate over a const QCborMap, you should use QCborMap::ConstIterator. It is generally good practice to use QCborMap::ConstIterator on a non-const QCborMap as well, unless you need to change the QCborMap through the iterator. Const iterators are slightly faster, and improve code readability. You must initialize the iterator using a QCborMap function like QCborMap::begin(), QCborMap::end(), or QCborMap::find() before you can start iterating.. Multiple iterators can be used on the same object. Existing iterators will however become dangling once the object gets modified. \sa QCborMap::ConstIterator */ /*! \typedef QCborMap::Iterator::difference_type \internal */ /*! \typedef QCborMap::Iterator::iterator_category A synonym for \e {std::random_access_iterator_tag} indicating this iterator is a random-access iterator. */ /*! \typedef QCborMap::Iterator::reference \internal */ /*! \typedef QCborMap::Iterator::value_type \internal */ /*! \typedef QCborMap::Iterator::pointer \internal */ /*! \fn QCborMap::Iterator::Iterator() Constructs an uninitialized iterator. Functions like key(), value(), and operator++() must not be called on an uninitialized iterator. Use operator=() to assign a value to it before using it. \sa QCborMap::begin(), QCborMap::end() */ /*! \fn QCborMap::Iterator::Iterator(const Iterator &other) Constructs an iterator as a copy of \a other. */ /*! \fn QCborMap::Iterator &QCborMap::Iterator::operator=(const Iterator &other) Makes this iterator a copy of \a other and returns a reference to this iterator. */ /*! \fn QCborValue QCborMap::Iterator::key() const Returns the current item's key. There is no direct way of changing an item's key through an iterator, although it can be done by calling QCborMap::erase() followed by QCborMap::insert(). \sa value() */ /*! \fn QCborValueRef QCborMap::Iterator::value() const Returns a modifiable reference to the current item's value. You can change the value for a key by using value() on the left side of an assignment. The return value is of type QCborValueRef, a helper class for QCborArray and QCborMap. When you get an object of type QCborValueRef, you can use it as if it were a reference to a QCborValue. If you assign to it, the assignment will apply to the element in the QCborArray or QCborMap from which you got the reference. \sa key(), operator*() */ /*! \fn QCborMap::Iterator::value_type QCborMap::Iterator::operator*() const Returns a pair containing the current item's key and a modifiable reference to the current item's value. The second element of the pair is of type QCborValueRef, a helper class for QCborArray and QCborMap. When you get an object of type QCborValueRef, you can use it as if it were a reference to a QCborValue. If you assign to it, the assignment will apply to the element in the QCborArray or QCborMap from which you got the reference. \sa key(), value() */ /*! \fn QCborValueRef *QCborMap::Iterator::operator->() const Returns a pointer to a modifiable reference to the current pair's value. */ /*! \fn bool QCborMap::Iterator::operator==(const Iterator &other) const \fn bool QCborMap::Iterator::operator==(const ConstIterator &other) const Returns \c true if \a other points to the same entry in the map as this iterator; otherwise returns \c false. \sa operator!=() */ /*! \fn bool QCborMap::Iterator::operator!=(const Iterator &other) const \fn bool QCborMap::Iterator::operator!=(const ConstIterator &other) const Returns \c true if \a other points to a different entry in the map than this iterator; otherwise returns \c false. \sa operator==() */ /*! \fn bool QCborMap::Iterator::operator<(const Iterator& other) const \fn bool QCborMap::Iterator::operator<(const ConstIterator& other) const Returns \c true if the entry in the map pointed to by this iterator occurs before the entry pointed to by the \a other iterator. */ /*! \fn bool QCborMap::Iterator::operator<=(const Iterator& other) const \fn bool QCborMap::Iterator::operator<=(const ConstIterator& other) const Returns \c true if the entry in the map pointed to by this iterator occurs before or is the same entry as is pointed to by the \a other iterator. */ /*! \fn bool QCborMap::Iterator::operator>(const Iterator& other) const \fn bool QCborMap::Iterator::operator>(const ConstIterator& other) const Returns \c true if the entry in the map pointed to by this iterator occurs after the entry pointed to by the \a other iterator. */ /*! \fn bool QCborMap::Iterator::operator>=(const Iterator& other) const \fn bool QCborMap::Iterator::operator>=(const ConstIterator& other) const Returns \c true if the entry in the map pointed to by this iterator occurs after or is the same entry as is pointed to by the \a other iterator. */ /*! \fn QCborMap::Iterator &QCborMap::Iterator::operator++() The prefix ++ operator, \c{++i}, advances the iterator to the next item in the map and returns this iterator. Calling this function on QCborMap::end() leads to undefined results. \sa operator--() */ /*! \fn QCborMap::Iterator QCborMap::Iterator::operator++(int) \overload The postfix ++ operator, \c{i++}, advances the iterator to the next item in the map and returns an iterator to the previously current item. */ /*! \fn QCborMap::Iterator QCborMap::Iterator::operator--() The prefix -- operator, \c{--i}, makes the preceding item current and returns this iterator. Calling this function on QCborMap::begin() leads to undefined results. \sa operator++() */ /*! \fn QCborMap::Iterator QCborMap::Iterator::operator--(int) \overload The postfix -- operator, \c{i--}, makes the preceding item current and returns an iterator pointing to the previously current item. */ /*! \fn QCborMap::Iterator QCborMap::Iterator::operator+(qsizetype j) const Returns an iterator to the item at \a j positions forward from this iterator. If \a j is negative, the iterator goes backward. \sa operator-() */ /*! \fn QCborMap::Iterator QCborMap::Iterator::operator-(qsizetype j) const Returns an iterator to the item at \a j positions backward from this iterator. If \a j is negative, the iterator goes forward. \sa operator+() */ /*! \fn qsizetype QCborMap::Iterator::operator-(QCborMap::Iterator j) const Returns the position of the item at iterator \a j relative to the item at this iterator. If the item at \a j is forward of this time, the returned value is negative. \sa operator+() */ /*! \fn QCborMap::Iterator &QCborMap::Iterator::operator+=(qsizetype j) Advances the iterator by \a j items. If \a j is negative, the iterator goes backward. Returns a reference to this iterator. \sa operator-=(), operator+() */ /*! \fn QCborMap::Iterator &QCborMap::Iterator::operator-=(qsizetype j) Makes the iterator go back by \a j items. If \a j is negative, the iterator goes forward. Returns a reference to this iterator. \sa operator+=(), operator-() */ /*! \class QCborMap::ConstIterator \inmodule QtCore \ingroup cbor \since 5.12 \brief The QCborMap::ConstIterator class provides an STL-style const iterator for QCborMap. QCborMap::ConstIterator allows you to iterate over a QCborMap. If you want to modify the QCborMap as you iterate over it, you must use QCborMap::Iterator instead. It is generally good practice to use QCborMap::ConstIterator, even on a non-const QCborMap, when you don't need to change the QCborMap through the iterator. Const iterators are slightly faster and improve code readability. You must initialize the iterator using a QCborMap function like QCborMap::begin(), QCborMap::end(), or QCborMap::find() before you can start iterating.. Multiple iterators can be used on the same object. Existing iterators will however become dangling if the object gets modified. \sa QCborMap::Iterator */ /*! \typedef QCborMap::ConstIterator::difference_type \internal */ /*! \typedef QCborMap::ConstIterator::iterator_category A synonym for \e {std::random_access_iterator_tag} indicating this iterator is a random-access iterator. */ /*! \typedef QCborMap::ConstIterator::reference \internal */ /*! \typedef QCborMap::ConstIterator::value_type \internal */ /*! \typedef QCborMap::ConstIterator::pointer \internal */ /*! \fn QCborMap::ConstIterator::ConstIterator() Constructs an uninitialized iterator. Functions like key(), value(), and operator++() must not be called on an uninitialized iterator. Use operator=() to assign a value to it before using it. \sa QCborMap::constBegin(), QCborMap::constEnd() */ /*! \fn QCborMap::ConstIterator::ConstIterator(const ConstIterator &other) Constructs an iterator as a copy of \a other. */ /*! \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator=(const ConstIterator &other) Makes this iterator a copy of \a other and returns a reference to this iterator. */ /*! \fn QString QCborMap::ConstIterator::key() const Returns the current item's key. \sa value() */ /*! \fn QCborValue QCborMap::ConstIterator::value() const Returns the current item's value. \sa key(), operator*() */ /*! \fn QCborMap::ConstIterator::value_type QCborMap::ConstIterator::operator*() const Returns a pair containing the curent item's key and value. \sa key(), value() */ /*! \fn const QCborValueRef *QCborMap::ConstIterator::operator->() const Returns a pointer to the current pair's value. */ /*! \fn bool QCborMap::ConstIterator::operator==(const ConstIterator &other) const \fn bool QCborMap::ConstIterator::operator==(const Iterator &other) const Returns \c true if \a other points to the same entry in the map as this iterator; otherwise returns \c false. \sa operator!=() */ /*! \fn bool QCborMap::ConstIterator::operator!=(const ConstIterator &other) const \fn bool QCborMap::ConstIterator::operator!=(const Iterator &other) const Returns \c true if \a other points to a different entry in the map than this iterator; otherwise returns \c false. \sa operator==() */ /*! \fn bool QCborMap::ConstIterator::operator<(const Iterator &other) const \fn bool QCborMap::ConstIterator::operator<(const ConstIterator &other) const Returns \c true if the entry in the map pointed to by this iterator occurs before the entry pointed to by the \a other iterator. */ /*! \fn bool QCborMap::ConstIterator::operator<=(const Iterator &other) const \fn bool QCborMap::ConstIterator::operator<=(const ConstIterator &other) const Returns \c true if the entry in the map pointed to by this iterator occurs before or is the same entry as is pointed to by the \a other iterator. */ /*! \fn bool QCborMap::ConstIterator::operator>(const Iterator &other) const \fn bool QCborMap::ConstIterator::operator>(const ConstIterator &other) const Returns \c true if the entry in the map pointed to by this iterator occurs after the entry pointed to by the \a other iterator. */ /*! \fn bool QCborMap::ConstIterator::operator>=(const Iterator &other) const \fn bool QCborMap::ConstIterator::operator>=(const ConstIterator &other) const Returns \c true if the entry in the map pointed to by this iterator occurs after or is the same entry as is pointed to by the \a other iterator. */ /*! \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator++() The prefix ++ operator, \c{++i}, advances the iterator to the next item in the map and returns this iterator. Calling this function on QCborMap::end() leads to undefined results. \sa operator--() */ /*! \fn QCborMap::ConstIterator QCborMap::ConstIterator::operator++(int) \overload The postfix ++ operator, \c{i++}, advances the iterator to the next item in the map and returns an iterator to the previously current item. */ /*! \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator--() The prefix -- operator, \c{--i}, makes the preceding item current and returns this iterator. Calling this function on QCborMap::begin() leads to undefined results. \sa operator++() */ /*! \fn QCborMap::ConstIterator QCborMap::ConstIterator::operator--(int) \overload The postfix -- operator, \c{i--}, makes the preceding item current and returns an iterator pointing to the previously current item. */ /*! \fn QCborMap::ConstIterator QCborMap::ConstIterator::operator+(qsizetype j) const Returns an iterator to the item at \a j positions forward from this iterator. If \a j is negative, the iterator goes backward. \sa operator-() */ /*! \fn QCborMap::ConstIterator QCborMap::ConstIterator::operator-(qsizetype j) const Returns an iterator to the item at \a j positions backward from this iterator. If \a j is negative, the iterator goes forward. \sa operator+() */ /*! \fn qsizetype QCborMap::ConstIterator::operator-(QCborMap::ConstIterator j) const Returns the position of the item at iterator \a j relative to the item at this iterator. If the item at \a j is forward of this time, the returned value is negative. \sa operator+() */ /*! \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator+=(qsizetype j) Advances the iterator by \a j items. If \a j is negative, the iterator goes backward. Returns a reference to this iterator. \sa operator-=(), operator+() */ /*! \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator-=(qsizetype j) Makes the iterator go back by \a j items. If \a j is negative, the iterator goes forward. Returns a reference to this iterator. \sa operator+=(), operator-() */ uint qHash(const QCborMap &map, uint seed) { return qHashRange(map.begin(), map.end(), seed); } #if !defined(QT_NO_DEBUG_STREAM) QDebug operator<<(QDebug dbg, const QCborMap &m) { QDebugStateSaver saver(dbg); dbg.nospace() << "QCborMap{"; const char *open = "{"; for (auto pair : m) { dbg << open << pair.first << ", " << pair.second << '}'; open = ", {"; } return dbg << '}'; } #endif QT_END_NAMESPACE