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