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 QJSONOBJECT_H
6#define QJSONOBJECT_H
7
8#include <QtCore/qjsonvalue.h>
9#include <QtCore/qiterator.h>
10#include <QtCore/qpair.h>
11#include <QtCore/qshareddata.h>
12#include <initializer_list>
13
14QT_BEGIN_NAMESPACE
15
16class QDebug;
17
18class QCborContainerPrivate;
19
20namespace QtPrivate {
21
22template <typename T, typename Iterator>
23struct QJsonObjectKeyValues
24{
25 static QAnyStringView key(const Iterator &it) { return it.keyView(); }
26 static QAnyStringView key(Iterator &it) { return it.keyView(); }
27 static T value(const Iterator &it) { return it.value(); }
28 static T value(Iterator &it) { return it.value(); }
29};
30
31} // namespace QtPrivate
32
33class Q_CORE_EXPORT QJsonObject
34{
35public:
36 QJsonObject();
37
38 QJsonObject(std::initializer_list<std::pair<QString, QJsonValue> > args);
39
40 ~QJsonObject();
41
42 QJsonObject(const QJsonObject &other) noexcept;
43 QJsonObject &operator =(const QJsonObject &other) noexcept;
44
45 QJsonObject(QJsonObject &&other) noexcept;
46
47 QJsonObject &operator =(QJsonObject &&other) noexcept
48 {
49 swap(other);
50 return *this;
51 }
52
53 void swap(QJsonObject &other) noexcept
54 {
55 o.swap(other&: other.o);
56 }
57
58 static QJsonObject fromVariantMap(const QVariantMap &map);
59 QVariantMap toVariantMap() const;
60 static QJsonObject fromVariantHash(const QVariantHash &map);
61 QVariantHash toVariantHash() const;
62
63 QStringList keys() const;
64 qsizetype size() const;
65 inline qsizetype count() const { return size(); }
66 inline qsizetype length() const { return size(); }
67 bool isEmpty() const;
68
69 QJsonValue value(const QString &key) const;
70 QJsonValue operator[] (const QString &key) const;
71 QJsonValueRef operator[] (const QString &key);
72 QJsonValue value(QStringView key) const;
73 QJsonValue value(QLatin1StringView key) const;
74 QJsonValue operator[] (QStringView key) const { return value(key); }
75 QJsonValue operator[] (QLatin1StringView key) const { return value(key); }
76 QJsonValueRef operator[] (QStringView key);
77 QJsonValueRef operator[] (QLatin1StringView key);
78
79 void remove(const QString &key);
80 QJsonValue take(const QString &key);
81 bool contains(const QString &key) const;
82 void remove(QStringView key);
83 void remove(QLatin1StringView key);
84 QJsonValue take(QStringView key);
85 QJsonValue take(QLatin1StringView key);
86 bool contains(QStringView key) const;
87 bool contains(QLatin1StringView key) const;
88
89#if QT_CORE_REMOVED_SINCE(6, 8)
90 bool operator==(const QJsonObject &other) const;
91 bool operator!=(const QJsonObject &other) const;
92#endif
93 class const_iterator;
94
95 class iterator
96 {
97 friend class const_iterator;
98 friend class QJsonObject;
99 QJsonValueRef item;
100
101 public:
102 typedef std::random_access_iterator_tag iterator_category;
103 typedef qsizetype difference_type;
104 typedef QJsonValue value_type;
105 typedef QJsonValueRef reference;
106 typedef QJsonValueRef *pointer;
107
108 inline iterator() : item(static_cast<QJsonObject*>(nullptr), 0) { }
109 inline iterator(QJsonObject *obj, qsizetype index) : item(obj, index) { }
110
111 constexpr iterator(const iterator &other) = default;
112 iterator &operator=(const iterator &other)
113 {
114 item.rebind(other: other.item);
115 return *this;
116 }
117
118 inline QString key() const { return item.objectKey(); }
119 QAnyStringView keyView() const { return item.objectKeyView(); }
120 inline QJsonValueRef value() const { return item; }
121 inline QJsonValueRef operator*() const { return item; }
122 inline const QJsonValueConstRef *operator->() const { return &item; }
123 inline QJsonValueRef *operator->() { return &item; }
124 inline QJsonValueRef operator[](qsizetype j) const { return *(*this + j); }
125#if QT_CORE_REMOVED_SINCE(6, 8)
126 inline bool operator==(const iterator &other) const
127 { return item.d == other.item.d && item.index == other.item.index; }
128 inline bool operator!=(const iterator &other) const { return !operator==(other); }
129 bool operator<(const iterator& other) const
130 { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; }
131 bool operator<=(const iterator& other) const
132 { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; }
133 bool operator>(const iterator& other) const { return !operator<=(other); }
134 bool operator>=(const iterator& other) const { return !operator<(other); }
135#endif
136 inline iterator &operator++() { ++item.index; return *this; }
137 inline iterator operator++(int) { iterator r = *this; ++item.index; return r; }
138 inline iterator &operator--() { --item.index; return *this; }
139 inline iterator operator--(int) { iterator r = *this; --item.index; return r; }
140 inline iterator operator+(qsizetype j) const { iterator r = *this; return r += j; }
141 inline iterator operator-(qsizetype j) const { return operator+(j: -j); }
142 inline iterator &operator+=(qsizetype j) { item.index += quint64(j); return *this; }
143 inline iterator &operator-=(qsizetype j) { item.index -= quint64(j); return *this; }
144 qsizetype operator-(iterator j) const { return item.index - j.item.index; }
145
146 public:
147#if QT_CORE_REMOVED_SINCE(6, 8)
148 inline bool operator==(const const_iterator &other) const
149 { return item.d == other.item.d && item.index == other.item.index; }
150 inline bool operator!=(const const_iterator &other) const { return !operator==(other); }
151 bool operator<(const const_iterator& other) const
152 { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; }
153 bool operator<=(const const_iterator& other) const
154 { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; }
155 bool operator>(const const_iterator& other) const { return operator<=(other); }
156 bool operator>=(const const_iterator& other) const { return operator<(other); }
157#endif
158 private:
159 // Helper functions
160 static bool comparesEqual_helper(const iterator &lhs, const iterator &rhs) noexcept
161 {
162 return lhs.item.d == rhs.item.d && lhs.item.index == rhs.item.index;
163 }
164 static bool comparesEqual_helper(const iterator &lhs, const const_iterator &rhs) noexcept
165 {
166 return lhs.item.d == rhs.item.d && lhs.item.index == rhs.item.index;
167 }
168
169 static Qt::strong_ordering compareThreeWay_helper(const iterator &lhs,
170 const iterator &rhs)
171 {
172 Q_ASSERT(lhs.item.d == rhs.item.d);
173 return Qt::compareThreeWay(lhs: lhs.item.index, rhs: rhs.item.index);
174 }
175 static Qt::strong_ordering compareThreeWay_helper(const iterator &lhs,
176 const const_iterator &rhs)
177 {
178 Q_ASSERT(lhs.item.d == rhs.item.d);
179 return Qt::compareThreeWay(lhs: lhs.item.index, rhs: rhs.item.index);
180 }
181
182 // Compare friends
183 friend bool comparesEqual(const iterator &lhs, const iterator &rhs) noexcept
184 {
185 return comparesEqual_helper(lhs, rhs);
186 }
187 friend Qt::strong_ordering compareThreeWay(const iterator &lhs,
188 const iterator &rhs)
189 {
190 return compareThreeWay_helper(lhs, rhs);
191 }
192 Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(iterator)
193
194 friend bool comparesEqual(const iterator &lhs, const const_iterator &rhs) noexcept
195 {
196 return comparesEqual_helper(lhs, rhs);
197 }
198 friend Qt::strong_ordering compareThreeWay(const iterator &lhs,
199 const const_iterator &rhs)
200 {
201 return compareThreeWay_helper(lhs, rhs);
202 }
203 Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(iterator, const_iterator)
204 };
205 friend class iterator;
206
207 class const_iterator
208 {
209 friend class iterator;
210 QJsonValueConstRef item;
211
212 public:
213 typedef std::random_access_iterator_tag iterator_category;
214 typedef qsizetype difference_type;
215 typedef QJsonValue value_type;
216 typedef const QJsonValueConstRef reference;
217 typedef const QJsonValueConstRef *pointer;
218
219 inline const_iterator() : item(static_cast<QJsonObject*>(nullptr), 0) { }
220 inline const_iterator(const QJsonObject *obj, qsizetype index)
221 : item(const_cast<QJsonObject*>(obj), index) { }
222 inline const_iterator(const iterator &other)
223 : item(other.item) { }
224
225 constexpr const_iterator(const const_iterator &other) = default;
226 const_iterator &operator=(const const_iterator &other)
227 {
228 item.rebind(other: other.item);
229 return *this;
230 }
231
232 inline QString key() const { return item.objectKey(); }
233 QAnyStringView keyView() const { return item.objectKeyView(); }
234 inline QJsonValueConstRef value() const { return item; }
235 inline const QJsonValueConstRef operator*() const { return item; }
236 inline const QJsonValueConstRef *operator->() const { return &item; }
237 inline QJsonValueConstRef operator[](qsizetype j) const { return *(*this + j); }
238#if QT_CORE_REMOVED_SINCE(6, 8)
239 inline bool operator==(const const_iterator &other) const
240 { return item.d == other.item.d && item.index == other.item.index; }
241 inline bool operator!=(const const_iterator &other) const { return !operator==(other); }
242 bool operator<(const const_iterator& other) const
243 { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; }
244 bool operator<=(const const_iterator& other) const
245 { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; }
246 bool operator>(const const_iterator& other) const { return !operator<=(other); }
247 bool operator>=(const const_iterator& other) const { return !operator<(other); }
248#endif
249 inline const_iterator &operator++() { ++item.index; return *this; }
250 inline const_iterator operator++(int) { const_iterator r = *this; ++item.index; return r; }
251 inline const_iterator &operator--() { --item.index; return *this; }
252 inline const_iterator operator--(int) { const_iterator r = *this; --item.index; return r; }
253 inline const_iterator operator+(qsizetype j) const { const_iterator r = *this; return r += j; }
254 inline const_iterator operator-(qsizetype j) const { return operator+(j: -j); }
255 inline const_iterator &operator+=(qsizetype j) { item.index += quint64(j); return *this; }
256 inline const_iterator &operator-=(qsizetype j) { item.index -= quint64(j); return *this; }
257 qsizetype operator-(const_iterator j) const { return item.index - j.item.index; }
258#if QT_CORE_REMOVED_SINCE(6, 8)
259 inline bool operator==(const iterator &other) const
260 { return item.d == other.item.d && item.index == other.item.index; }
261 inline bool operator!=(const iterator &other) const { return !operator==(other); }
262 bool operator<(const iterator& other) const
263 { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; }
264 bool operator<=(const iterator& other) const
265 { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; }
266 bool operator>(const iterator& other) const { return !operator<=(other); }
267 bool operator>=(const iterator& other) const { return !operator<(other); }
268#endif
269
270 private:
271 // Helper functions
272 static bool comparesEqual_helper(const const_iterator &lhs,
273 const const_iterator &rhs) noexcept
274 {
275 return lhs.item.d == rhs.item.d && lhs.item.index == rhs.item.index;
276 }
277 static Qt::strong_ordering compareThreeWay_helper(const const_iterator &lhs,
278 const const_iterator &rhs)
279 {
280 Q_ASSERT(lhs.item.d == rhs.item.d);
281 return Qt::compareThreeWay(lhs: lhs.item.index, rhs: rhs.item.index);
282 }
283
284 // Compare friends
285 friend bool comparesEqual(const const_iterator &lhs, const const_iterator &rhs) noexcept
286 {
287 return comparesEqual_helper(lhs, rhs);
288 }
289 friend Qt::strong_ordering compareThreeWay(const const_iterator &lhs,
290 const const_iterator &rhs)
291 {
292 return compareThreeWay_helper(lhs, rhs);
293 }
294 Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(const_iterator)
295 };
296 friend class const_iterator;
297
298 typedef QKeyValueIterator<QAnyStringView, QJsonValueConstRef, const_iterator,
299 QtPrivate::QJsonObjectKeyValues<QJsonValueConstRef, const_iterator>>
300 const_key_value_iterator;
301 typedef QKeyValueIterator<QAnyStringView, QJsonValueRef, iterator,
302 QtPrivate::QJsonObjectKeyValues<QJsonValueRef, iterator>>
303 key_value_iterator;
304
305 // STL style
306 inline iterator begin() { detach(); return iterator(this, 0); }
307 inline const_iterator begin() const { return const_iterator(this, 0); }
308 inline const_iterator constBegin() const { return const_iterator(this, 0); }
309 inline iterator end() { detach(); return iterator(this, size()); }
310 inline const_iterator end() const { return const_iterator(this, size()); }
311 inline const_iterator constEnd() const { return const_iterator(this, size()); }
312 key_value_iterator keyValueBegin() { return key_value_iterator(begin()); }
313 key_value_iterator keyValueEnd() { return key_value_iterator(end()); }
314 const_key_value_iterator keyValueBegin() const { return const_key_value_iterator(begin()); }
315 const_key_value_iterator constKeyValueBegin() const
316 {
317 return const_key_value_iterator(begin());
318 }
319 const_key_value_iterator keyValueEnd() const { return const_key_value_iterator(end()); }
320 const_key_value_iterator constKeyValueEnd() const { return const_key_value_iterator(end()); }
321 iterator erase(iterator it);
322
323 auto asKeyValueRange() & { return QtPrivate::QKeyValueRange<QJsonObject &>(*this); }
324 auto asKeyValueRange() const & { return QtPrivate::QKeyValueRange<const QJsonObject &>(*this); }
325 auto asKeyValueRange() && { return QtPrivate::QKeyValueRange<QJsonObject>(std::move(*this)); }
326 auto asKeyValueRange() const &&
327 {
328 return QtPrivate::QKeyValueRange<QJsonObject>(std::move(*this));
329 }
330
331 // more Qt
332 typedef iterator Iterator;
333 typedef const_iterator ConstIterator;
334 iterator find(const QString &key);
335 const_iterator find(const QString &key) const { return constFind(key); }
336 const_iterator constFind(const QString &key) const;
337 iterator insert(const QString &key, const QJsonValue &value);
338 iterator find(QStringView key);
339 iterator find(QLatin1StringView key);
340 const_iterator find(QStringView key) const { return constFind(key); }
341 const_iterator find(QLatin1StringView key) const { return constFind(key); }
342 const_iterator constFind(QStringView key) const;
343 const_iterator constFind(QLatin1StringView key) const;
344 iterator insert(QStringView key, const QJsonValue &value);
345 iterator insert(QLatin1StringView key, const QJsonValue &value);
346
347 // STL compatibility
348 typedef QJsonValue mapped_type;
349 typedef QString key_type;
350 typedef qsizetype size_type;
351
352 inline bool empty() const { return isEmpty(); }
353
354private:
355 friend Q_CORE_EXPORT bool comparesEqual(const QJsonObject &lhs,
356 const QJsonObject &rhs);
357 friend bool comparesEqual(const QJsonObject &lhs, const QJsonValue &rhs)
358 {
359 return comparesEqual(lhs, rhs: rhs.toObject());
360 }
361 friend bool comparesEqual(const QJsonObject &lhs, const QJsonValueConstRef &rhs)
362 {
363 return comparesEqual(lhs, rhs: rhs.toObject());
364 }
365 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QJsonObject)
366 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QJsonObject, QJsonValue)
367 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QJsonObject, QJsonValueConstRef)
368 friend class QJsonValue;
369 friend class QJsonDocument;
370 friend class QJsonPrivate::Value;
371 friend class QJsonValueConstRef;
372 friend class QJsonValueRef;
373 friend class QCborMap;
374 friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
375
376 QJsonObject(QCborContainerPrivate *object);
377 bool detach(qsizetype reserve = 0);
378
379 template <typename T> QJsonValue valueImpl(T key) const;
380 template <typename T> QJsonValueRef atImpl(T key);
381 template <typename T> void removeImpl(T key);
382 template <typename T> QJsonValue takeImpl(T key);
383 template <typename T> bool containsImpl(T key) const;
384 template <typename T> iterator findImpl(T key);
385 template <typename T> const_iterator constFindImpl(T key) const;
386 template <typename T> iterator insertImpl(T key, const QJsonValue &value);
387
388#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
389 QString keyAt(qsizetype i) const;
390 QJsonValue valueAt(qsizetype i) const;
391 void setValueAt(qsizetype i, const QJsonValue &val);
392#endif
393 void removeAt(qsizetype i);
394 template <typename T> iterator insertAt(qsizetype i, T key, const QJsonValue &val, bool exists);
395
396 QExplicitlySharedDataPointer<QCborContainerPrivate> o;
397};
398
399Q_DECLARE_SHARED(QJsonObject)
400
401#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED)
402inline QJsonValueConstRef::QJsonValueConstRef(QJsonObject *o, qsizetype idx)
403 : d(o ? o->o.data() : nullptr), is_object(true), index(idx)
404{}
405#endif
406
407Q_CORE_EXPORT size_t qHash(const QJsonObject &object, size_t seed = 0);
408
409#if !defined(QT_NO_DEBUG_STREAM)
410Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
411#endif
412
413#ifndef QT_NO_DATASTREAM
414Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonObject &);
415Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonObject &);
416#endif
417
418QT_END_NAMESPACE
419
420#endif // QJSONOBJECT_H
421

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