diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-12-12 23:34:08 -0800 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-06-08 07:46:29 +0000 |
commit | 92e472302a0ef8390f60fd91cac7f360b199a1e4 (patch) | |
tree | f35dc12c20bff0c952e81f1c53d5f2c55494a4ed /src/corelib/serialization/qcbormap.cpp | |
parent | 95e6ab332917c83e874442eca4785fe3d62cec9b (diff) |
Long live DOM API for CBOR!
This is very similar to QJsonDocument, but there's no QCborDocument.
QCborValue is that.
[ChangeLog][QtCore] Added QCborValue, QCborArray and QCborMap, classes
that permit DOM-like access to CBOR data. The API is similar to
QJsonValue, QJsonArray and QJsonObject, respectively.
Change-Id: I9741f017961b410c910dfffd14ffca50dd8ef3ba
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/corelib/serialization/qcbormap.cpp')
-rw-r--r-- | src/corelib/serialization/qcbormap.cpp | 1553 |
1 files changed, 1553 insertions, 0 deletions
diff --git a/src/corelib/serialization/qcbormap.cpp b/src/corelib/serialization/qcbormap.cpp new file mode 100644 index 0000000000..f7d58ca90b --- /dev/null +++ b/src/corelib/serialization/qcbormap.cpp @@ -0,0 +1,1553 @@ +/**************************************************************************** +** +** 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 + +/*! + \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() Q_DECL_NOTHROW + : d(nullptr) +{ +} + +/*! + Creates a QCborMap object that is a copy of \a other. + */ +QCborMap::QCborMap(const QCborMap &other) Q_DECL_NOTHROW + : d(other.d) +{ +} + +/*! + \fn QCborMap::QCborMap(std::initializer_list<value_type> 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) Q_DECL_NOTHROW +{ + 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() + */ + +/*! + Returns the number of elements in this map. + + \sa isEmpty() + */ +qsizetype QCborMap::size() const Q_DECL_NOTHROW +{ + return d ? d->elements.size() / 2 : 0; +} + +/*! + Returns a list of all keys in this map. + + \sa QMap::keys(), QHash::keys() + */ +QVector<QCborValue> QCborMap::keys() const +{ + QVector<QCborValue> 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 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) + + 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 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) + \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 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) + \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 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) + + 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 }; +} + +/*! + 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 }; +} + +/*! + \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 }; +} + +/*! + \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 }; +} + +/*! + \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) + */ + +/*! + \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) + */ + +/*! + \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 &) + */ + +/*! + \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 &) + */ + +/*! + \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() + */ + + +/*! + \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() + */ + +/*! + \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 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 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 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 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 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-() +*/ + +QT_END_NAMESPACE |