1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:data-parser
4
5#ifndef QJSONVALUE_H
6#define QJSONVALUE_H
7
8#include <QtCore/qcborvalue.h>
9#include <QtCore/qcompare.h>
10#include <QtCore/qglobal.h>
11#if (QT_VERSION < QT_VERSION_CHECK(7, 0, 0)) && !defined(QT_BOOTSTRAPPED)
12#include <QtCore/qjsondocument.h>
13#endif
14#include <QtCore/qjsonparseerror.h>
15#include <QtCore/qstring.h>
16#include <QtCore/qshareddata.h>
17
18QT_BEGIN_NAMESPACE
19
20class QVariant;
21class QJsonArray;
22class QJsonObject;
23class QCborContainerPrivate;
24
25namespace QJsonPrivate {
26class Value;
27}
28
29class Q_CORE_EXPORT QJsonValue
30{
31public:
32 enum Type {
33 Null = 0x0,
34 Bool = 0x1,
35 Double = 0x2,
36 String = 0x3,
37 Array = 0x4,
38 Object = 0x5,
39 Undefined = 0x80
40 };
41
42#if (QT_VERSION < QT_VERSION_CHECK(7, 0, 0)) && !defined(QT_BOOTSTRAPPED)
43 using JsonFormat = QJsonDocument::JsonFormat;
44#else
45 enum class JsonFormat {
46 Indented,
47 Compact,
48 };
49#endif
50
51 QJsonValue(Type = Null);
52 QJsonValue(bool b);
53 QJsonValue(double n);
54 QJsonValue(int n);
55 QJsonValue(qint64 v);
56 QJsonValue(const QString &s);
57 QJsonValue(QLatin1StringView s);
58#ifndef QT_NO_CAST_FROM_ASCII
59 QT_ASCII_CAST_WARN inline QJsonValue(const char *s)
60 : QJsonValue(QString::fromUtf8(s)) {}
61#endif
62 QJsonValue(const QJsonArray &a);
63 QJsonValue(QJsonArray &&a) noexcept;
64 QJsonValue(const QJsonObject &o);
65 QJsonValue(QJsonObject &&o) noexcept;
66
67 ~QJsonValue();
68
69 QJsonValue(const QJsonValue &other) noexcept;
70 QJsonValue &operator =(const QJsonValue &other) noexcept;
71
72 QJsonValue(QJsonValue &&other) noexcept;
73
74 QJsonValue &operator =(QJsonValue &&other) noexcept
75 {
76 swap(other);
77 return *this;
78 }
79
80 void swap(QJsonValue &other) noexcept;
81
82 static QJsonValue fromVariant(const QVariant &variant);
83 QVariant toVariant() const;
84
85 static QJsonValue fromJson(QByteArrayView json, QJsonParseError *error = nullptr);
86
87 QByteArray toJson(JsonFormat format = JsonFormat::Indented) const;
88
89 Type type() const;
90 inline bool isNull() const { return type() == Null; }
91 inline bool isBool() const { return type() == Bool; }
92 inline bool isDouble() const { return type() == Double; }
93 inline bool isString() const { return type() == String; }
94 inline bool isArray() const { return type() == Array; }
95 inline bool isObject() const { return type() == Object; }
96 inline bool isUndefined() const { return type() == Undefined; }
97
98 bool toBool(bool defaultValue = false) const;
99 int toInt(int defaultValue = 0) const;
100 qint64 toInteger(qint64 defaultValue = 0) const;
101 double toDouble(double defaultValue = 0) const;
102 QString toString() const;
103 QString toString(const QString &defaultValue) const;
104 QAnyStringView toStringView(QAnyStringView defaultValue = {}) const;
105 QJsonArray toArray() const;
106 QJsonArray toArray(const QJsonArray &defaultValue) const;
107 QJsonObject toObject() const;
108 QJsonObject toObject(const QJsonObject &defaultValue) const;
109
110 const QJsonValue operator[](const QString &key) const;
111 const QJsonValue operator[](QStringView key) const;
112 const QJsonValue operator[](QLatin1StringView key) const;
113 const QJsonValue operator[](qsizetype i) const;
114
115#if QT_CORE_REMOVED_SINCE(6, 8)
116 bool operator==(const QJsonValue &other) const;
117 bool operator!=(const QJsonValue &other) const;
118#endif
119
120private:
121 friend Q_CORE_EXPORT bool comparesEqual(const QJsonValue &lhs,
122 const QJsonValue &rhs);
123 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QJsonValue)
124
125 // avoid implicit conversions from char * to bool
126 QJsonValue(const void *) = delete;
127 friend class QJsonPrivate::Value;
128 friend class QJsonArray;
129 friend class QJsonObject;
130 friend class QCborValue;
131 friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
132 friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonValue &);
133
134 QCborValue value;
135
136 // Assert binary compatibility with pre-5.15 QJsonValue
137 static_assert(sizeof(QExplicitlySharedDataPointer<QCborContainerPrivate>) == sizeof(void *));
138 static_assert(sizeof(QCborValue::Type) == sizeof(QJsonValue::Type));
139};
140
141Q_DECLARE_SHARED(QJsonValue)
142
143class QJsonValueConstRef
144{
145public:
146 QJsonValueConstRef(const QJsonValueConstRef &) = default;
147 QJsonValueConstRef &operator=(const QJsonValueConstRef &) = delete;
148 inline operator QJsonValue() const { return concrete(self: *this); }
149
150 Q_CORE_EXPORT QVariant toVariant() const;
151 QJsonValue::Type type() const { return concreteType(self: *this); }
152 bool isNull() const { return type() == QJsonValue::Null; }
153 bool isBool() const { return type() == QJsonValue::Bool; }
154 bool isDouble() const { return type() == QJsonValue::Double; }
155 bool isString() const { return type() == QJsonValue::String; }
156 bool isArray() const { return type() == QJsonValue::Array; }
157 bool isObject() const { return type() == QJsonValue::Object; }
158 bool isUndefined() const { return type() == QJsonValue::Undefined; }
159
160 bool toBool(bool defaultValue = false) const
161 { return concreteBool(self: *this, defaultValue); }
162 int toInt(int defaultValue = 0) const
163 { return int(concreteInt(self: *this, defaultValue, clamp: true)); }
164 qint64 toInteger(qint64 defaultValue = 0) const
165 { return concreteInt(self: *this, defaultValue, clamp: false); }
166 double toDouble(double defaultValue = 0) const
167 { return concreteDouble(self: *this, defaultValue); }
168 QString toString(const QString &defaultValue = {}) const
169 { return concreteString(self: *this, defaultValue); }
170 QAnyStringView toStringView(QAnyStringView defaultValue = {}) const
171 { return concreteStringView(self: *this, defaultValue); }
172 Q_CORE_EXPORT QJsonArray toArray() const;
173 Q_CORE_EXPORT QJsonObject toObject() const;
174
175 const QJsonValue operator[](QStringView key) const { return concrete(self: *this)[key]; }
176 const QJsonValue operator[](QLatin1StringView key) const { return concrete(self: *this)[key]; }
177 const QJsonValue operator[](qsizetype i) const { return concrete(self: *this)[i]; }
178
179protected:
180 friend bool comparesEqual(const QJsonValueConstRef &lhs,
181 const QJsonValueConstRef &rhs)
182 {
183 return comparesEqual(lhs: concrete(self: lhs), rhs: concrete(self: rhs));
184 }
185 friend bool comparesEqual(const QJsonValueConstRef &lhs,
186 const QJsonValue &rhs)
187 {
188 return comparesEqual(lhs: concrete(self: lhs), rhs);
189 }
190 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QJsonValueConstRef)
191 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QJsonValueConstRef, QJsonValue)
192
193 Q_CORE_EXPORT static QJsonValue::Type
194 concreteType(QJsonValueConstRef self) noexcept Q_DECL_PURE_FUNCTION;
195 Q_CORE_EXPORT static bool
196 concreteBool(QJsonValueConstRef self, bool defaultValue) noexcept Q_DECL_PURE_FUNCTION;
197 Q_CORE_EXPORT static qint64
198 concreteInt(QJsonValueConstRef self, qint64 defaultValue, bool clamp) noexcept Q_DECL_PURE_FUNCTION;
199 Q_CORE_EXPORT static double
200 concreteDouble(QJsonValueConstRef self, double defaultValue) noexcept Q_DECL_PURE_FUNCTION;
201 Q_CORE_EXPORT static QString concreteString(QJsonValueConstRef self, const QString &defaultValue);
202 Q_CORE_EXPORT static QAnyStringView concreteStringView(QJsonValueConstRef self, QAnyStringView defaultValue);
203 Q_CORE_EXPORT static QJsonValue concrete(QJsonValueConstRef self) noexcept;
204
205 // for iterators
206 Q_CORE_EXPORT static QString objectKey(QJsonValueConstRef self);
207 QString objectKey() const { return objectKey(self: *this); }
208
209 Q_CORE_EXPORT static QAnyStringView objectKeyView(QJsonValueConstRef self);
210 QAnyStringView objectKeyView() const { return objectKeyView(self: *this); }
211
212#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
213 QJsonValueConstRef(QJsonArray *array, qsizetype idx)
214 : a(array), is_object(false), index(static_cast<quint64>(idx)) {}
215 QJsonValueConstRef(QJsonObject *object, qsizetype idx)
216 : o(object), is_object(true), index(static_cast<quint64>(idx)) {}
217
218 void rebind(QJsonValueConstRef other)
219 {
220 Q_ASSERT(is_object == other.is_object);
221 if (is_object)
222 o = other.o;
223 else
224 a = other.a;
225 index = other.index;
226 }
227
228 union {
229 QJsonArray *a;
230 QJsonObject *o;
231 void *d;
232 };
233 quint64 is_object : 1;
234 quint64 index : 63;
235#else
236 constexpr QJsonValueConstRef(QCborContainerPrivate *d, size_t index, bool is_object)
237 : d(d), is_object(is_object), index(index)
238 {}
239
240 // implemented in qjsonarray.h & qjsonobject.h, to get their d
241 QJsonValueConstRef(QJsonArray *array, qsizetype idx);
242 QJsonValueConstRef(QJsonObject *object, qsizetype idx);
243
244 void rebind(QJsonValueConstRef other)
245 {
246 d = other.d;
247 index = other.index;
248 }
249
250 QCborContainerPrivate *d = nullptr;
251 size_t is_object : 1;
252 size_t index : std::numeric_limits<size_t>::digits - 1;
253#endif
254
255 friend class QJsonArray;
256 friend class QJsonObject;
257 friend class QJsonPrivate::Value;
258};
259
260QT_WARNING_PUSH
261QT6_ONLY(QT_WARNING_DISABLE_MSVC(4275)) // non dll-interface class 'QJsonValueConstRef' used as base for dll-interface class 'QJsonValueRef'
262class QT6_ONLY(Q_CORE_EXPORT) QJsonValueRef : public QJsonValueConstRef
263{
264public:
265 QJsonValueRef(const QJsonValueRef &) = default;
266 QT7_ONLY(Q_CORE_EXPORT) QJsonValueRef &operator = (const QJsonValue &val);
267 QT7_ONLY(Q_CORE_EXPORT) QJsonValueRef &operator = (const QJsonValueRef &val);
268
269#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
270 // retained for binary compatibility (due to the Q_CORE_EXPORT) because at
271 // least one compiler emits and exports all inlines in an exported class
272
273 QJsonValueRef(QJsonArray *array, qsizetype idx)
274 : QJsonValueConstRef(array, idx) {}
275 QJsonValueRef(QJsonObject *object, qsizetype idx)
276 : QJsonValueConstRef(object, idx) {}
277
278 operator QJsonValue() const { return toValue(); }
279
280 QVariant toVariant() const;
281 inline QJsonValue::Type type() const { return QJsonValueConstRef::type(); }
282 inline bool isNull() const { return type() == QJsonValue::Null; }
283 inline bool isBool() const { return type() == QJsonValue::Bool; }
284 inline bool isDouble() const { return type() == QJsonValue::Double; }
285 inline bool isString() const { return type() == QJsonValue::String; }
286 inline bool isArray() const { return type() == QJsonValue::Array; }
287 inline bool isObject() const { return type() == QJsonValue::Object; }
288 inline bool isUndefined() const { return type() == QJsonValue::Undefined; }
289
290 inline bool toBool(bool defaultValue = false) const { return QJsonValueConstRef::toBool(defaultValue); }
291 inline int toInt(int defaultValue = 0) const { return QJsonValueConstRef::toInt(defaultValue); }
292 inline qint64 toInteger(qint64 defaultValue = 0) const { return QJsonValueConstRef::toInteger(defaultValue); }
293 inline double toDouble(double defaultValue = 0) const { return QJsonValueConstRef::toDouble(defaultValue); }
294 inline QString toString(const QString &defaultValue = {}) const { return QJsonValueConstRef::toString(defaultValue); }
295 QAnyStringView toStringView(QAnyStringView defaultValue = {}) const
296 { return QJsonValueConstRef::toStringView(defaultValue); }
297 QJsonArray toArray() const;
298 QJsonObject toObject() const;
299
300 const QJsonValue operator[](QStringView key) const { return QJsonValueConstRef::operator[](key); }
301 const QJsonValue operator[](QLatin1StringView key) const { return QJsonValueConstRef::operator[](key); }
302 const QJsonValue operator[](qsizetype i) const { return QJsonValueConstRef::operator[](i); }
303
304#if QT_CORE_REMOVED_SINCE(6, 8)
305 inline bool operator==(const QJsonValue &other) const { return comparesEqual(*this, other); }
306 inline bool operator!=(const QJsonValue &other) const { return !comparesEqual(*this, other); }
307#endif
308
309private:
310 friend bool comparesEqual(const QJsonValueRef &lhs, const QJsonValueRef &rhs)
311 {
312 return comparesEqual(lhs: QJsonValue(lhs), rhs: QJsonValue(rhs));
313 }
314 friend bool comparesEqual(const QJsonValueRef &lhs, const QJsonValueConstRef &rhs)
315 {
316 return comparesEqual(lhs: QJsonValue(lhs), rhs: QJsonValue(rhs));
317 }
318 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QJsonValueRef)
319 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QJsonValueRef, QJsonValueConstRef)
320
321 QJsonValue toValue() const;
322#else
323 using QJsonValueConstRef::operator[];
324 Q_CORE_EXPORT QJsonValueRef operator[](QAnyStringView key);
325 Q_CORE_EXPORT QJsonValueRef operator[](qsizetype i);
326
327private:
328 using QJsonValueConstRef::QJsonValueConstRef;
329#endif // < Qt 7
330
331 QT7_ONLY(Q_CORE_EXPORT) void detach();
332 friend class QJsonArray;
333 friend class QJsonObject;
334};
335QT_WARNING_POP
336
337inline QJsonValue QCborValueConstRef::toJsonValue() const
338{
339 return concrete().toJsonValue();
340}
341
342Q_CORE_EXPORT size_t qHash(const QJsonValue &value, size_t seed = 0);
343
344#if !defined(QT_NO_DEBUG_STREAM)
345Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
346#endif
347
348#ifndef QT_NO_DATASTREAM
349Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonValue &);
350Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonValue &);
351#endif
352
353QT_END_NAMESPACE
354
355#endif // QJSONVALUE_H
356

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