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 <qurl.h>
45#include <quuid.h>
46#include <qvariant.h>
47#include <qstringlist.h>
48#include <qdebug.h>
49#include "qdatastream.h"
50
51#include <private/qnumeric_p.h>
52#include <private/qcborvalue_p.h>
53
54#include <qcborarray.h>
55#include <qcbormap.h>
56
57#include "qjson_p.h"
58
59QT_BEGIN_NAMESPACE
60
61/*!
62 \class QJsonValue
63 \inmodule QtCore
64 \ingroup json
65 \ingroup shared
66 \reentrant
67 \since 5.0
68
69 \brief The QJsonValue class encapsulates a value in JSON.
70
71 A value in JSON can be one of 6 basic types:
72
73 JSON is a format to store structured data. It has 6 basic data types:
74
75 \list
76 \li bool QJsonValue::Bool
77 \li double QJsonValue::Double
78 \li string QJsonValue::String
79 \li array QJsonValue::Array
80 \li object QJsonValue::Object
81 \li null QJsonValue::Null
82 \endlist
83
84 A value can represent any of the above data types. In addition, QJsonValue has one special
85 flag to represent undefined values. This can be queried with isUndefined().
86
87 The type of the value can be queried with type() or accessors like isBool(), isString(), and so on.
88 Likewise, the value can be converted to the type stored in it using the toBool(), toString() and so on.
89
90 Values are strictly typed internally and contrary to QVariant will not attempt to do any implicit type
91 conversions. This implies that converting to a type that is not stored in the value will return a default
92 constructed return value.
93
94 \section1 QJsonValueRef
95
96 QJsonValueRef is a helper class for QJsonArray and QJsonObject.
97 When you get an object of type QJsonValueRef, you can
98 use it as if it were a reference to a QJsonValue. If you assign to it,
99 the assignment will apply to the element in the QJsonArray or QJsonObject
100 from which you got the reference.
101
102 The following methods return QJsonValueRef:
103 \list
104 \li \l {QJsonArray}::operator[](int i)
105 \li \l {QJsonObject}::operator[](const QString & key) const
106 \endlist
107
108 \sa {JSON Support in Qt}, {JSON Save Game Example}
109*/
110
111/*!
112 Creates a QJsonValue of type \a type.
113
114 The default is to create a Null value.
115 */
116QJsonValue::QJsonValue(Type type)
117 : d(nullptr), t(QCborValue::Undefined)
118{
119 switch (type) {
120 case Null:
121 t = QCborValue::Null;
122 break;
123 case Bool:
124 t = QCborValue::False;
125 break;
126 case Double:
127 t = QCborValue::Double;
128 break;
129 case String:
130 t = QCborValue::String;
131 break;
132 case Array:
133 t = QCborValue::Array;
134 break;
135 case Object:
136 t = QCborValue::Map;
137 break;
138 case Undefined:
139 break;
140 }
141}
142
143/*!
144 Creates a value of type Bool, with value \a b.
145 */
146QJsonValue::QJsonValue(bool b)
147 : t(b ? QCborValue::True : QCborValue::False)
148{
149}
150
151/*!
152 Creates a value of type Double, with value \a v.
153 */
154QJsonValue::QJsonValue(double v)
155 : d(nullptr)
156{
157 if (convertDoubleTo(v, value: &n)) {
158 t = QCborValue::Integer;
159 } else {
160 memcpy(dest: &n, src: &v, n: sizeof(n));
161 t = QCborValue::Double;
162 }
163}
164
165/*!
166 \overload
167 Creates a value of type Double, with value \a v.
168 */
169QJsonValue::QJsonValue(int v)
170 : n(v), t(QCborValue::Integer)
171{
172}
173
174/*!
175 \overload
176 Creates a value of type Double, with value \a v.
177 NOTE: the integer limits for IEEE 754 double precision data is 2^53 (-9007199254740992 to +9007199254740992).
178 If you pass in values outside this range expect a loss of precision to occur.
179 */
180QJsonValue::QJsonValue(qint64 v)
181 : n(v), t(QCborValue::Integer)
182{
183}
184
185/*!
186 Creates a value of type String, with value \a s.
187 */
188QJsonValue::QJsonValue(const QString &s)
189 : QJsonValue(QJsonPrivate::Value::fromTrustedCbor(v: s))
190{
191}
192
193/*!
194 \fn QJsonValue::QJsonValue(const char *s)
195
196 Creates a value of type String with value \a s, assuming
197 UTF-8 encoding of the input.
198
199 You can disable this constructor by defining \c
200 QT_NO_CAST_FROM_ASCII when you compile your applications.
201
202 \since 5.3
203 */
204
205// ### Qt6: remove
206void QJsonValue::stringDataFromQStringHelper(const QString &string)
207{
208 *this = QJsonValue(string);
209}
210
211/*!
212 Creates a value of type String, with value \a s.
213 */
214QJsonValue::QJsonValue(QLatin1String s)
215 : QJsonValue(QJsonPrivate::Value::fromTrustedCbor(v: s))
216{
217}
218
219/*!
220 Creates a value of type Array, with value \a a.
221 */
222QJsonValue::QJsonValue(const QJsonArray &a)
223 : n(-1), d(a.a), t(QCborValue::Array)
224{
225}
226
227/*!
228 Creates a value of type Object, with value \a o.
229 */
230QJsonValue::QJsonValue(const QJsonObject &o)
231 : n(-1), d(o.o), t(QCborValue::Map)
232{
233}
234
235
236/*!
237 Destroys the value.
238 */
239QJsonValue::~QJsonValue() = default;
240
241/*!
242 Creates a copy of \a other.
243 */
244QJsonValue::QJsonValue(const QJsonValue &other)
245{
246 n = other.n;
247 t = other.t;
248 d = other.d;
249}
250
251/*!
252 Assigns the value stored in \a other to this object.
253 */
254QJsonValue &QJsonValue::operator =(const QJsonValue &other)
255{
256 QJsonValue copy(other);
257 swap(other&: copy);
258 return *this;
259}
260
261QJsonValue::QJsonValue(QJsonValue &&other) noexcept :
262 n(other.n),
263 d(other.d),
264 t(other.t)
265{
266 other.n = 0;
267 other.d = nullptr;
268 other.t = QCborValue::Null;
269}
270
271void QJsonValue::swap(QJsonValue &other) noexcept
272{
273 qSwap(value1&: n, value2&: other.n);
274 qSwap(value1&: d, value2&: other.d);
275 qSwap(value1&: t, value2&: other.t);
276}
277
278/*!
279 \fn QJsonValue::QJsonValue(QJsonValue &&other)
280 \since 5.10
281
282 Move-constructs a QJsonValue from \a other.
283*/
284
285/*!
286 \fn QJsonValue &QJsonValue::operator =(QJsonValue &&other)
287 \since 5.10
288
289 Move-assigns \a other to this value.
290*/
291
292/*!
293 \fn void QJsonValue::swap(QJsonValue &other)
294 \since 5.10
295
296 Swaps the value \a other with this. This operation is very fast and never fails.
297*/
298
299/*!
300 \fn bool QJsonValue::isNull() const
301
302 Returns \c true if the value is null.
303*/
304
305/*!
306 \fn bool QJsonValue::isBool() const
307
308 Returns \c true if the value contains a boolean.
309
310 \sa toBool()
311 */
312
313/*!
314 \fn bool QJsonValue::isDouble() const
315
316 Returns \c true if the value contains a double.
317
318 \sa toDouble()
319 */
320
321/*!
322 \fn bool QJsonValue::isString() const
323
324 Returns \c true if the value contains a string.
325
326 \sa toString()
327 */
328
329/*!
330 \fn bool QJsonValue::isArray() const
331
332 Returns \c true if the value contains an array.
333
334 \sa toArray()
335 */
336
337/*!
338 \fn bool QJsonValue::isObject() const
339
340 Returns \c true if the value contains an object.
341
342 \sa toObject()
343 */
344
345/*!
346 \fn bool QJsonValue::isUndefined() const
347
348 Returns \c true if the value is undefined. This can happen in certain
349 error cases as e.g. accessing a non existing key in a QJsonObject.
350 */
351
352/*!
353 Converts \a variant to a QJsonValue and returns it.
354
355 The conversion will convert QVariant types as follows:
356
357 \table
358 \header
359 \li Source type
360 \li Destination type
361 \row
362 \li
363 \list
364 \li QMetaType::Nullptr
365 \endlist
366 \li QJsonValue::Null
367 \row
368 \li
369 \list
370 \li QMetaType::Bool
371 \endlist
372 \li QJsonValue::Bool
373 \row
374 \li
375 \list
376 \li QMetaType::Int
377 \li QMetaType::UInt
378 \li QMetaType::LongLong
379 \li QMetaType::ULongLong
380 \li QMetaType::Float
381 \li QMetaType::Double
382 \endlist
383 \li QJsonValue::Double
384 \row
385 \li
386 \list
387 \li QMetaType::QString
388 \endlist
389 \li QJsonValue::String
390 \row
391 \li
392 \list
393 \li QMetaType::QStringList
394 \li QMetaType::QVariantList
395 \endlist
396 \li QJsonValue::Array
397 \row
398 \li
399 \list
400 \li QMetaType::QVariantMap
401 \li QMetaType::QVariantHash
402 \endlist
403 \li QJsonValue::Object
404
405 \row
406 \li
407 \list
408 \li QMetaType::QUrl
409 \endlist
410 \li QJsonValue::String. The conversion will use QUrl::toString() with flag
411 QUrl::FullyEncoded, so as to ensure maximum compatibility in parsing the URL
412 \row
413 \li
414 \list
415 \li QMetaType::QUuid
416 \endlist
417 \li QJsonValue::String. Since Qt 5.11, the resulting string will not include braces
418 \row
419 \li
420 \list
421 \li QMetaType::QCborValue
422 \endlist
423 \li Whichever type QCborValue::toJsonValue() returns.
424 \row
425 \li
426 \list
427 \li QMetaType::QCborArray
428 \endlist
429 \li QJsonValue::Array. See QCborValue::toJsonValue() for conversion restrictions.
430 \row
431 \li
432 \list
433 \li QMetaType::QCborMap
434 \endlist
435 \li QJsonValue::Map. See QCborValue::toJsonValue() for conversion restrictions and the
436 "stringification" of map keys.
437 \endtable
438
439 \section2 Loss of information and other types
440
441 QVariant can carry more information than is representable in JSON. If the
442 QVariant is not one of the types above, the conversion is not guaranteed
443 and is subject to change in future versions of Qt, as the UUID one did.
444 Code should strive not to use any other types than those listed above.
445
446 If QVariant::isNull() returns true, a null QJsonValue is returned or
447 inserted into the list or object, regardless of the type carried by
448 QVariant. Note the behavior change in Qt 6.0 affecting QVariant::isNull()
449 also affects this function.
450
451 A floating point value that is either an infinity or NaN will be converted
452 to a null JSON value. The values outside the range of ±2^53 may lose precision,
453 because they are converted to a double QJsonValue.
454
455 For other types not listed above, a conversion to string will be attempted,
456 usually but not always by calling QVariant::toString(). If the conversion
457 fails the value is replaced by a null JSON value. Note that
458 QVariant::toString() is also lossy for the majority of types. For example,
459 if the passed QVariant is representing raw byte array data, it is recommended
460 to pre-encode it to \l {https://www.ietf.org/rfc/rfc4648.txt}{Base64} (or
461 another lossless encoding), otherwise a lossy conversion using QString::fromUtf8()
462 will be used.
463
464 Please note that the conversions via QVariant::toString() are subject to
465 change at any time. Both QVariant and QJsonValue may be extended in the
466 future to support more types, which will result in a change in how this
467 function performs conversions.
468
469 \sa toVariant(), QCborValue::fromVariant()
470 */
471QJsonValue QJsonValue::fromVariant(const QVariant &variant)
472{
473 switch (variant.userType()) {
474 case QMetaType::Nullptr:
475 return QJsonValue(Null);
476 case QMetaType::Bool:
477 return QJsonValue(variant.toBool());
478 case QMetaType::Int:
479 case QMetaType::Float:
480 case QMetaType::Double:
481 case QMetaType::LongLong:
482 case QMetaType::ULongLong:
483 case QMetaType::UInt: {
484 double v = variant.toDouble();
485 return qt_is_finite(d: v) ? QJsonValue(v) : QJsonValue();
486 }
487 case QMetaType::QString:
488 return QJsonValue(variant.toString());
489 case QMetaType::QStringList:
490 return QJsonValue(QJsonArray::fromStringList(list: variant.toStringList()));
491 case QMetaType::QVariantList:
492 return QJsonValue(QJsonArray::fromVariantList(list: variant.toList()));
493 case QMetaType::QVariantMap:
494 return QJsonValue(QJsonObject::fromVariantMap(map: variant.toMap()));
495 case QMetaType::QVariantHash:
496 return QJsonValue(QJsonObject::fromVariantHash(map: variant.toHash()));
497#ifndef QT_BOOTSTRAPPED
498 case QMetaType::QUrl:
499 return QJsonValue(variant.toUrl().toString(options: QUrl::FullyEncoded));
500 case QMetaType::QUuid:
501 return variant.toUuid().toString(mode: QUuid::WithoutBraces);
502 case QMetaType::QJsonValue:
503 return variant.toJsonValue();
504 case QMetaType::QJsonObject:
505 return variant.toJsonObject();
506 case QMetaType::QJsonArray:
507 return variant.toJsonArray();
508 case QMetaType::QJsonDocument: {
509 QJsonDocument doc = variant.toJsonDocument();
510 return doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
511 }
512 case QMetaType::QCborValue:
513 return qvariant_cast<QCborValue>(v: variant).toJsonValue();
514 case QMetaType::QCborArray:
515 return qvariant_cast<QCborArray>(v: variant).toJsonArray();
516 case QMetaType::QCborMap:
517 return qvariant_cast<QCborMap>(v: variant).toJsonObject();
518#endif
519 default:
520 break;
521 }
522 QString string = variant.toString();
523 if (string.isEmpty())
524 return QJsonValue();
525 return QJsonValue(string);
526}
527
528/*!
529 Converts the value to a \l {QVariant::}{QVariant()}.
530
531 The QJsonValue types will be converted as follows:
532
533 \value Null QMetaType::Nullptr
534 \value Bool QMetaType::Bool
535 \value Double QMetaType::Double or QMetaType::LongLong
536 \value String QString
537 \value Array QVariantList
538 \value Object QVariantMap
539 \value Undefined \l {QVariant::}{QVariant()}
540
541 \sa fromVariant()
542 */
543QVariant QJsonValue::toVariant() const
544{
545 switch (t) {
546 case QCborValue::True:
547 return true;
548 case QCborValue::False:
549 return false;
550 case QCborValue::Integer:
551 return n;
552 case QCborValue::Double:
553 return toDouble();
554 case QCborValue::String:
555 return toString();
556 case QCborValue::Array:
557 return d ?
558 QJsonArray(d.data()).toVariantList() :
559 QVariantList();
560 case QCborValue::Map:
561 return d ?
562 QJsonObject(d.data()).toVariantMap() :
563 QVariantMap();
564 case QCborValue::Null:
565 return QVariant::fromValue(value: nullptr);
566 case QCborValue::Undefined:
567 default:
568 break;
569 }
570 return QVariant();
571}
572
573/*!
574 \enum QJsonValue::Type
575
576 This enum describes the type of the JSON value.
577
578 \value Null A Null value
579 \value Bool A boolean value. Use toBool() to convert to a bool.
580 \value Double A double. Use toDouble() to convert to a double.
581 \value String A string. Use toString() to convert to a QString.
582 \value Array An array. Use toArray() to convert to a QJsonArray.
583 \value Object An object. Use toObject() to convert to a QJsonObject.
584 \value Undefined The value is undefined. This is usually returned as an
585 error condition, when trying to read an out of bounds value
586 in an array or a non existent key in an object.
587*/
588
589/*!
590 Returns the type of the value.
591
592 \sa QJsonValue::Type
593 */
594QJsonValue::Type QJsonValue::type() const
595{
596 switch (t) {
597 case QCborValue::Null:
598 return QJsonValue::Null;
599 case QCborValue::True:
600 case QCborValue::False:
601 return QJsonValue::Bool;
602 case QCborValue::Double:
603 case QCborValue::Integer:
604 return QJsonValue::Double;
605 case QCborValue::String:
606 return QJsonValue::String;
607 case QCborValue::Array:
608 return QJsonValue::Array;
609 case QCborValue::Map:
610 return QJsonValue::Object;
611 case QCborValue::Undefined:
612 default:
613 return QJsonValue::Undefined;
614 }
615}
616
617/*!
618 Converts the value to a bool and returns it.
619
620 If type() is not bool, the \a defaultValue will be returned.
621 */
622bool QJsonValue::toBool(bool defaultValue) const
623{
624 switch (t) {
625 case QCborValue::True:
626 return true;
627 case QCborValue::False:
628 return false;
629 default:
630 return defaultValue;
631 }
632}
633
634/*!
635 \since 5.2
636 Converts the value to an int and returns it.
637
638 If type() is not Double or the value is not a whole number,
639 the \a defaultValue will be returned.
640 */
641int QJsonValue::toInt(int defaultValue) const
642{
643 switch (t) {
644 case QCborValue::Double: {
645 const double dbl = toDouble();
646 int dblInt;
647 convertDoubleTo<int>(v: dbl, value: &dblInt);
648 return dbl == dblInt ? dblInt : defaultValue;
649 }
650 case QCborValue::Integer:
651 return (n <= qint64(std::numeric_limits<int>::max())
652 && n >= qint64(std::numeric_limits<int>::min()))
653 ? n : defaultValue;
654 default:
655 return defaultValue;
656 }
657}
658
659/*!
660 Converts the value to a double and returns it.
661
662 If type() is not Double, the \a defaultValue will be returned.
663 */
664double QJsonValue::toDouble(double defaultValue) const
665{
666 switch (t) {
667 case QCborValue::Double: {
668 double d;
669 memcpy(dest: &d, src: &n, n: sizeof(d));
670 return d;
671 }
672 case QCborValue::Integer:
673 return n;
674 default:
675 return defaultValue;
676 }
677}
678
679/*!
680 Converts the value to a QString and returns it.
681
682 If type() is not String, the \a defaultValue will be returned.
683 */
684QString QJsonValue::toString(const QString &defaultValue) const
685{
686 return (t == QCborValue::String && d) ? d->stringAt(idx: n) : defaultValue;
687}
688
689/*!
690 Converts the value to a QString and returns it.
691
692 If type() is not String, a null QString will be returned.
693
694 \sa QString::isNull()
695 */
696QString QJsonValue::toString() const
697{
698 return (t == QCborValue::String && d) ? d->stringAt(idx: n) : QString();
699}
700
701/*!
702 Converts the value to an array and returns it.
703
704 If type() is not Array, the \a defaultValue will be returned.
705 */
706QJsonArray QJsonValue::toArray(const QJsonArray &defaultValue) const
707{
708 if (t != QCborValue::Array || n >= 0 || !d)
709 return defaultValue;
710
711 return QJsonArray(d.data());
712}
713
714/*!
715 \overload
716
717 Converts the value to an array and returns it.
718
719 If type() is not Array, a \l{QJsonArray::}{QJsonArray()} will be returned.
720 */
721QJsonArray QJsonValue::toArray() const
722{
723 return toArray(defaultValue: QJsonArray());
724}
725
726/*!
727 Converts the value to an object and returns it.
728
729 If type() is not Object, the \a defaultValue will be returned.
730 */
731QJsonObject QJsonValue::toObject(const QJsonObject &defaultValue) const
732{
733 if (t != QCborValue::Map || n >= 0 || !d)
734 return defaultValue;
735
736 return QJsonObject(d.data());
737}
738
739/*!
740 \overload
741
742 Converts the value to an object and returns it.
743
744 If type() is not Object, the \l {QJsonObject::}{QJsonObject()} will be returned.
745*/
746QJsonObject QJsonValue::toObject() const
747{
748 return toObject(defaultValue: QJsonObject());
749}
750
751#if QT_STRINGVIEW_LEVEL < 2
752/*!
753 Returns a QJsonValue representing the value for the key \a key.
754
755 Equivalent to calling toObject().value(key).
756
757 The returned QJsonValue is QJsonValue::Undefined if the key does not exist,
758 or if isObject() is false.
759
760 \since 5.10
761
762 \sa QJsonValue, QJsonValue::isUndefined(), QJsonObject
763 */
764const QJsonValue QJsonValue::operator[](const QString &key) const
765{
766 return (*this)[QStringView(key)];
767}
768#endif
769
770/*!
771 \overload
772 \since 5.14
773*/
774const QJsonValue QJsonValue::operator[](QStringView key) const
775{
776 if (!isObject())
777 return QJsonValue(QJsonValue::Undefined);
778
779 return toObject().value(key);
780}
781
782/*!
783 \overload
784 \since 5.10
785*/
786const QJsonValue QJsonValue::operator[](QLatin1String key) const
787{
788 if (!isObject())
789 return QJsonValue(QJsonValue::Undefined);
790
791 return toObject().value(key);
792}
793
794/*!
795 Returns a QJsonValue representing the value for index \a i.
796
797 Equivalent to calling toArray().at(i).
798
799 The returned QJsonValue is QJsonValue::Undefined, if \a i is out of bounds,
800 or if isArray() is false.
801
802 \since 5.10
803
804 \sa QJsonValue, QJsonValue::isUndefined(), QJsonArray
805 */
806const QJsonValue QJsonValue::operator[](int i) const
807{
808 if (!isArray())
809 return QJsonValue(QJsonValue::Undefined);
810
811 return toArray().at(i);
812}
813
814/*!
815 Returns \c true if the value is equal to \a other.
816 */
817bool QJsonValue::operator==(const QJsonValue &other) const
818{
819 if (t != other.t)
820 return false;
821
822 switch (t) {
823 case QCborValue::Undefined:
824 case QCborValue::Null:
825 case QCborValue::True:
826 case QCborValue::False:
827 break;
828 case QCborValue::Double:
829 return toDouble() == other.toDouble();
830 case QCborValue::Integer:
831 return n == other.n;
832 case QCborValue::String:
833 return toString() == other.toString();
834 case QCborValue::Array:
835 if (!d)
836 return !other.d || other.d->elements.length() == 0;
837 if (!other.d)
838 return d->elements.length() == 0;
839 return QJsonArray(d.data()) == QJsonArray(other.d.data());
840 case QCborValue::Map:
841 if (!d)
842 return !other.d || other.d->elements.length() == 0;
843 if (!other.d)
844 return d->elements.length() == 0;
845 return QJsonObject(d.data()) == QJsonObject(other.d.data());
846 default:
847 return false;
848 }
849 return true;
850}
851
852/*!
853 Returns \c true if the value is not equal to \a other.
854 */
855bool QJsonValue::operator!=(const QJsonValue &other) const
856{
857 return !(*this == other);
858}
859
860/*!
861 \internal
862 */
863void QJsonValue::detach()
864{
865 d.detach();
866}
867
868
869/*!
870 \class QJsonValueRef
871 \inmodule QtCore
872 \reentrant
873 \brief The QJsonValueRef class is a helper class for QJsonValue.
874
875 \internal
876
877 \ingroup json
878
879 When you get an object of type QJsonValueRef, if you can assign to it,
880 the assignment will apply to the character in the string from
881 which you got the reference. That is its whole purpose in life.
882
883 You can use it exactly in the same way as a reference to a QJsonValue.
884
885 The QJsonValueRef becomes invalid once modifications are made to the
886 string: if you want to keep the character, copy it into a QJsonValue.
887
888 Most of the QJsonValue member functions also exist in QJsonValueRef.
889 However, they are not explicitly documented here.
890*/
891
892
893QJsonValueRef &QJsonValueRef::operator =(const QJsonValue &val)
894{
895 if (is_object)
896 o->setValueAt(i: index, val);
897 else
898 a->replace(i: index, value: val);
899
900 return *this;
901}
902
903QJsonValueRef &QJsonValueRef::operator =(const QJsonValueRef &ref)
904{
905 if (is_object)
906 o->setValueAt(i: index, val: ref);
907 else
908 a->replace(i: index, value: ref);
909
910 return *this;
911}
912
913QVariant QJsonValueRef::toVariant() const
914{
915 return toValue().toVariant();
916}
917
918QJsonArray QJsonValueRef::toArray() const
919{
920 return toValue().toArray();
921}
922
923QJsonObject QJsonValueRef::toObject() const
924{
925 return toValue().toObject();
926}
927
928QJsonValue QJsonValueRef::toValue() const
929{
930 if (!is_object)
931 return a->at(i: index);
932 return o->valueAt(i: index);
933}
934
935uint qHash(const QJsonValue &value, uint seed)
936{
937 switch (value.type()) {
938 case QJsonValue::Null:
939 return qHash(nullptr, seed);
940 case QJsonValue::Bool:
941 return qHash(t: value.toBool(), seed);
942 case QJsonValue::Double:
943 return qHash(key: value.toDouble(), seed);
944 case QJsonValue::String:
945 return qHash(key: value.toString(), seed);
946 case QJsonValue::Array:
947 return qHash(array: value.toArray(), seed);
948 case QJsonValue::Object:
949 return qHash(object: value.toObject(), seed);
950 case QJsonValue::Undefined:
951 return seed;
952 }
953 Q_UNREACHABLE();
954 return 0;
955}
956
957#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
958QDebug operator<<(QDebug dbg, const QJsonValue &o)
959{
960 QDebugStateSaver saver(dbg);
961 switch (o.type()) {
962 case QJsonValue::Undefined:
963 dbg << "QJsonValue(undefined)";
964 break;
965 case QJsonValue::Null:
966 dbg << "QJsonValue(null)";
967 break;
968 case QJsonValue::Bool:
969 dbg.nospace() << "QJsonValue(bool, " << o.toBool() << ')';
970 break;
971 case QJsonValue::Double:
972 dbg.nospace() << "QJsonValue(double, " << o.toDouble() << ')';
973 break;
974 case QJsonValue::String:
975 dbg.nospace() << "QJsonValue(string, " << o.toString() << ')';
976 break;
977 case QJsonValue::Array:
978 dbg.nospace() << "QJsonValue(array, ";
979 dbg << o.toArray();
980 dbg << ')';
981 break;
982 case QJsonValue::Object:
983 dbg.nospace() << "QJsonValue(object, ";
984 dbg << o.toObject();
985 dbg << ')';
986 break;
987 }
988 return dbg;
989}
990#endif
991
992#ifndef QT_NO_DATASTREAM
993QDataStream &operator<<(QDataStream &stream, const QJsonValue &v)
994{
995 quint8 type = v.type();
996 stream << type;
997 switch (type) {
998 case QJsonValue::Undefined:
999 case QJsonValue::Null:
1000 break;
1001 case QJsonValue::Bool:
1002 stream << v.toBool();
1003 break;
1004 case QJsonValue::Double:
1005 stream << v.toDouble();
1006 break;
1007 case QJsonValue::String:
1008 stream << v.toString();
1009 break;
1010 case QJsonValue::Array:
1011 stream << v.toArray();
1012 break;
1013 case QJsonValue::Object:
1014 stream << v.toObject();
1015 break;
1016 }
1017 return stream;
1018}
1019
1020QDataStream &operator>>(QDataStream &stream, QJsonValue &v)
1021{
1022 quint8 type;
1023 stream >> type;
1024 switch (type) {
1025 case QJsonValue::Undefined:
1026 case QJsonValue::Null:
1027 v = QJsonValue{QJsonValue::Type(type)};
1028 break;
1029 case QJsonValue::Bool: {
1030 bool b;
1031 stream >> b;
1032 v = QJsonValue(b);
1033 break;
1034 } case QJsonValue::Double: {
1035 double d;
1036 stream >> d;
1037 v = QJsonValue{d};
1038 break;
1039 } case QJsonValue::String: {
1040 QString s;
1041 stream >> s;
1042 v = QJsonValue{s};
1043 break;
1044 }
1045 case QJsonValue::Array: {
1046 QJsonArray a;
1047 stream >> a;
1048 v = QJsonValue{a};
1049 break;
1050 }
1051 case QJsonValue::Object: {
1052 QJsonObject o;
1053 stream >> o;
1054 v = QJsonValue{o};
1055 break;
1056 }
1057 default: {
1058 stream.setStatus(QDataStream::ReadCorruptData);
1059 v = QJsonValue{QJsonValue::Undefined};
1060 }
1061 }
1062 return stream;
1063}
1064#endif
1065
1066QT_END_NAMESPACE
1067

source code of qtbase/src/corelib/serialization/qjsonvalue.cpp