| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the QtCore module of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU Lesser General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | 
| 21 | ** packaging of this file. Please review the following information to | 
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements | 
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | 
| 24 | ** | 
| 25 | ** GNU General Public License Usage | 
| 26 | ** Alternatively, this file may be used under the terms of the GNU | 
| 27 | ** General Public License version 2.0 or (at your option) the GNU General | 
| 28 | ** Public license version 3 or any later version approved by the KDE Free | 
| 29 | ** Qt Foundation. The licenses are as published by the Free Software | 
| 30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | 
| 31 | ** included in the packaging of this file. Please review the following | 
| 32 | ** information to ensure the GNU General Public License requirements will | 
| 33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | 
| 34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | 
| 35 | ** | 
| 36 | ** $QT_END_LICENSE$ | 
| 37 | ** | 
| 38 | ****************************************************************************/ | 
| 39 |  | 
| 40 | #include <qjsonobject.h> | 
| 41 | #include <qjsonvalue.h> | 
| 42 | #include <qjsonarray.h> | 
| 43 | #include <qjsondocument.h> | 
| 44 | #include <qstringlist.h> | 
| 45 | #include <qdebug.h> | 
| 46 | #include <qvariant.h> | 
| 47 | #include <qcbormap.h> | 
| 48 |  | 
| 49 | #include <private/qcborvalue_p.h> | 
| 50 | #include "qjsonwriter_p.h" | 
| 51 | #include "qjson_p.h" | 
| 52 |  | 
| 53 | #include <algorithm> | 
| 54 |  | 
| 55 | QT_BEGIN_NAMESPACE | 
| 56 |  | 
| 57 | /*! | 
| 58 |     \class QJsonObject | 
| 59 |     \inmodule QtCore | 
| 60 |     \ingroup json | 
| 61 |     \ingroup shared | 
| 62 |     \reentrant | 
| 63 |     \since 5.0 | 
| 64 |  | 
| 65 |     \brief The QJsonObject class encapsulates a JSON object. | 
| 66 |  | 
| 67 |     A JSON object is a list of key value pairs, where the keys are unique strings | 
| 68 |     and the values are represented by a QJsonValue. | 
| 69 |  | 
| 70 |     A QJsonObject can be converted to and from a QVariantMap. You can query the | 
| 71 |     number of (key, value) pairs with size(), insert(), and remove() entries from it | 
| 72 |     and iterate over its content using the standard C++ iterator pattern. | 
| 73 |  | 
| 74 |     QJsonObject is an implicitly shared class, and shares the data with the document | 
| 75 |     it has been created from as long as it is not being modified. | 
| 76 |  | 
| 77 |     You can convert the object to and from text based JSON through QJsonDocument. | 
| 78 |  | 
| 79 |     \sa {JSON Support in Qt}, {JSON Save Game Example} | 
| 80 | */ | 
| 81 |  | 
| 82 | /*! | 
| 83 |     \typedef QJsonObject::Iterator | 
| 84 |  | 
| 85 |     Qt-style synonym for QJsonObject::iterator. | 
| 86 | */ | 
| 87 |  | 
| 88 | /*! | 
| 89 |     \typedef QJsonObject::ConstIterator | 
| 90 |  | 
| 91 |     Qt-style synonym for QJsonObject::const_iterator. | 
| 92 | */ | 
| 93 |  | 
| 94 | /*! | 
| 95 |     \typedef QJsonObject::key_type | 
| 96 |  | 
| 97 |     Typedef for QString. Provided for STL compatibility. | 
| 98 | */ | 
| 99 |  | 
| 100 | /*! | 
| 101 |     \typedef QJsonObject::mapped_type | 
| 102 |  | 
| 103 |     Typedef for QJsonValue. Provided for STL compatibility. | 
| 104 | */ | 
| 105 |  | 
| 106 | /*! | 
| 107 |     \typedef QJsonObject::size_type | 
| 108 |  | 
| 109 |     Typedef for qsizetype. Provided for STL compatibility. | 
| 110 | */ | 
| 111 |  | 
| 112 |  | 
| 113 | /*! | 
| 114 |     Constructs an empty JSON object. | 
| 115 |  | 
| 116 |     \sa isEmpty() | 
| 117 |  */ | 
| 118 | QJsonObject::QJsonObject() = default; | 
| 119 |  | 
| 120 | /*! | 
| 121 |     \fn QJsonObject::QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args) | 
| 122 |     \since 5.4 | 
| 123 |     Constructs a QJsonObject instance initialized from \a args initialization list. | 
| 124 |     For example: | 
| 125 |     \code | 
| 126 |     QJsonObject object | 
| 127 |     { | 
| 128 |         {"property1", 1}, | 
| 129 |         {"property2", 2} | 
| 130 |     }; | 
| 131 |     \endcode | 
| 132 | */ | 
| 133 |  | 
| 134 | /*! | 
| 135 |     \internal | 
| 136 |  */ | 
| 137 | QJsonObject::QJsonObject(QCborContainerPrivate *object) | 
| 138 |     : o(object) | 
| 139 | { | 
| 140 |     Q_ASSERT(o); | 
| 141 | } | 
| 142 |  | 
| 143 | /*! | 
| 144 |     Destroys the object. | 
| 145 |  */ | 
| 146 | QJsonObject::~QJsonObject() = default; | 
| 147 |  | 
| 148 | QJsonObject::QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args) | 
| 149 | { | 
| 150 |     for (const auto &arg : args) | 
| 151 |         insert(arg.first, arg.second); | 
| 152 | } | 
| 153 |  | 
| 154 | /*! | 
| 155 |     Creates a copy of \a other. | 
| 156 |  | 
| 157 |     Since QJsonObject is implicitly shared, the copy is shallow | 
| 158 |     as long as the object does not get modified. | 
| 159 |  */ | 
| 160 | QJsonObject::QJsonObject(const QJsonObject &other) | 
| 161 | { | 
| 162 |     o = other.o; | 
| 163 | } | 
| 164 |  | 
| 165 | QJsonObject::QJsonObject(QJsonObject &&other) noexcept | 
| 166 |     : o(other.o) | 
| 167 | { | 
| 168 |     other.o = nullptr; | 
| 169 | } | 
| 170 |  | 
| 171 | /*! | 
| 172 |     Assigns \a other to this object. | 
| 173 |  */ | 
| 174 | QJsonObject &QJsonObject::operator =(const QJsonObject &other) | 
| 175 | { | 
| 176 |     o = other.o; | 
| 177 |     return *this; | 
| 178 | } | 
| 179 |  | 
| 180 | /*! | 
| 181 |     \fn QJsonObject::QJsonObject(QJsonObject &&other) | 
| 182 |     \since 5.10 | 
| 183 |  | 
| 184 |     Move-constructs a QJsonObject from \a other. | 
| 185 | */ | 
| 186 |  | 
| 187 | /*! | 
| 188 |     \fn QJsonObject &QJsonObject::operator =(QJsonObject &&other) | 
| 189 |     \since 5.10 | 
| 190 |  | 
| 191 |     Move-assigns \a other to this object. | 
| 192 | */ | 
| 193 |  | 
| 194 | /*! | 
| 195 |     \fn void QJsonObject::swap(QJsonObject &other) | 
| 196 |     \since 5.10 | 
| 197 |  | 
| 198 |     Swaps the object \a other with this. This operation is very fast and never fails. | 
| 199 | */ | 
| 200 |  | 
| 201 |  | 
| 202 | /*! | 
| 203 |     Converts the variant map \a map to a QJsonObject. | 
| 204 |  | 
| 205 |     The keys in \a map will be used as the keys in the JSON object, | 
| 206 |     and the QVariant values will be converted to JSON values. | 
| 207 |  | 
| 208 |     \note Conversion from \l QVariant is not completely lossless. Please see | 
| 209 |     the documentation in QJsonValue::fromVariant() for more information. | 
| 210 |  | 
| 211 |     \sa fromVariantHash(), toVariantMap(), QJsonValue::fromVariant() | 
| 212 |  */ | 
| 213 | QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map) | 
| 214 | { | 
| 215 |     return QJsonPrivate::Variant::toJsonObject(map); | 
| 216 | } | 
| 217 |  | 
| 218 | /*! | 
| 219 |     Converts this object to a QVariantMap. | 
| 220 |  | 
| 221 |     Returns the created map. | 
| 222 |  | 
| 223 |     \sa toVariantHash() | 
| 224 |  */ | 
| 225 | QVariantMap QJsonObject::toVariantMap() const | 
| 226 | { | 
| 227 |     return QCborMap::fromJsonObject(*this).toVariantMap(); | 
| 228 | } | 
| 229 |  | 
| 230 | /*! | 
| 231 |     Converts the variant hash \a hash to a QJsonObject. | 
| 232 |     \since 5.5 | 
| 233 |  | 
| 234 |     The keys in \a hash will be used as the keys in the JSON object, | 
| 235 |     and the QVariant values will be converted to JSON values. | 
| 236 |  | 
| 237 |     \note Conversion from \l QVariant is not completely lossless. Please see | 
| 238 |     the documentation in QJsonValue::fromVariant() for more information. | 
| 239 |  | 
| 240 |     \sa fromVariantMap(), toVariantHash(), QJsonValue::fromVariant() | 
| 241 |  */ | 
| 242 | QJsonObject QJsonObject::fromVariantHash(const QVariantHash &hash) | 
| 243 | { | 
| 244 |     // ### this is implemented the trivial way, not the most efficient way | 
| 245 |  | 
| 246 |     QJsonObject object; | 
| 247 |     for (QVariantHash::const_iterator it = hash.constBegin(); it != hash.constEnd(); ++it) | 
| 248 |         object.insert(it.key(), QJsonValue::fromVariant(it.value())); | 
| 249 |     return object; | 
| 250 | } | 
| 251 |  | 
| 252 | /*! | 
| 253 |     Converts this object to a QVariantHash. | 
| 254 |     \since 5.5 | 
| 255 |  | 
| 256 |     Returns the created hash. | 
| 257 |  | 
| 258 |     \sa toVariantMap() | 
| 259 |  */ | 
| 260 | QVariantHash QJsonObject::toVariantHash() const | 
| 261 | { | 
| 262 |     return QCborMap::fromJsonObject(*this).toVariantHash(); | 
| 263 | } | 
| 264 |  | 
| 265 | /*! | 
| 266 |     Returns a list of all keys in this object. | 
| 267 |  | 
| 268 |     The list is sorted lexographically. | 
| 269 |  */ | 
| 270 | QStringList QJsonObject::keys() const | 
| 271 | { | 
| 272 |     QStringList keys; | 
| 273 |     if (o) { | 
| 274 |         keys.reserve(o->elements.length() / 2); | 
| 275 |         for (qsizetype i = 0, end = o->elements.length(); i < end; i += 2) | 
| 276 |             keys.append(o->stringAt(i)); | 
| 277 |     } | 
| 278 |     return keys; | 
| 279 | } | 
| 280 |  | 
| 281 | /*! | 
| 282 |     Returns the number of (key, value) pairs stored in the object. | 
| 283 |  */ | 
| 284 | qsizetype QJsonObject::size() const | 
| 285 | { | 
| 286 |     return o ? o->elements.length() / 2 : 0; | 
| 287 | } | 
| 288 |  | 
| 289 | /*! | 
| 290 |     Returns \c true if the object is empty. This is the same as size() == 0. | 
| 291 |  | 
| 292 |     \sa size() | 
| 293 |  */ | 
| 294 | bool QJsonObject::isEmpty() const | 
| 295 | { | 
| 296 |     return !o || o->elements.isEmpty(); | 
| 297 | } | 
| 298 |  | 
| 299 | template<typename String> | 
| 300 | static qsizetype indexOf(const QExplicitlySharedDataPointer<QCborContainerPrivate> &o, | 
| 301 |                          String key, bool *keyExists) | 
| 302 | { | 
| 303 |     const auto begin = QJsonPrivate::ConstKeyIterator(o->elements.constBegin()); | 
| 304 |     const auto end = QJsonPrivate::ConstKeyIterator(o->elements.constEnd()); | 
| 305 |  | 
| 306 |     const auto it = std::lower_bound( | 
| 307 |                 begin, end, key, | 
| 308 |                 [&](const QJsonPrivate::ConstKeyIterator::value_type &e, const String &key) { | 
| 309 |         return o->stringCompareElement(e.key(), key) < 0; | 
| 310 |     }); | 
| 311 |  | 
| 312 |     *keyExists = (it != end) && o->stringEqualsElement((*it).key(), key); | 
| 313 |     return (it - begin) * 2; | 
| 314 | } | 
| 315 |  | 
| 316 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 317 | /*! | 
| 318 |     Returns a QJsonValue representing the value for the key \a key. | 
| 319 |  | 
| 320 |     The returned QJsonValue is QJsonValue::Undefined if the key does not exist. | 
| 321 |  | 
| 322 |     \sa QJsonValue, QJsonValue::isUndefined() | 
| 323 |  */ | 
| 324 | QJsonValue QJsonObject::value(const QString &key) const | 
| 325 | { | 
| 326 |     return value(QStringView(key)); | 
| 327 | } | 
| 328 | #endif | 
| 329 |  | 
| 330 | /*! | 
| 331 |     \overload | 
| 332 |     \since 5.14 | 
| 333 | */ | 
| 334 | QJsonValue QJsonObject::value(QStringView key) const | 
| 335 | { | 
| 336 |     return valueImpl(key); | 
| 337 | } | 
| 338 |  | 
| 339 | /*! | 
| 340 |     \overload | 
| 341 |     \since 5.7 | 
| 342 | */ | 
| 343 | QJsonValue QJsonObject::value(QLatin1String key) const | 
| 344 | { | 
| 345 |     return valueImpl(key); | 
| 346 | } | 
| 347 |  | 
| 348 | /*! | 
| 349 |     \internal | 
| 350 | */ | 
| 351 | template <typename T> | 
| 352 | QJsonValue QJsonObject::valueImpl(T key) const | 
| 353 | { | 
| 354 |     if (!o) | 
| 355 |         return QJsonValue(QJsonValue::Undefined); | 
| 356 |  | 
| 357 |     bool keyExists; | 
| 358 |     auto i = indexOf(o, key, &keyExists); | 
| 359 |     if (!keyExists) | 
| 360 |         return QJsonValue(QJsonValue::Undefined); | 
| 361 |     return QJsonPrivate::Value::fromTrustedCbor(o->valueAt(i + 1)); | 
| 362 | } | 
| 363 |  | 
| 364 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 365 | /*! | 
| 366 |     Returns a QJsonValue representing the value for the key \a key. | 
| 367 |  | 
| 368 |     This does the same as value(). | 
| 369 |  | 
| 370 |     The returned QJsonValue is QJsonValue::Undefined if the key does not exist. | 
| 371 |  | 
| 372 |     \sa value(), QJsonValue, QJsonValue::isUndefined() | 
| 373 |  */ | 
| 374 | QJsonValue QJsonObject::operator [](const QString &key) const | 
| 375 | { | 
| 376 |     return (*this)[QStringView(key)]; | 
| 377 | } | 
| 378 | #endif | 
| 379 |  | 
| 380 | /*! | 
| 381 |     \fn QJsonValue QJsonObject::operator [](QStringView key) const | 
| 382 |  | 
| 383 |     \overload | 
| 384 |     \since 5.14 | 
| 385 | */ | 
| 386 |  | 
| 387 | /*! | 
| 388 |     \fn QJsonValue QJsonObject::operator [](QLatin1String key) const | 
| 389 |  | 
| 390 |     \overload | 
| 391 |     \since 5.7 | 
| 392 | */ | 
| 393 |  | 
| 394 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 395 | /*! | 
| 396 |     Returns a reference to the value for \a key. If there is no value with key | 
| 397 |     \a key in the object, one is created with a QJsonValue::Null value and then | 
| 398 |     returned. | 
| 399 |  | 
| 400 |     The return value is of type QJsonValueRef, a helper class for QJsonArray | 
| 401 |     and QJsonObject. When you get an object of type QJsonValueRef, you can | 
| 402 |     use it as if it were a reference to a QJsonValue. If you assign to it, | 
| 403 |     the assignment will apply to the element in the QJsonArray or QJsonObject | 
| 404 |     from which you got the reference. | 
| 405 |  | 
| 406 |     \sa value() | 
| 407 |  */ | 
| 408 | QJsonValueRef QJsonObject::operator [](const QString &key) | 
| 409 | { | 
| 410 |     return (*this)[QStringView(key)]; | 
| 411 | } | 
| 412 | #endif | 
| 413 |  | 
| 414 | /*! | 
| 415 |     \overload | 
| 416 |     \since 5.14 | 
| 417 | */ | 
| 418 | QJsonValueRef QJsonObject::operator [](QStringView key) | 
| 419 | { | 
| 420 |     return atImpl(key); | 
| 421 | } | 
| 422 |  | 
| 423 | /*! | 
| 424 |     \overload | 
| 425 |     \since 5.7 | 
| 426 | */ | 
| 427 | QJsonValueRef QJsonObject::operator [](QLatin1String key) | 
| 428 | { | 
| 429 |     return atImpl(key); | 
| 430 | } | 
| 431 |  | 
| 432 | /*! | 
| 433 |     \internal | 
| 434 | */ | 
| 435 | template <typename T> | 
| 436 | QJsonValueRef QJsonObject::atImpl(T key) | 
| 437 | { | 
| 438 |     if (!o) | 
| 439 |         o = new QCborContainerPrivate; | 
| 440 |  | 
| 441 |     bool keyExists = false; | 
| 442 |     auto index = indexOf(o, key, &keyExists); | 
| 443 |     if (!keyExists) { | 
| 444 |         detach(o->elements.length() / 2 + 1); | 
| 445 |         o->insertAt(index, key); | 
| 446 |         o->insertAt(index + 1, QCborValue::fromJsonValue(QJsonValue())); | 
| 447 |     } | 
| 448 |     // detaching will happen if and when this QJsonValueRef is assigned to | 
| 449 |     return QJsonValueRef(this, index / 2); | 
| 450 | } | 
| 451 |  | 
| 452 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 453 | /*! | 
| 454 |     Inserts a new item with the key \a key and a value of \a value. | 
| 455 |  | 
| 456 |     If there is already an item with the key \a key, then that item's value | 
| 457 |     is replaced with \a value. | 
| 458 |  | 
| 459 |     Returns an iterator pointing to the inserted item. | 
| 460 |  | 
| 461 |     If the value is QJsonValue::Undefined, it will cause the key to get removed | 
| 462 |     from the object. The returned iterator will then point to end(). | 
| 463 |  | 
| 464 |     \sa remove(), take(), QJsonObject::iterator, end() | 
| 465 |  */ | 
| 466 | QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &value) | 
| 467 | { | 
| 468 |     return insert(QStringView(key), value); | 
| 469 | } | 
| 470 | #endif | 
| 471 |  | 
| 472 | /*! | 
| 473 |     \overload | 
| 474 |     \since 5.14 | 
| 475 | */ | 
| 476 | QJsonObject::iterator QJsonObject::insert(QStringView key, const QJsonValue &value) | 
| 477 | { | 
| 478 |     return insertImpl(key, value); | 
| 479 | } | 
| 480 |  | 
| 481 | /*! | 
| 482 |     \overload | 
| 483 |     \since 5.14 | 
| 484 | */ | 
| 485 | QJsonObject::iterator QJsonObject::insert(QLatin1String key, const QJsonValue &value) | 
| 486 | { | 
| 487 |     return insertImpl(key, value); | 
| 488 | } | 
| 489 |  | 
| 490 | /*! | 
| 491 |     \internal | 
| 492 | */ | 
| 493 | template <typename T> | 
| 494 | QJsonObject::iterator QJsonObject::insertImpl(T key, const QJsonValue &value) | 
| 495 | { | 
| 496 |     if (value.type() == QJsonValue::Undefined) { | 
| 497 |         remove(key); | 
| 498 |         return end(); | 
| 499 |     } | 
| 500 |     bool keyExists = false; | 
| 501 |     auto pos = o ? indexOf(o, key, &keyExists) : 0; | 
| 502 |     return insertAt(pos, key, value, keyExists); | 
| 503 | } | 
| 504 |  | 
| 505 | /*! | 
| 506 |     \internal | 
| 507 |  */ | 
| 508 | template <typename T> | 
| 509 | QJsonObject::iterator QJsonObject::insertAt(qsizetype pos, T key, const QJsonValue &value, bool keyExists) | 
| 510 | { | 
| 511 |     if (o) | 
| 512 |         detach(o->elements.length() / 2 + (keyExists ? 0 : 1)); | 
| 513 |     else | 
| 514 |         o = new QCborContainerPrivate; | 
| 515 |  | 
| 516 |     if (keyExists) { | 
| 517 |         o->replaceAt(pos + 1, QCborValue::fromJsonValue(value)); | 
| 518 |     } else { | 
| 519 |         o->insertAt(pos, key); | 
| 520 |         o->insertAt(pos + 1, QCborValue::fromJsonValue(value)); | 
| 521 |     } | 
| 522 |     return {this, pos / 2}; | 
| 523 | } | 
| 524 |  | 
| 525 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 526 | /*! | 
| 527 |     Removes \a key from the object. | 
| 528 |  | 
| 529 |     \sa insert(), take() | 
| 530 |  */ | 
| 531 | void QJsonObject::remove(const QString &key) | 
| 532 | { | 
| 533 |     remove(QStringView(key)); | 
| 534 | } | 
| 535 | #endif | 
| 536 |  | 
| 537 | /*! | 
| 538 |     \overload | 
| 539 |     \since 5.14 | 
| 540 | */ | 
| 541 | void QJsonObject::remove(QStringView key) | 
| 542 | { | 
| 543 |     removeImpl(key); | 
| 544 | } | 
| 545 |  | 
| 546 | /*! | 
| 547 |     \overload | 
| 548 |     \since 5.14 | 
| 549 | */ | 
| 550 | void QJsonObject::remove(QLatin1String key) | 
| 551 | { | 
| 552 |     removeImpl(key); | 
| 553 | } | 
| 554 |  | 
| 555 | /*! | 
| 556 |     \internal | 
| 557 | */ | 
| 558 | template <typename T> | 
| 559 | void QJsonObject::removeImpl(T key) | 
| 560 | { | 
| 561 |     if (!o) | 
| 562 |         return; | 
| 563 |  | 
| 564 |     bool keyExists; | 
| 565 |     auto index = indexOf(o, key, &keyExists); | 
| 566 |     if (!keyExists) | 
| 567 |         return; | 
| 568 |  | 
| 569 |     removeAt(index / 2); | 
| 570 | } | 
| 571 |  | 
| 572 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 573 | /*! | 
| 574 |     Removes \a key from the object. | 
| 575 |  | 
| 576 |     Returns a QJsonValue containing the value referenced by \a key. | 
| 577 |     If \a key was not contained in the object, the returned QJsonValue | 
| 578 |     is QJsonValue::Undefined. | 
| 579 |  | 
| 580 |     \sa insert(), remove(), QJsonValue | 
| 581 |  */ | 
| 582 | QJsonValue QJsonObject::take(const QString &key) | 
| 583 | { | 
| 584 |     return take(QStringView(key)); | 
| 585 | } | 
| 586 | #endif | 
| 587 |  | 
| 588 | /*! | 
| 589 |     \overload | 
| 590 |     \since 5.14 | 
| 591 | */ | 
| 592 | QJsonValue QJsonObject::take(QStringView key) | 
| 593 | { | 
| 594 |     return takeImpl(key); | 
| 595 | } | 
| 596 |  | 
| 597 | /*! | 
| 598 |     \overload | 
| 599 |     \since 5.14 | 
| 600 | */ | 
| 601 | QJsonValue QJsonObject::take(QLatin1String key) | 
| 602 | { | 
| 603 |     return takeImpl(key); | 
| 604 | } | 
| 605 |  | 
| 606 | /*! | 
| 607 |     \internal | 
| 608 | */ | 
| 609 | template <typename T> | 
| 610 | QJsonValue QJsonObject::takeImpl(T key) | 
| 611 | { | 
| 612 |     if (!o) | 
| 613 |         return QJsonValue(QJsonValue::Undefined); | 
| 614 |  | 
| 615 |     bool keyExists; | 
| 616 |     auto index = indexOf(o, key, &keyExists); | 
| 617 |     if (!keyExists) | 
| 618 |         return QJsonValue(QJsonValue::Undefined); | 
| 619 |  | 
| 620 |     const QJsonValue v = QJsonPrivate::Value::fromTrustedCbor(o->extractAt(index + 1)); | 
| 621 |     removeAt(index / 2); | 
| 622 |     return v; | 
| 623 | } | 
| 624 |  | 
| 625 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 626 | /*! | 
| 627 |     Returns \c true if the object contains key \a key. | 
| 628 |  | 
| 629 |     \sa insert(), remove(), take() | 
| 630 |  */ | 
| 631 | bool QJsonObject::contains(const QString &key) const | 
| 632 | { | 
| 633 |     return contains(QStringView(key)); | 
| 634 | } | 
| 635 | #endif | 
| 636 |  | 
| 637 | /*! | 
| 638 |     \overload | 
| 639 |     \since 5.14 | 
| 640 | */ | 
| 641 | bool QJsonObject::contains(QStringView key) const | 
| 642 | { | 
| 643 |     return containsImpl(key); | 
| 644 | } | 
| 645 |  | 
| 646 | /*! | 
| 647 |     \overload | 
| 648 |     \since 5.7 | 
| 649 | */ | 
| 650 | bool QJsonObject::contains(QLatin1String key) const | 
| 651 | { | 
| 652 |     return containsImpl(key); | 
| 653 | } | 
| 654 |  | 
| 655 | /*! | 
| 656 |     \internal | 
| 657 | */ | 
| 658 | template <typename T> | 
| 659 | bool QJsonObject::containsImpl(T key) const | 
| 660 | { | 
| 661 |     if (!o) | 
| 662 |         return false; | 
| 663 |  | 
| 664 |     bool keyExists; | 
| 665 |     indexOf(o, key, &keyExists); | 
| 666 |     return keyExists; | 
| 667 | } | 
| 668 |  | 
| 669 | /*! | 
| 670 |     Returns \c true if \a other is equal to this object. | 
| 671 |  */ | 
| 672 | bool QJsonObject::operator==(const QJsonObject &other) const | 
| 673 | { | 
| 674 |     if (o == other.o) | 
| 675 |         return true; | 
| 676 |  | 
| 677 |     if (!o) | 
| 678 |         return !other.o->elements.length(); | 
| 679 |     if (!other.o) | 
| 680 |         return !o->elements.length(); | 
| 681 |     if (o->elements.length() != other.o->elements.length()) | 
| 682 |         return false; | 
| 683 |  | 
| 684 |     for (qsizetype i = 0, end = o->elements.length(); i < end; ++i) { | 
| 685 |         if (o->valueAt(i) != other.o->valueAt(i)) | 
| 686 |             return false; | 
| 687 |     } | 
| 688 |  | 
| 689 |     return true; | 
| 690 | } | 
| 691 |  | 
| 692 | /*! | 
| 693 |     Returns \c true if \a other is not equal to this object. | 
| 694 |  */ | 
| 695 | bool QJsonObject::operator!=(const QJsonObject &other) const | 
| 696 | { | 
| 697 |     return !(*this == other); | 
| 698 | } | 
| 699 |  | 
| 700 | /*! | 
| 701 |     Removes the (key, value) pair pointed to by the iterator \a it | 
| 702 |     from the map, and returns an iterator to the next item in the | 
| 703 |     map. | 
| 704 |  | 
| 705 |     \sa remove() | 
| 706 |  */ | 
| 707 | QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it) | 
| 708 | { | 
| 709 |     if (it.item.o != this || qsizetype(it.item.index) >= o->elements.length()) | 
| 710 |         return {this, o->elements.length()}; | 
| 711 |  | 
| 712 |     removeAt(it.item.index); | 
| 713 |  | 
| 714 |     // iterator hasn't changed | 
| 715 |     return it; | 
| 716 | } | 
| 717 |  | 
| 718 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 719 | /*! | 
| 720 |     Returns an iterator pointing to the item with key \a key in the | 
| 721 |     map. | 
| 722 |  | 
| 723 |     If the map contains no item with key \a key, the function | 
| 724 |     returns end(). | 
| 725 |  */ | 
| 726 | QJsonObject::iterator QJsonObject::find(const QString &key) | 
| 727 | { | 
| 728 |     return find(QStringView(key)); | 
| 729 | } | 
| 730 | #endif | 
| 731 |  | 
| 732 | /*! | 
| 733 |     \overload | 
| 734 |     \since 5.14 | 
| 735 | */ | 
| 736 | QJsonObject::iterator QJsonObject::find(QStringView key) | 
| 737 | { | 
| 738 |     return findImpl(key); | 
| 739 | } | 
| 740 |  | 
| 741 | /*! | 
| 742 |     \overload | 
| 743 |     \since 5.7 | 
| 744 | */ | 
| 745 | QJsonObject::iterator QJsonObject::find(QLatin1String key) | 
| 746 | { | 
| 747 |     return findImpl(key); | 
| 748 | } | 
| 749 |  | 
| 750 | /*! | 
| 751 |     \internal | 
| 752 | */ | 
| 753 | template <typename T> | 
| 754 | QJsonObject::iterator QJsonObject::findImpl(T key) | 
| 755 | { | 
| 756 |     bool keyExists = false; | 
| 757 |     auto index = o ? indexOf(o, key, &keyExists) : 0; | 
| 758 |     if (!keyExists) | 
| 759 |         return end(); | 
| 760 |     detach(); | 
| 761 |     return {this, index / 2}; | 
| 762 | } | 
| 763 |  | 
| 764 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 765 | /*! \fn QJsonObject::const_iterator QJsonObject::find(const QString &key) const | 
| 766 |  | 
| 767 |     \overload | 
| 768 | */ | 
| 769 | #endif | 
| 770 |  | 
| 771 | /*! \fn QJsonObject::const_iterator QJsonObject::find(QStringView key) const | 
| 772 |  | 
| 773 |     \overload | 
| 774 |     \since 5.14 | 
| 775 | */ | 
| 776 |  | 
| 777 | /*! \fn QJsonObject::const_iterator QJsonObject::find(QLatin1String key) const | 
| 778 |  | 
| 779 |     \overload | 
| 780 |     \since 5.7 | 
| 781 | */ | 
| 782 |  | 
| 783 | #if QT_STRINGVIEW_LEVEL < 2 | 
| 784 | /*! | 
| 785 |     Returns a const iterator pointing to the item with key \a key in the | 
| 786 |     map. | 
| 787 |  | 
| 788 |     If the map contains no item with key \a key, the function | 
| 789 |     returns constEnd(). | 
| 790 |  */ | 
| 791 | QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const | 
| 792 | { | 
| 793 |     return constFind(QStringView(key)); | 
| 794 | } | 
| 795 | #endif | 
| 796 |  | 
| 797 | /*! | 
| 798 |     \overload | 
| 799 |     \since 5.14 | 
| 800 | */ | 
| 801 | QJsonObject::const_iterator QJsonObject::constFind(QStringView key) const | 
| 802 | { | 
| 803 |     return constFindImpl(key); | 
| 804 | } | 
| 805 |  | 
| 806 | /*! | 
| 807 |     \overload | 
| 808 |     \since 5.7 | 
| 809 | */ | 
| 810 | QJsonObject::const_iterator QJsonObject::constFind(QLatin1String key) const | 
| 811 | { | 
| 812 |     return constFindImpl(key); | 
| 813 | } | 
| 814 |  | 
| 815 | /*! | 
| 816 |     \internal | 
| 817 | */ | 
| 818 | template <typename T> | 
| 819 | QJsonObject::const_iterator QJsonObject::constFindImpl(T key) const | 
| 820 | { | 
| 821 |     bool keyExists = false; | 
| 822 |     auto index = o ? indexOf(o, key, &keyExists) : 0; | 
| 823 |     if (!keyExists) | 
| 824 |         return end(); | 
| 825 |     return {this, index / 2}; | 
| 826 | } | 
| 827 |  | 
| 828 | /*! \fn qsizetype QJsonObject::count() const | 
| 829 |  | 
| 830 |     \overload | 
| 831 |  | 
| 832 |     Same as size(). | 
| 833 | */ | 
| 834 |  | 
| 835 | /*! \fn qsizetype QJsonObject::length() const | 
| 836 |  | 
| 837 |     \overload | 
| 838 |  | 
| 839 |     Same as size(). | 
| 840 | */ | 
| 841 |  | 
| 842 | /*! \fn QJsonObject::iterator QJsonObject::begin() | 
| 843 |  | 
| 844 |     Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in | 
| 845 |     the object. | 
| 846 |  | 
| 847 |     \sa constBegin(), end() | 
| 848 | */ | 
| 849 |  | 
| 850 | /*! \fn QJsonObject::const_iterator QJsonObject::begin() const | 
| 851 |  | 
| 852 |     \overload | 
| 853 | */ | 
| 854 |  | 
| 855 | /*! \fn QJsonObject::const_iterator QJsonObject::constBegin() const | 
| 856 |  | 
| 857 |     Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item | 
| 858 |     in the object. | 
| 859 |  | 
| 860 |     \sa begin(), constEnd() | 
| 861 | */ | 
| 862 |  | 
| 863 | /*! \fn QJsonObject::iterator QJsonObject::end() | 
| 864 |  | 
| 865 |     Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item | 
| 866 |     after the last item in the object. | 
| 867 |  | 
| 868 |     \sa begin(), constEnd() | 
| 869 | */ | 
| 870 |  | 
| 871 | /*! \fn QJsonObject::const_iterator QJsonObject::end() const | 
| 872 |  | 
| 873 |     \overload | 
| 874 | */ | 
| 875 |  | 
| 876 | /*! \fn QJsonObject::const_iterator QJsonObject::constEnd() const | 
| 877 |  | 
| 878 |     Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary | 
| 879 |     item after the last item in the object. | 
| 880 |  | 
| 881 |     \sa constBegin(), end() | 
| 882 | */ | 
| 883 |  | 
| 884 | /*! | 
| 885 |     \fn bool QJsonObject::empty() const | 
| 886 |  | 
| 887 |     This function is provided for STL compatibility. It is equivalent | 
| 888 |     to isEmpty(), returning \c true if the object is empty; otherwise | 
| 889 |     returning \c false. | 
| 890 | */ | 
| 891 |  | 
| 892 | /*! \class QJsonObject::iterator | 
| 893 |     \inmodule QtCore | 
| 894 |     \ingroup json | 
| 895 |     \reentrant | 
| 896 |     \since 5.0 | 
| 897 |  | 
| 898 |     \brief The QJsonObject::iterator class provides an STL-style non-const iterator for QJsonObject. | 
| 899 |  | 
| 900 |     QJsonObject::iterator allows you to iterate over a QJsonObject | 
| 901 |     and to modify the value (but not the key) stored under | 
| 902 |     a particular key. If you want to iterate over a const QJsonObject, you | 
| 903 |     should use QJsonObject::const_iterator. It is generally good practice to | 
| 904 |     use QJsonObject::const_iterator on a non-const QJsonObject as well, unless you | 
| 905 |     need to change the QJsonObject through the iterator. Const iterators are | 
| 906 |     slightly faster, and improve code readability. | 
| 907 |  | 
| 908 |     The default QJsonObject::iterator constructor creates an uninitialized | 
| 909 |     iterator. You must initialize it using a QJsonObject function like | 
| 910 |     QJsonObject::begin(), QJsonObject::end(), or QJsonObject::find() before you can | 
| 911 |     start iterating. | 
| 912 |  | 
| 913 |     Multiple iterators can be used on the same object. Existing iterators will however | 
| 914 |     become dangling once the object gets modified. | 
| 915 |  | 
| 916 |     \sa QJsonObject::const_iterator, {JSON Support in Qt}, {JSON Save Game Example} | 
| 917 | */ | 
| 918 |  | 
| 919 | /*! \typedef QJsonObject::iterator::difference_type | 
| 920 |  | 
| 921 |     \internal | 
| 922 | */ | 
| 923 |  | 
| 924 | /*! \typedef QJsonObject::iterator::iterator_category | 
| 925 |  | 
| 926 |     A synonym for \e {std::random_access_iterator_tag} indicating | 
| 927 |     this iterator is a random-access iterator. | 
| 928 |  | 
| 929 |     \note In Qt versions before 5.6, this was set by mistake to | 
| 930 |     \e {std::bidirectional_iterator_tag}. | 
| 931 | */ | 
| 932 |  | 
| 933 | /*! \typedef QJsonObject::iterator::reference | 
| 934 |  | 
| 935 |     \internal | 
| 936 | */ | 
| 937 |  | 
| 938 | /*! \typedef QJsonObject::iterator::value_type | 
| 939 |  | 
| 940 |     \internal | 
| 941 | */ | 
| 942 |  | 
| 943 | /*! \typedef QJsonObject::iterator::pointer | 
| 944 |  | 
| 945 |     \internal | 
| 946 | */ | 
| 947 |  | 
| 948 | /*! \fn QJsonObject::iterator::iterator() | 
| 949 |  | 
| 950 |     Constructs an uninitialized iterator. | 
| 951 |  | 
| 952 |     Functions like key(), value(), and operator++() must not be | 
| 953 |     called on an uninitialized iterator. Use operator=() to assign a | 
| 954 |     value to it before using it. | 
| 955 |  | 
| 956 |     \sa QJsonObject::begin(), QJsonObject::end() | 
| 957 | */ | 
| 958 |  | 
| 959 | /*! \fn QJsonObject::iterator::iterator(QJsonObject *obj, qsizetype index) | 
| 960 |     \internal | 
| 961 | */ | 
| 962 |  | 
| 963 | /*! \fn QString QJsonObject::iterator::key() const | 
| 964 |  | 
| 965 |     Returns the current item's key. | 
| 966 |  | 
| 967 |     There is no direct way of changing an item's key through an | 
| 968 |     iterator, although it can be done by calling QJsonObject::erase() | 
| 969 |     followed by QJsonObject::insert(). | 
| 970 |  | 
| 971 |     \sa value() | 
| 972 | */ | 
| 973 |  | 
| 974 | /*! \fn QJsonValueRef QJsonObject::iterator::value() const | 
| 975 |  | 
| 976 |     Returns a modifiable reference to the current item's value. | 
| 977 |  | 
| 978 |     You can change the value of an item by using value() on | 
| 979 |     the left side of an assignment. | 
| 980 |  | 
| 981 |     The return value is of type QJsonValueRef, a helper class for QJsonArray | 
| 982 |     and QJsonObject. When you get an object of type QJsonValueRef, you can | 
| 983 |     use it as if it were a reference to a QJsonValue. If you assign to it, | 
| 984 |     the assignment will apply to the element in the QJsonArray or QJsonObject | 
| 985 |     from which you got the reference. | 
| 986 |  | 
| 987 |     \sa key(), operator*() | 
| 988 | */ | 
| 989 |  | 
| 990 | /*! \fn QJsonValueRef QJsonObject::iterator::operator*() const | 
| 991 |  | 
| 992 |     Returns a modifiable reference to the current item's value. | 
| 993 |  | 
| 994 |     Same as value(). | 
| 995 |  | 
| 996 |     The return value is of type QJsonValueRef, a helper class for QJsonArray | 
| 997 |     and QJsonObject. When you get an object of type QJsonValueRef, you can | 
| 998 |     use it as if it were a reference to a QJsonValue. If you assign to it, | 
| 999 |     the assignment will apply to the element in the QJsonArray or QJsonObject | 
| 1000 |     from which you got the reference. | 
| 1001 |  | 
| 1002 |     \sa key() | 
| 1003 | */ | 
| 1004 |  | 
| 1005 | /*! \fn QJsonValueRef *QJsonObject::iterator::operator->() const | 
| 1006 |  | 
| 1007 |     Returns a pointer to a modifiable reference to the current item. | 
| 1008 | */ | 
| 1009 |  | 
| 1010 | /*! \fn const QJsonValueRef QJsonObject::iterator::operator[](qsizetype j) | 
| 1011 |  | 
| 1012 |     Returns a modifiable reference to the item at offset \a j from the | 
| 1013 |     item pointed to by this iterator (the item at position \c{*this + j}). | 
| 1014 |  | 
| 1015 |     This function is provided to make QJsonObject iterators behave like C++ | 
| 1016 |     pointers. | 
| 1017 |  | 
| 1018 |     The return value is of type QJsonValueRef, a helper class for QJsonArray | 
| 1019 |     and QJsonObject. When you get an object of type QJsonValueRef, you can | 
| 1020 |     use it as if it were a reference to a QJsonValue. If you assign to it, | 
| 1021 |     the assignment will apply to the element in the QJsonArray or QJsonObject | 
| 1022 |     from which you got the reference. | 
| 1023 |  | 
| 1024 |     \sa operator+() | 
| 1025 | */ | 
| 1026 |  | 
| 1027 | /*! | 
| 1028 |     \fn bool QJsonObject::iterator::operator==(const iterator &other) const | 
| 1029 |     \fn bool QJsonObject::iterator::operator==(const const_iterator &other) const | 
| 1030 |  | 
| 1031 |     Returns \c true if \a other points to the same item as this | 
| 1032 |     iterator; otherwise returns \c false. | 
| 1033 |  | 
| 1034 |     \sa operator!=() | 
| 1035 | */ | 
| 1036 |  | 
| 1037 | /*! | 
| 1038 |     \fn bool QJsonObject::iterator::operator!=(const iterator &other) const | 
| 1039 |     \fn bool QJsonObject::iterator::operator!=(const const_iterator &other) const | 
| 1040 |  | 
| 1041 |     Returns \c true if \a other points to a different item than this | 
| 1042 |     iterator; otherwise returns \c false. | 
| 1043 |  | 
| 1044 |     \sa operator==() | 
| 1045 | */ | 
| 1046 |  | 
| 1047 | /*! | 
| 1048 |     \fn bool QJsonObject::iterator::operator<(const iterator& other) const | 
| 1049 |     \fn bool QJsonObject::iterator::operator<(const const_iterator& other) const | 
| 1050 |  | 
| 1051 |     Returns \c true if the item pointed to by this iterator is less than | 
| 1052 |     the item pointed to by the \a other iterator. | 
| 1053 | */ | 
| 1054 |  | 
| 1055 | /*! | 
| 1056 |     \fn bool QJsonObject::iterator::operator<=(const iterator& other) const | 
| 1057 |     \fn bool QJsonObject::iterator::operator<=(const const_iterator& other) const | 
| 1058 |  | 
| 1059 |     Returns \c true if the item pointed to by this iterator is less than | 
| 1060 |     or equal to the item pointed to by the \a other iterator. | 
| 1061 | */ | 
| 1062 |  | 
| 1063 | /*! | 
| 1064 |     \fn bool QJsonObject::iterator::operator>(const iterator& other) const | 
| 1065 |     \fn bool QJsonObject::iterator::operator>(const const_iterator& other) const | 
| 1066 |  | 
| 1067 |     Returns \c true if the item pointed to by this iterator is greater | 
| 1068 |     than the item pointed to by the \a other iterator. | 
| 1069 | */ | 
| 1070 |  | 
| 1071 | /*! | 
| 1072 |     \fn bool QJsonObject::iterator::operator>=(const iterator& other) const | 
| 1073 |     \fn bool QJsonObject::iterator::operator>=(const const_iterator& other) const | 
| 1074 |  | 
| 1075 |     Returns \c true if the item pointed to by this iterator is greater | 
| 1076 |     than or equal to the item pointed to by the \a other iterator. | 
| 1077 | */ | 
| 1078 |  | 
| 1079 | /*! \fn QJsonObject::iterator QJsonObject::iterator::operator++() | 
| 1080 |  | 
| 1081 |     The prefix ++ operator, \c{++i}, advances the iterator to the | 
| 1082 |     next item in the object and returns an iterator to the new current | 
| 1083 |     item. | 
| 1084 |  | 
| 1085 |     Calling this function on QJsonObject::end() leads to undefined results. | 
| 1086 |  | 
| 1087 |     \sa operator--() | 
| 1088 | */ | 
| 1089 |  | 
| 1090 | /*! \fn QJsonObject::iterator QJsonObject::iterator::operator++(int) | 
| 1091 |  | 
| 1092 |     \overload | 
| 1093 |  | 
| 1094 |     The postfix ++ operator, \c{i++}, advances the iterator to the | 
| 1095 |     next item in the object and returns an iterator to the previously | 
| 1096 |     current item. | 
| 1097 | */ | 
| 1098 |  | 
| 1099 | /*! \fn QJsonObject::iterator QJsonObject::iterator::operator--() | 
| 1100 |  | 
| 1101 |     The prefix -- operator, \c{--i}, makes the preceding item | 
| 1102 |     current and returns an iterator pointing to the new current item. | 
| 1103 |  | 
| 1104 |     Calling this function on QJsonObject::begin() leads to undefined | 
| 1105 |     results. | 
| 1106 |  | 
| 1107 |     \sa operator++() | 
| 1108 | */ | 
| 1109 |  | 
| 1110 | /*! \fn QJsonObject::iterator QJsonObject::iterator::operator--(int) | 
| 1111 |  | 
| 1112 |     \overload | 
| 1113 |  | 
| 1114 |     The postfix -- operator, \c{i--}, makes the preceding item | 
| 1115 |     current and returns an iterator pointing to the previously | 
| 1116 |     current item. | 
| 1117 | */ | 
| 1118 |  | 
| 1119 | /*! \fn QJsonObject::iterator QJsonObject::iterator::operator+(qsizetype j) const | 
| 1120 |  | 
| 1121 |     Returns an iterator to the item at \a j positions forward from | 
| 1122 |     this iterator. If \a j is negative, the iterator goes backward. | 
| 1123 |  | 
| 1124 |     \sa operator-() | 
| 1125 |  | 
| 1126 | */ | 
| 1127 |  | 
| 1128 | /*! \fn QJsonObject::iterator QJsonObject::iterator::operator-(qsizetype j) const | 
| 1129 |  | 
| 1130 |     Returns an iterator to the item at \a j positions backward from | 
| 1131 |     this iterator. If \a j is negative, the iterator goes forward. | 
| 1132 |  | 
| 1133 |     \sa operator+() | 
| 1134 | */ | 
| 1135 |  | 
| 1136 | /*! \fn QJsonObject::iterator &QJsonObject::iterator::operator+=(qsizetype j) | 
| 1137 |  | 
| 1138 |     Advances the iterator by \a j items. If \a j is negative, the | 
| 1139 |     iterator goes backward. | 
| 1140 |  | 
| 1141 |     \sa operator-=(), operator+() | 
| 1142 | */ | 
| 1143 |  | 
| 1144 | /*! \fn QJsonObject::iterator &QJsonObject::iterator::operator-=(qsizetype j) | 
| 1145 |  | 
| 1146 |     Makes the iterator go back by \a j items. If \a j is negative, | 
| 1147 |     the iterator goes forward. | 
| 1148 |  | 
| 1149 |     \sa operator+=(), operator-() | 
| 1150 | */ | 
| 1151 |  | 
| 1152 | /*! \fn qsizetype QJsonObject::iterator::operator-(iterator other) const | 
| 1153 |  | 
| 1154 |     Returns the number of items between the item pointed to by \a | 
| 1155 |     other and the item pointed to by this iterator. | 
| 1156 | */ | 
| 1157 |  | 
| 1158 | /*! | 
| 1159 |     \class QJsonObject::const_iterator | 
| 1160 |     \inmodule QtCore | 
| 1161 |     \ingroup json | 
| 1162 |     \since 5.0 | 
| 1163 |     \brief The QJsonObject::const_iterator class provides an STL-style const iterator for QJsonObject. | 
| 1164 |  | 
| 1165 |     QJsonObject::const_iterator allows you to iterate over a QJsonObject. | 
| 1166 |     If you want to modify the QJsonObject as you iterate | 
| 1167 |     over it, you must use QJsonObject::iterator instead. It is generally | 
| 1168 |     good practice to use QJsonObject::const_iterator on a non-const QJsonObject as | 
| 1169 |     well, unless you need to change the QJsonObject through the iterator. | 
| 1170 |     Const iterators are slightly faster and improve code | 
| 1171 |     readability. | 
| 1172 |  | 
| 1173 |     The default QJsonObject::const_iterator constructor creates an | 
| 1174 |     uninitialized iterator. You must initialize it using a QJsonObject | 
| 1175 |     function like QJsonObject::constBegin(), QJsonObject::constEnd(), or | 
| 1176 |     QJsonObject::find() before you can start iterating. | 
| 1177 |  | 
| 1178 |     Multiple iterators can be used on the same object. Existing iterators | 
| 1179 |     will however become dangling if the object gets modified. | 
| 1180 |  | 
| 1181 |     \sa QJsonObject::iterator, {JSON Support in Qt}, {JSON Save Game Example} | 
| 1182 | */ | 
| 1183 |  | 
| 1184 | /*! \typedef QJsonObject::const_iterator::difference_type | 
| 1185 |  | 
| 1186 |     \internal | 
| 1187 | */ | 
| 1188 |  | 
| 1189 | /*! \typedef QJsonObject::const_iterator::iterator_category | 
| 1190 |  | 
| 1191 |     A synonym for \e {std::random_access_iterator_tag} indicating | 
| 1192 |     this iterator is a random-access iterator. | 
| 1193 |  | 
| 1194 |     \note In Qt versions before 5.6, this was set by mistake to | 
| 1195 |     \e {std::bidirectional_iterator_tag}. | 
| 1196 | */ | 
| 1197 |  | 
| 1198 | /*! \typedef QJsonObject::const_iterator::reference | 
| 1199 |  | 
| 1200 |     \internal | 
| 1201 | */ | 
| 1202 |  | 
| 1203 | /*! \typedef QJsonObject::const_iterator::value_type | 
| 1204 |  | 
| 1205 |     \internal | 
| 1206 | */ | 
| 1207 |  | 
| 1208 | /*! \typedef QJsonObject::const_iterator::pointer | 
| 1209 |  | 
| 1210 |     \internal | 
| 1211 | */ | 
| 1212 |  | 
| 1213 | /*! \fn QJsonObject::const_iterator::const_iterator() | 
| 1214 |  | 
| 1215 |     Constructs an uninitialized iterator. | 
| 1216 |  | 
| 1217 |     Functions like key(), value(), and operator++() must not be | 
| 1218 |     called on an uninitialized iterator. Use operator=() to assign a | 
| 1219 |     value to it before using it. | 
| 1220 |  | 
| 1221 |     \sa QJsonObject::constBegin(), QJsonObject::constEnd() | 
| 1222 | */ | 
| 1223 |  | 
| 1224 | /*! \fn QJsonObject::const_iterator::const_iterator(const QJsonObject *obj, qsizetype index) | 
| 1225 |     \internal | 
| 1226 | */ | 
| 1227 |  | 
| 1228 | /*! \fn QJsonObject::const_iterator::const_iterator(const iterator &other) | 
| 1229 |  | 
| 1230 |     Constructs a copy of \a other. | 
| 1231 | */ | 
| 1232 |  | 
| 1233 | /*! \fn QString QJsonObject::const_iterator::key() const | 
| 1234 |  | 
| 1235 |     Returns the current item's key. | 
| 1236 |  | 
| 1237 |     \sa value() | 
| 1238 | */ | 
| 1239 |  | 
| 1240 | /*! \fn QJsonValueRef QJsonObject::const_iterator::value() const | 
| 1241 |  | 
| 1242 |     Returns the current item's value. | 
| 1243 |  | 
| 1244 |     \sa key(), operator*() | 
| 1245 | */ | 
| 1246 |  | 
| 1247 | /*! \fn const QJsonValueRef QJsonObject::const_iterator::operator*() const | 
| 1248 |  | 
| 1249 |     Returns the current item's value. | 
| 1250 |  | 
| 1251 |     Same as value(). | 
| 1252 |  | 
| 1253 |     \sa key() | 
| 1254 | */ | 
| 1255 |  | 
| 1256 | /*! \fn const QJsonValueRef *QJsonObject::const_iterator::operator->() const | 
| 1257 |  | 
| 1258 |     Returns a pointer to the current item. | 
| 1259 | */ | 
| 1260 |  | 
| 1261 | /*! \fn const QJsonValue QJsonObject::const_iterator::operator[](qsizetype j) | 
| 1262 |  | 
| 1263 |     Returns the item at offset \a j from the item pointed to by this iterator (the item at | 
| 1264 |     position \c{*this + j}). | 
| 1265 |  | 
| 1266 |     This function is provided to make QJsonObject iterators behave like C++ | 
| 1267 |     pointers. | 
| 1268 |  | 
| 1269 |     \sa operator+() | 
| 1270 | */ | 
| 1271 |  | 
| 1272 |  | 
| 1273 | /*! \fn bool QJsonObject::const_iterator::operator==(const const_iterator &other) const | 
| 1274 |     \fn bool QJsonObject::const_iterator::operator==(const iterator &other) const | 
| 1275 |  | 
| 1276 |     Returns \c true if \a other points to the same item as this | 
| 1277 |     iterator; otherwise returns \c false. | 
| 1278 |  | 
| 1279 |     \sa operator!=() | 
| 1280 | */ | 
| 1281 |  | 
| 1282 | /*! \fn bool QJsonObject::const_iterator::operator!=(const const_iterator &other) const | 
| 1283 |     \fn bool QJsonObject::const_iterator::operator!=(const iterator &other) const | 
| 1284 |  | 
| 1285 |     Returns \c true if \a other points to a different item than this | 
| 1286 |     iterator; otherwise returns \c false. | 
| 1287 |  | 
| 1288 |     \sa operator==() | 
| 1289 | */ | 
| 1290 |  | 
| 1291 | /*! | 
| 1292 |     \fn bool QJsonObject::const_iterator::operator<(const const_iterator& other) const | 
| 1293 |  | 
| 1294 |     Returns \c true if the item pointed to by this iterator is less than | 
| 1295 |     the item pointed to by the \a other iterator. | 
| 1296 | */ | 
| 1297 |  | 
| 1298 | /*! | 
| 1299 |     \fn bool QJsonObject::const_iterator::operator<=(const const_iterator& other) const | 
| 1300 |  | 
| 1301 |     Returns \c true if the item pointed to by this iterator is less than | 
| 1302 |     or equal to the item pointed to by the \a other iterator. | 
| 1303 | */ | 
| 1304 |  | 
| 1305 | /*! | 
| 1306 |     \fn bool QJsonObject::const_iterator::operator>(const const_iterator& other) const | 
| 1307 |  | 
| 1308 |     Returns \c true if the item pointed to by this iterator is greater | 
| 1309 |     than the item pointed to by the \a other iterator. | 
| 1310 | */ | 
| 1311 |  | 
| 1312 | /*! | 
| 1313 |     \fn bool QJsonObject::const_iterator::operator>=(const const_iterator& other) const | 
| 1314 |  | 
| 1315 |     Returns \c true if the item pointed to by this iterator is greater | 
| 1316 |     than or equal to the item pointed to by the \a other iterator. | 
| 1317 | */ | 
| 1318 |  | 
| 1319 | /*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator++() | 
| 1320 |  | 
| 1321 |     The prefix ++ operator, \c{++i}, advances the iterator to the | 
| 1322 |     next item in the object and returns an iterator to the new current | 
| 1323 |     item. | 
| 1324 |  | 
| 1325 |     Calling this function on QJsonObject::end() leads to undefined results. | 
| 1326 |  | 
| 1327 |     \sa operator--() | 
| 1328 | */ | 
| 1329 |  | 
| 1330 | /*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator++(int) | 
| 1331 |  | 
| 1332 |     \overload | 
| 1333 |  | 
| 1334 |     The postfix ++ operator, \c{i++}, advances the iterator to the | 
| 1335 |     next item in the object and returns an iterator to the previously | 
| 1336 |     current item. | 
| 1337 | */ | 
| 1338 |  | 
| 1339 | /*! \fn QJsonObject::const_iterator &QJsonObject::const_iterator::operator--() | 
| 1340 |  | 
| 1341 |     The prefix -- operator, \c{--i}, makes the preceding item | 
| 1342 |     current and returns an iterator pointing to the new current item. | 
| 1343 |  | 
| 1344 |     Calling this function on QJsonObject::begin() leads to undefined | 
| 1345 |     results. | 
| 1346 |  | 
| 1347 |     \sa operator++() | 
| 1348 | */ | 
| 1349 |  | 
| 1350 | /*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator--(int) | 
| 1351 |  | 
| 1352 |     \overload | 
| 1353 |  | 
| 1354 |     The postfix -- operator, \c{i--}, makes the preceding item | 
| 1355 |     current and returns an iterator pointing to the previously | 
| 1356 |     current item. | 
| 1357 | */ | 
| 1358 |  | 
| 1359 | /*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator+(qsizetype j) const | 
| 1360 |  | 
| 1361 |     Returns an iterator to the item at \a j positions forward from | 
| 1362 |     this iterator. If \a j is negative, the iterator goes backward. | 
| 1363 |  | 
| 1364 |     This operation can be slow for large \a j values. | 
| 1365 |  | 
| 1366 |     \sa operator-() | 
| 1367 | */ | 
| 1368 |  | 
| 1369 | /*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator-(qsizetype j) const | 
| 1370 |  | 
| 1371 |     Returns an iterator to the item at \a j positions backward from | 
| 1372 |     this iterator. If \a j is negative, the iterator goes forward. | 
| 1373 |  | 
| 1374 |     This operation can be slow for large \a j values. | 
| 1375 |  | 
| 1376 |     \sa operator+() | 
| 1377 | */ | 
| 1378 |  | 
| 1379 | /*! \fn QJsonObject::const_iterator &QJsonObject::const_iterator::operator+=(qsizetype j) | 
| 1380 |  | 
| 1381 |     Advances the iterator by \a j items. If \a j is negative, the | 
| 1382 |     iterator goes backward. | 
| 1383 |  | 
| 1384 |     This operation can be slow for large \a j values. | 
| 1385 |  | 
| 1386 |     \sa operator-=(), operator+() | 
| 1387 | */ | 
| 1388 |  | 
| 1389 | /*! \fn QJsonObject::const_iterator &QJsonObject::const_iterator::operator-=(qsizetype j) | 
| 1390 |  | 
| 1391 |     Makes the iterator go back by \a j items. If \a j is negative, | 
| 1392 |     the iterator goes forward. | 
| 1393 |  | 
| 1394 |     This operation can be slow for large \a j values. | 
| 1395 |  | 
| 1396 |     \sa operator+=(), operator-() | 
| 1397 | */ | 
| 1398 |  | 
| 1399 | /*! \fn qsizetype QJsonObject::const_iterator::operator-(const_iterator other) const | 
| 1400 |  | 
| 1401 |     Returns the number of items between the item pointed to by \a | 
| 1402 |     other and the item pointed to by this iterator. | 
| 1403 | */ | 
| 1404 |  | 
| 1405 |  | 
| 1406 | /*! | 
| 1407 |     \internal | 
| 1408 |  */ | 
| 1409 | bool QJsonObject::detach(qsizetype reserve) | 
| 1410 | { | 
| 1411 |     if (!o) | 
| 1412 |         return true; | 
| 1413 |     o = QCborContainerPrivate::detach(o.data(), reserve ? reserve * 2 : o->elements.length()); | 
| 1414 |     return o; | 
| 1415 | } | 
| 1416 |  | 
| 1417 | /*! | 
| 1418 |     \internal | 
| 1419 |  */ | 
| 1420 | QString QJsonObject::keyAt(qsizetype i) const | 
| 1421 | { | 
| 1422 |     Q_ASSERT(o && i >= 0 && i * 2 < o->elements.length()); | 
| 1423 |     return o->stringAt(i * 2); | 
| 1424 | } | 
| 1425 |  | 
| 1426 | /*! | 
| 1427 |     \internal | 
| 1428 |  */ | 
| 1429 | QJsonValue QJsonObject::valueAt(qsizetype i) const | 
| 1430 | { | 
| 1431 |     if (!o || i < 0 || 2 * i + 1 >= o->elements.length()) | 
| 1432 |         return QJsonValue(QJsonValue::Undefined); | 
| 1433 |     return QJsonPrivate::Value::fromTrustedCbor(o->valueAt(2 * i + 1)); | 
| 1434 | } | 
| 1435 |  | 
| 1436 | /*! | 
| 1437 |     \internal | 
| 1438 |  */ | 
| 1439 | void QJsonObject::setValueAt(qsizetype i, const QJsonValue &val) | 
| 1440 | { | 
| 1441 |     Q_ASSERT(o && i >= 0 && 2 * i + 1 < o->elements.length()); | 
| 1442 |     detach(); | 
| 1443 |     if (val.isUndefined()) { | 
| 1444 |         o->removeAt(2 * i + 1); | 
| 1445 |         o->removeAt(2 * i); | 
| 1446 |     } else { | 
| 1447 |         o->replaceAt(2 * i + 1, QCborValue::fromJsonValue(val)); | 
| 1448 |     } | 
| 1449 | } | 
| 1450 |  | 
| 1451 | /*! | 
| 1452 |     \internal | 
| 1453 |  */ | 
| 1454 | void QJsonObject::removeAt(qsizetype index) | 
| 1455 | { | 
| 1456 |     detach(); | 
| 1457 |     o->removeAt(2 * index + 1); | 
| 1458 |     o->removeAt(2 * index); | 
| 1459 | } | 
| 1460 |  | 
| 1461 | size_t qHash(const QJsonObject &object, size_t seed) | 
| 1462 | { | 
| 1463 |     QtPrivate::QHashCombine hash; | 
| 1464 |     for (auto it = object.begin(), end = object.end(); it != end; ++it) { | 
| 1465 |         const QString key = it.key(); | 
| 1466 |         const QJsonValue value = it.value(); | 
| 1467 |         seed = hash(seed, std::pair<const QString&, const QJsonValue&>(key, value)); | 
| 1468 |     } | 
| 1469 |     return seed; | 
| 1470 | } | 
| 1471 |  | 
| 1472 | #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) | 
| 1473 | QDebug operator<<(QDebug dbg, const QJsonObject &o) | 
| 1474 | { | 
| 1475 |     QDebugStateSaver saver(dbg); | 
| 1476 |     if (!o.o) { | 
| 1477 |         dbg << "QJsonObject()" ; | 
| 1478 |         return dbg; | 
| 1479 |     } | 
| 1480 |     QByteArray json; | 
| 1481 |     QJsonPrivate::Writer::objectToJson(o.o.data(), json, 0, true); | 
| 1482 |     dbg.nospace() << "QJsonObject("  | 
| 1483 |                   << json.constData() // print as utf-8 string without extra quotation marks | 
| 1484 |                   << ")" ; | 
| 1485 |     return dbg; | 
| 1486 | } | 
| 1487 | #endif | 
| 1488 |  | 
| 1489 | #ifndef QT_NO_DATASTREAM | 
| 1490 | QDataStream &operator<<(QDataStream &stream, const QJsonObject &object) | 
| 1491 | { | 
| 1492 |     QJsonDocument doc{object}; | 
| 1493 |     stream << doc.toJson(QJsonDocument::Compact); | 
| 1494 |     return stream; | 
| 1495 | } | 
| 1496 |  | 
| 1497 | QDataStream &operator>>(QDataStream &stream, QJsonObject &object) | 
| 1498 | { | 
| 1499 |     QJsonDocument doc; | 
| 1500 |     stream >> doc; | 
| 1501 |     object = doc.object(); | 
| 1502 |     return stream; | 
| 1503 | } | 
| 1504 | #endif | 
| 1505 |  | 
| 1506 | QT_END_NAMESPACE | 
| 1507 |  |