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