QtBase  v6.3.1
qjsonvalue.cpp
Go to the documentation of this file.
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 
60 
117 {
118  switch (type) {
119  case Null:
121  break;
122  case Bool:
124  break;
125  case Double:
127  break;
128  case String:
130  break;
131  case Array:
133  break;
134  case Object:
136  break;
137  case Undefined:
138  break;
139  }
140 }
141 
146  : value(b)
147 {
148 }
149 
150 static 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 
165  : value(doubleValueHelper(v))
166 {
167 }
168 
174  : value(v)
175 {
176 }
177 
185  : value(v)
186 {
187 }
188 
193  : value(s)
194 {
195 }
196 
213  : value(s)
214 {
215 }
216 
221  : value(QCborArray::fromJsonArray(a))
222 {
223 }
224 
230  : value(QCborArray::fromJsonArray(std::move(a)))
231 {
232 }
233 
238  : value(QCborMap::fromJsonObject(o))
239 {
240 }
241 
247  : value(QCborMap::fromJsonObject(std::move(o)))
248 {
249 }
250 
251 
255 QJsonValue::~QJsonValue() = default;
256 
261  : value(other.value)
262 {
263 }
264 
269 {
270  QJsonValue copy(other);
271  swap(copy);
272  return *this;
273 }
274 
276  : value(std::move(other.value))
277 {
278  other.value = QCborValue(nullptr);
279 }
280 
282 {
283  value.swap(other.value);
284 }
285 
483 {
484  switch (variant.metaType().id()) {
485  case QMetaType::Nullptr:
486  return QJsonValue(Null);
487  case QMetaType::Bool:
488  return QJsonValue(variant.toBool());
489  case QMetaType::Short:
490  case QMetaType::UShort:
491  case QMetaType::Int:
492  case QMetaType::UInt:
493  case QMetaType::LongLong:
494  return QJsonValue(variant.toLongLong());
495  case QMetaType::ULongLong:
496  if (variant.toULongLong() <= static_cast<uint64_t>(std::numeric_limits<qint64>::max()))
497  return QJsonValue(variant.toLongLong());
498  Q_FALLTHROUGH();
499  case QMetaType::Float:
500  case QMetaType::Double: {
501  double v = variant.toDouble();
502  return qt_is_finite(v) ? QJsonValue(v) : QJsonValue();
503  }
504  case QMetaType::QString:
505  return QJsonValue(variant.toString());
514 #ifndef QT_BOOTSTRAPPED
515  case QMetaType::QUrl:
517  case QMetaType::QUuid:
519  case QMetaType::QJsonValue:
520  return variant.toJsonValue();
521  case QMetaType::QJsonObject:
522  return variant.toJsonObject();
523  case QMetaType::QJsonArray:
524  return variant.toJsonArray();
525  case QMetaType::QJsonDocument: {
527  return doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
528  }
530  return qvariant_cast<QCborValue>(variant).toJsonValue();
531  case QMetaType::QCborArray:
532  return qvariant_cast<QCborArray>(variant).toJsonArray();
533  case QMetaType::QCborMap:
534  return qvariant_cast<QCborMap>(variant).toJsonObject();
535 #endif
536  default:
537  break;
538  }
539  QString string = variant.toString();
540  if (string.isEmpty())
541  return QJsonValue();
542  return QJsonValue(string);
543 }
544 
561 {
562  switch (value.type()) {
563  case QCborValue::True:
564  return true;
565  case QCborValue::False:
566  return false;
567  case QCborValue::Integer:
568  return toInteger();
569  case QCborValue::Double:
570  return toDouble();
571  case QCborValue::String:
572  return toString();
573  case QCborValue::Array:
574  return toArray().toVariantList();
575  case QCborValue::Map:
576  return toObject().toVariantMap();
577  case QCborValue::Null:
578  return QVariant::fromValue(nullptr);
580  default:
581  break;
582  }
583  return QVariant();
584 }
585 
609 {
610  switch (value.type()) {
611  case QCborValue::Null:
612  return QJsonValue::Null;
613  case QCborValue::True:
614  case QCborValue::False:
615  return QJsonValue::Bool;
616  case QCborValue::Double:
617  case QCborValue::Integer:
618  return QJsonValue::Double;
619  case QCborValue::String:
620  return QJsonValue::String;
621  case QCborValue::Array:
622  return QJsonValue::Array;
623  case QCborValue::Map:
624  return QJsonValue::Object;
626  default:
627  return QJsonValue::Undefined;
628  }
629 }
630 
636 bool QJsonValue::toBool(bool defaultValue) const
637 {
638  switch (value.type()) {
639  case QCborValue::True:
640  return true;
641  case QCborValue::False:
642  return false;
643  default:
644  return defaultValue;
645  }
646 }
647 
655 int QJsonValue::toInt(int defaultValue) const
656 {
657  switch (value.type()) {
658  case QCborValue::Double: {
659  int dblInt;
660  if (convertDoubleTo<int>(toDouble(), &dblInt))
661  return dblInt;
662  break;
663  }
664  case QCborValue::Integer: {
665  const auto n = value.toInteger();
666  if (qint64(int(n)) == n)
667  return int(n);
668  break;
669  }
670  default:
671  break;
672  }
673  return defaultValue;
674 }
675 
684 {
685  switch (value.type()) {
686  case QCborValue::Integer:
687  return value.toInteger();
688  case QCborValue::Double: {
689  qint64 dblInt;
690  if (convertDoubleTo<qint64>(toDouble(), &dblInt))
691  return dblInt;
692  break;
693  }
694  default:
695  break;
696  }
697  return defaultValue;
698 }
699 
705 double QJsonValue::toDouble(double defaultValue) const
706 {
707  return value.toDouble(defaultValue);
708 }
709 
715 QString QJsonValue::toString(const QString &defaultValue) const
716 {
717  return value.toString(defaultValue);
718 }
719 
728 {
729  return value.toString();
730 }
731 
737 QJsonArray QJsonValue::toArray(const QJsonArray &defaultValue) const
738 {
739  const auto dd = QJsonPrivate::Value::container(value);
741  if (value.type() != QCborValue::Array || n >= 0 || !dd)
742  return defaultValue;
743 
744  return QJsonArray(dd);
745 }
746 
755 {
756  return toArray(QJsonArray());
757 }
758 
764 QJsonObject QJsonValue::toObject(const QJsonObject &defaultValue) const
765 {
766  const auto dd = QJsonPrivate::Value::container(value);
768  if (value.type() != QCborValue::Map || n >= 0 || !dd)
769  return defaultValue;
770 
771  return QJsonObject(dd);
772 }
773 
782 {
783  return toObject(QJsonObject());
784 }
785 
786 #if QT_STRINGVIEW_LEVEL < 2
800 {
801  return (*this)[QStringView(key)];
802 }
803 #endif
804 
810 {
811  if (!isObject())
813 
814  return toObject().value(key);
815 }
816 
822 {
823  if (!isObject())
825 
826  return toObject().value(key);
827 }
828 
842 {
843  if (!isArray())
845 
846  return toArray().at(i);
847 }
848 
853 {
854  if (value.type() != other.value.type()) {
855  if (isDouble() && other.isDouble()) {
856  // One value Cbor integer, one Cbor double, should interact as doubles.
857  return toDouble() == other.toDouble();
858  }
859  return false;
860  }
861 
862  switch (value.type()) {
864  case QCborValue::Null:
865  case QCborValue::True:
866  case QCborValue::False:
867  break;
868  case QCborValue::Double:
869  return toDouble() == other.toDouble();
870  case QCborValue::Integer:
873  case QCborValue::String:
874  return toString() == other.toString();
875  case QCborValue::Array:
876  return toArray() == other.toArray();
877  case QCborValue::Map:
878  return toObject() == other.toObject();
879  default:
880  return false;
881  }
882  return true;
883 }
884 
889 {
890  return !(*this == other);
891 }
892 
918 {
919  if (is_object)
920  o->setValueAt(index, val);
921  else
922  a->replace(index, val);
923 
924  return *this;
925 }
926 
928 {
929  if (is_object)
930  o->setValueAt(index, ref);
931  else
932  a->replace(index, ref);
933 
934  return *this;
935 }
936 
938 {
939  return toValue().toVariant();
940 }
941 
943 {
944  return toValue().toArray();
945 }
946 
948 {
949  return toValue().toObject();
950 }
951 
952 QJsonValue QJsonValueRef::toValue() const
953 {
954  if (!is_object)
955  return a->at(index);
956  return o->valueAt(index);
957 }
958 
959 size_t qHash(const QJsonValue &value, size_t seed)
960 {
961  switch (value.type()) {
962  case QJsonValue::Null:
963  return qHash(nullptr, seed);
964  case QJsonValue::Bool:
965  return qHash(value.toBool(), seed);
966  case QJsonValue::Double:
967  return qHash(value.toDouble(), seed);
968  case QJsonValue::String:
969  return qHash(value.toString(), seed);
970  case QJsonValue::Array:
971  return qHash(value.toArray(), seed);
972  case QJsonValue::Object:
973  return qHash(value.toObject(), seed);
975  return seed;
976  }
977  Q_UNREACHABLE();
978  return 0;
979 }
980 
981 #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
983 {
984  QDebugStateSaver saver(dbg);
985  switch (o.value.type()) {
987  dbg << "QJsonValue(undefined)";
988  break;
989  case QCborValue::Null:
990  dbg << "QJsonValue(null)";
991  break;
992  case QCborValue::True:
993  case QCborValue::False:
994  dbg.nospace() << "QJsonValue(bool, " << o.toBool() << ')';
995  break;
996  case QCborValue::Integer:
997  dbg.nospace() << "QJsonValue(double, " << o.toInteger() << ')';
998  break;
999  case QCborValue::Double:
1000  dbg.nospace() << "QJsonValue(double, " << o.toDouble() << ')';
1001  break;
1002  case QCborValue::String:
1003  dbg.nospace() << "QJsonValue(string, " << o.toString() << ')';
1004  break;
1005  case QCborValue::Array:
1006  dbg.nospace() << "QJsonValue(array, ";
1007  dbg << o.toArray();
1008  dbg << ')';
1009  break;
1010  case QCborValue::Map:
1011  dbg.nospace() << "QJsonValue(object, ";
1012  dbg << o.toObject();
1013  dbg << ')';
1014  break;
1015  default:
1016  Q_UNREACHABLE();
1017  }
1018  return dbg;
1019 }
1020 #endif
1021 
1022 #ifndef QT_NO_DATASTREAM
1024 {
1025  quint8 type = v.type();
1026  stream << type;
1027  switch (type) {
1028  case QJsonValue::Undefined:
1029  case QJsonValue::Null:
1030  break;
1031  case QJsonValue::Bool:
1032  stream << v.toBool();
1033  break;
1034  case QJsonValue::Double:
1035  stream << v.toDouble();
1036  break;
1037  case QJsonValue::String:
1038  stream << v.toString();
1039  break;
1040  case QJsonValue::Array:
1041  stream << v.toArray();
1042  break;
1043  case QJsonValue::Object:
1044  stream << v.toObject();
1045  break;
1046  }
1047  return stream;
1048 }
1049 
1051 {
1052  quint8 type;
1053  stream >> type;
1054  switch (type) {
1055  case QJsonValue::Undefined:
1056  case QJsonValue::Null:
1058  break;
1059  case QJsonValue::Bool: {
1060  bool b;
1061  stream >> b;
1062  v = QJsonValue(b);
1063  break;
1064  } case QJsonValue::Double: {
1065  double d;
1066  stream >> d;
1067  v = QJsonValue{d};
1068  break;
1069  } case QJsonValue::String: {
1070  QString s;
1071  stream >> s;
1072  v = QJsonValue{s};
1073  break;
1074  }
1075  case QJsonValue::Array: {
1076  QJsonArray a;
1077  stream >> a;
1078  v = QJsonValue{a};
1079  break;
1080  }
1081  case QJsonValue::Object: {
1082  QJsonObject o;
1083  stream >> o;
1084  v = QJsonValue{o};
1085  break;
1086  }
1087  default: {
1090  }
1091  }
1092  return stream;
1093 }
1094 #endif
1095 
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
@ Float
@ Double
The QCborArray class is used to hold an array of CBOR elements.
Definition: qcborarray.h:56
static QCborArray fromJsonArray(const QJsonArray &array)
Definition: qjsoncbor.cpp:875
The QCborMap class is used to hold an associative container representable in CBOR.
Definition: qcbormap.h:57
static QCborMap fromJsonObject(const QJsonObject &o)
Definition: qjsoncbor.cpp:1001
The QCborValue class encapsulates a value in CBOR.
Definition: qcborvalue.h:86
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
operator>>(QDataStream &ds, qfloat16 &f)
Definition: qfloat16.cpp:344
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:65
QDebug & nospace()
Definition: qdebug.h:113
Convenience class for custom QDebug operators.
Definition: qdebug.h:176
template< typename Enum > size_t qHash(QFlags< Enum > flags, size_t seed=0) noexcept
The QJsonArray class encapsulates a JSON array.
Definition: qjsonarray.h:54
static QJsonArray fromStringList(const QStringList &list)
Definition: qjsonarray.cpp:251
static QJsonArray fromVariantList(const QVariantList &list)
Definition: qjsonarray.cpp:269
QJsonValue at(qsizetype i) const
Definition: qjsonarray.cpp:317
QVariantList toVariantList() const
Definition: qjsonarray.cpp:279
The QJsonDocument class provides a way to read and write JSON documents.
Definition: qjsondocument.h:83
bool isArray() const
QJsonArray array() const
QJsonObject object() const
The QJsonObject class encapsulates a JSON object.
Definition: qjsonobject.h:56
QVariantMap toVariantMap() const
static QJsonObject fromVariantMap(const QVariantMap &map)
QJsonValue value(const QString &key) const
static QJsonObject fromVariantHash(const QVariantHash &map)
static QCborContainerPrivate * container(const QCborValue &v)
Definition: qjson_p.h:206
static qint64 valueHelper(const QCborValue &v)
Definition: qjson_p.h:207
The QJsonValue class encapsulates a value in JSON.
Definition: qjsonvalue.h:60
QJsonValue & operator=(const QJsonValue &other)
Definition: qjsonvalue.cpp:268
bool isDouble() const
Definition: qjsonvalue.h:109
void swap(QJsonValue &other) noexcept
Definition: qjsonvalue.cpp:281
QJsonValue(Type=Null)
Definition: qjsonvalue.cpp:116
friend class QJsonObject
Definition: qjsonvalue.h:141
int toInt(int defaultValue=0) const
Definition: qjsonvalue.cpp:655
friend class QJsonArray
Definition: qjsonvalue.h:140
QJsonObject toObject() const
Definition: qjsonvalue.cpp:781
QJsonArray toArray() const
Definition: qjsonvalue.cpp:754
double toDouble(double defaultValue=0) const
Definition: qjsonvalue.cpp:705
bool operator==(const QJsonValue &other) const
Definition: qjsonvalue.cpp:852
bool toBool(bool defaultValue=false) const
Definition: qjsonvalue.cpp:636
static QJsonValue fromVariant(const QVariant &variant)
Definition: qjsonvalue.cpp:482
bool isArray() const
Definition: qjsonvalue.h:111
Type type() const
Definition: qjsonvalue.cpp:608
QString toString() const
Definition: qjsonvalue.cpp:727
bool isObject() const
Definition: qjsonvalue.h:112
const QJsonValue operator[](const QString &key) const
Definition: qjsonvalue.cpp:799
QVariant toVariant() const
Definition: qjsonvalue.cpp:560
bool operator!=(const QJsonValue &other) const
Definition: qjsonvalue.cpp:888
qint64 toInteger(qint64 defaultValue=0) const
Definition: qjsonvalue.cpp:683
The QJsonValueRef class is a helper class for QJsonValue.
Definition: qjsonvalue.h:154
QVariant toVariant() const
Definition: qjsonvalue.cpp:937
QJsonValueRef & operator=(const QJsonValue &val)
Definition: qjsonvalue.cpp:917
QJsonObject toObject() const
Definition: qjsonvalue.cpp:947
QJsonObject * o
Definition: qjsonvalue.h:197
QJsonArray toArray() const
Definition: qjsonvalue.cpp:942
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
int id(int=0) const
Definition: qmetatype.h:453
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
Definition: qstringview.h:122
@ FullyEncoded
Definition: qurl.h:165
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Definition: qurl.cpp:2851
@ WithoutBraces
Definition: quuid.h:90
QString toString(StringFormat mode=WithBraces) const
Definition: quuid.cpp:583
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
static auto fromValue(const T &value) -> std::enable_if_t< std::is_copy_constructible_v< T >, QVariant >
Definition: qvariant.h:391
QJsonValue toJsonValue() const
Definition: qvariant.cpp:1729
double toDouble(bool *ok=nullptr) const
Definition: qvariant.cpp:1929
QList< QVariant > toList() const
Definition: qvariant.cpp:1979
QMap< QString, QVariant > toMap() const
Definition: qvariant.cpp:1427
qlonglong toLongLong(bool *ok=nullptr) const
Definition: qvariant.cpp:1872
QString toString() const
Definition: qvariant.cpp:1416
bool toBool() const
Definition: qvariant.cpp:1906
QJsonArray toJsonArray() const
Definition: qvariant.cpp:1755
QHash< QString, QVariant > toHash() const
Definition: qvariant.cpp:1438
QJsonDocument toJsonDocument() const
Definition: qvariant.cpp:1768
QJsonObject toJsonObject() const
Definition: qvariant.cpp:1742
QUuid toUuid() const
Definition: qvariant.cpp:1715
QMetaType metaType() const
Definition: qvariant.cpp:1003
qulonglong toULongLong(bool *ok=nullptr) const
Definition: qvariant.cpp:1889
QStringList toStringList() const
Definition: qvariant.cpp:1396
QUrl toUrl() const
Definition: qvariant.cpp:1643
unsigned short UShort
Definition: ftraster.c:310
char Bool
Definition: ftraster.c:315
int Int
Definition: ftraster.c:307
unsigned int UInt
Definition: ftraster.c:308
short Short
Definition: ftraster.c:309
#define QString()
Definition: parse-defines.h:51
#define Q_FALLTHROUGH()
#define Q_UNREACHABLE()
QHash< QString, QVariant > QVariantHash
Definition: qcontainerfwd.h:76
QMap< QString, QVariant > QVariantMap
Definition: qcontainerfwd.h:75
QList< QString > QStringList
Definition: qcontainerfwd.h:64
EGLStreamKHR stream
EGLOutputLayerEXT EGLint EGLAttrib value
ptrdiff_t qsizetype
Definition: qglobal.h:308
long long qint64
Definition: qglobal.h:298
unsigned char quint8
Definition: qglobal.h:284
QList< QVariant > QVariantList
Definition: qjsonarray.h:50
GLenum type
Definition: qopengl.h:270
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLint ref
GLfloat n
GLuint GLfloat * val
Definition: qopenglext.h:1513
GLdouble s
[6]
Definition: qopenglext.h:235
QVariant variant
[1]
QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9))
[0]
QSharedPointer< T > other(t)
[5]
Definition: hb-null.hh:93
Definition: moc.h:48