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