json/qjsonobject.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
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 Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include <qjsonobject.h> -
43#include <qjsonvalue.h> -
44#include <qjsonarray.h> -
45#include <qstringlist.h> -
46#include <qdebug.h> -
47#include <qvariant.h> -
48#include "qjson_p.h" -
49#include "qjsonwriter_p.h" -
50 -
51QT_BEGIN_NAMESPACE -
52 -
53/*! -
54 \class QJsonObject -
55 \inmodule QtCore -
56 \ingroup json -
57 \reentrant -
58 \since 5.0 -
59 -
60 \brief The QJsonObject class encapsulates a JSON object. -
61 -
62 A JSON object is a list of key value pairs, where the keys are unique strings -
63 and the values are represented by a QJsonValue. -
64 -
65 A QJsonObject can be converted to and from a QVariantMap. You can query the -
66 number of (key, value) pairs with size(), insert(), and remove() entries from it -
67 and iterate over its content using the standard C++ iterator pattern. -
68 -
69 QJsonObject is an implicitly shared class, and shares the data with the document -
70 it has been created from as long as it is not being modified. -
71 -
72 You can convert the array to and from text based JSON through QJsonDocument. -
73*/ -
74 -
75/*! -
76 \typedef QJsonObject::Iterator -
77 -
78 Qt-style synonym for QJsonObject::iterator. -
79*/ -
80 -
81/*! -
82 \typedef QJsonObject::ConstIterator -
83 -
84 Qt-style synonym for QJsonObject::const_iterator. -
85*/ -
86 -
87/*! -
88 \typedef QJsonObject::key_type -
89 -
90 Typedef for QString. Provided for STL compatibility. -
91*/ -
92 -
93/*! -
94 \typedef QJsonObject::mapped_type -
95 -
96 Typedef for QJsonValue. Provided for STL compatibility. -
97*/ -
98 -
99/*! -
100 \typedef QJsonObject::size_type -
101 -
102 Typedef for int. Provided for STL compatibility. -
103*/ -
104 -
105 -
106/*! -
107 Constructs an empty JSON object -
108 -
109 \sa isEmpty() -
110 */ -
111QJsonObject::QJsonObject() -
112 : d(0), o(0) -
113{ -
114}
executed: }
Execution Count:12178
12178
115 -
116/*! -
117 \internal -
118 */ -
119QJsonObject::QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object) -
120 : d(data), o(object) -
121{ -
122 Q_ASSERT(d);
executed (the execution status of this line is deduced): qt_noop();
-
123 Q_ASSERT(o);
executed (the execution status of this line is deduced): qt_noop();
-
124 d->ref.ref();
executed (the execution status of this line is deduced): d->ref.ref();
-
125}
executed: }
Execution Count:15208
15208
126 -
127 -
128/*! -
129 Destroys the object. -
130 */ -
131QJsonObject::~QJsonObject() -
132{ -
133 if (d && !d->ref.deref())
evaluated: d
TRUEFALSE
yes
Evaluation Count:28290
yes
Evaluation Count:12051
evaluated: !d->ref.deref()
TRUEFALSE
yes
Evaluation Count:1947
yes
Evaluation Count:26343
1947-28290
134 delete d;
executed: delete d;
Execution Count:1947
1947
135}
executed: }
Execution Count:40341
40341
136 -
137/*! -
138 Creates a copy of \a other. -
139 -
140 Since QJsonObject is implicitly shared, the copy is shallow -
141 as long as the object does not get modified. -
142 */ -
143QJsonObject::QJsonObject(const QJsonObject &other) -
144{ -
145 d = other.d;
executed (the execution status of this line is deduced): d = other.d;
-
146 o = other.o;
executed (the execution status of this line is deduced): o = other.o;
-
147 if (d)
evaluated: d
TRUEFALSE
yes
Evaluation Count:11148
yes
Evaluation Count:8
8-11148
148 d->ref.ref();
executed: d->ref.ref();
Execution Count:11148
11148
149}
executed: }
Execution Count:11156
11156
150 -
151/*! -
152 Assigns \a other to this object. -
153 */ -
154QJsonObject &QJsonObject::operator =(const QJsonObject &other) -
155{ -
156 if (d != other.d) {
evaluated: d != other.d
TRUEFALSE
yes
Evaluation Count:229
yes
Evaluation Count:3
3-229
157 if (d && !d->ref.deref())
evaluated: d
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:228
partially evaluated: !d->ref.deref()
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-228
158 delete d;
executed: delete d;
Execution Count:1
1
159 d = other.d;
executed (the execution status of this line is deduced): d = other.d;
-
160 if (d)
partially evaluated: d
TRUEFALSE
yes
Evaluation Count:229
no
Evaluation Count:0
0-229
161 d->ref.ref();
executed: d->ref.ref();
Execution Count:229
229
162 }
executed: }
Execution Count:229
229
163 o = other.o;
executed (the execution status of this line is deduced): o = other.o;
-
164 -
165 return *this;
executed: return *this;
Execution Count:232
232
166} -
167 -
168/*! -
169 Converts the variant map \a map to a QJsonObject. -
170 -
171 The keys in \a map will be used as the keys in the JSON object, -
172 and the QVariant values will be converted to JSON values. -
173 -
174 \sa toVariantMap(), QJsonValue::fromVariant() -
175 */ -
176QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map) -
177{ -
178 // ### this is implemented the trivial way, not the most efficient way -
179 -
180 QJsonObject object;
executed (the execution status of this line is deduced): QJsonObject object;
-
181 for (QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it)
evaluated: it != map.constEnd()
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:2
2-5
182 object.insert(it.key(), QJsonValue::fromVariant(it.value()));
executed: object.insert(it.key(), QJsonValue::fromVariant(it.value()));
Execution Count:5
5
183 return object;
executed: return object;
Execution Count:2
2
184} -
185 -
186/*! -
187 Converts this object to a QVariantMap. -
188 -
189 Returns the created map. -
190 */ -
191QVariantMap QJsonObject::toVariantMap() const -
192{ -
193 QVariantMap map;
executed (the execution status of this line is deduced): QVariantMap map;
-
194 if (o) {
evaluated: o
TRUEFALSE
yes
Evaluation Count:867
yes
Evaluation Count:1
1-867
195 for (uint i = 0; i < o->length; ++i) {
evaluated: i < o->length
TRUEFALSE
yes
Evaluation Count:2663
yes
Evaluation Count:867
867-2663
196 QJsonPrivate::Entry *e = o->entryAt(i);
executed (the execution status of this line is deduced): QJsonPrivate::Entry *e = o->entryAt(i);
-
197 map.insert(e->key(), QJsonValue(d, o, e->value).toVariant());
executed (the execution status of this line is deduced): map.insert(e->key(), QJsonValue(d, o, e->value).toVariant());
-
198 }
executed: }
Execution Count:2663
2663
199 }
executed: }
Execution Count:867
867
200 return map;
executed: return map;
Execution Count:868
868
201} -
202 -
203/*! -
204 Returns a list of all keys in this object. -
205 */ -
206QStringList QJsonObject::keys() const -
207{ -
208 if (!d)
evaluated: !d
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:5
1-5
209 return QStringList();
executed: return QStringList();
Execution Count:1
1
210 -
211 QStringList keys;
executed (the execution status of this line is deduced): QStringList keys;
-
212 -
213 for (uint i = 0; i < o->length; ++i) {
evaluated: i < o->length
TRUEFALSE
yes
Evaluation Count:6
yes
Evaluation Count:5
5-6
214 QJsonPrivate::Entry *e = o->entryAt(i);
executed (the execution status of this line is deduced): QJsonPrivate::Entry *e = o->entryAt(i);
-
215 keys.append(e->key());
executed (the execution status of this line is deduced): keys.append(e->key());
-
216 }
executed: }
Execution Count:6
6
217 -
218 return keys;
executed: return keys;
Execution Count:5
5
219} -
220 -
221/*! -
222 Returns the number of (key, value) pairs stored in the object. -
223 */ -
224int QJsonObject::size() const -
225{ -
226 if (!d)
evaluated: !d
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:63
1-63
227 return 0;
executed: return 0;
Execution Count:1
1
228 -
229 return o->length;
executed: return o->length;
Execution Count:63
63
230} -
231 -
232/*! -
233 Returns \c true if the object is empty. This is the same as size() == 0. -
234 -
235 \sa size() -
236 */ -
237bool QJsonObject::isEmpty() const -
238{ -
239 if (!d)
partially evaluated: !d
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:13
0-13
240 return true;
never executed: return true;
0
241 -
242 return !o->length;
executed: return !o->length;
Execution Count:13
13
243} -
244 -
245/*! -
246 Returns a QJsonValue representing the value for the key \a key. -
247 -
248 The returned QJsonValue is \c Undefined, if the key does not exist. -
249 -
250 \sa QJsonValue, QJsonValue::isUndefined() -
251 */ -
252QJsonValue QJsonObject::value(const QString &key) const -
253{ -
254 if (!d)
evaluated: !d
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:28515
1-28515
255 return QJsonValue();
executed: return QJsonValue();
Execution Count:1
1
256 -
257 bool keyExists;
executed (the execution status of this line is deduced): bool keyExists;
-
258 int i = o->indexOf(key, &keyExists);
executed (the execution status of this line is deduced): int i = o->indexOf(key, &keyExists);
-
259 if (!keyExists)
evaluated: !keyExists
TRUEFALSE
yes
Evaluation Count:160
yes
Evaluation Count:28355
160-28355
260 return QJsonValue(QJsonValue::Undefined);
executed: return QJsonValue(QJsonValue::Undefined);
Execution Count:160
160
261 return QJsonValue(d, o, o->entryAt(i)->value);
executed: return QJsonValue(d, o, o->entryAt(i)->value);
Execution Count:28355
28355
262} -
263 -
264/*! -
265 Returns a QJsonValue representing the value for the key \a key. -
266 -
267 This does the same as value(). -
268 -
269 The returned QJsonValue is \c Undefined, if the key does not exist. -
270 -
271 \sa value(), QJsonValue, QJsonValue::isUndefined() -
272 */ -
273QJsonValue QJsonObject::operator [](const QString &key) const -
274{ -
275 return value(key);
never executed: return value(key);
0
276} -
277 -
278/*! -
279 Returns a reference to the value for \a key. -
280 -
281 The return value is of type QJsonValueRef, a helper class for QJsonArray -
282 and QJsonObject. When you get an object of type QJsonValueRef, you can -
283 use it as if it were a reference to a QJsonValue. If you assign to it, -
284 the assignment will apply to the character in the QJsonArray of QJsonObject -
285 from which you got the reference. -
286 -
287 \sa value() -
288 */ -
289QJsonValueRef QJsonObject::operator [](const QString &key) -
290{ -
291 // ### somewhat inefficient, as we lookup the key twice if it doesn't yet exist -
292 bool keyExists = false;
executed (the execution status of this line is deduced): bool keyExists = false;
-
293 int index = o ? o->indexOf(key, &keyExists) : -1;
evaluated: o
TRUEFALSE
yes
Evaluation Count:22
yes
Evaluation Count:3
3-22
294 if (!keyExists) {
evaluated: !keyExists
TRUEFALSE
yes
Evaluation Count:21
yes
Evaluation Count:4
4-21
295 iterator i = insert(key, QJsonValue());
executed (the execution status of this line is deduced): iterator i = insert(key, QJsonValue());
-
296 index = i.i;
executed (the execution status of this line is deduced): index = i.i;
-
297 }
executed: }
Execution Count:21
21
298 return QJsonValueRef(this, index);
executed: return QJsonValueRef(this, index);
Execution Count:25
25
299} -
300 -
301/*! -
302 Inserts a new item with the key \a key and a value of \a value. -
303 -
304 If there is already an item with the key \a key then that item's value -
305 is replaced with \a value. -
306 -
307 Returns an iterator pointing to the inserted item. -
308 -
309 If the value is QJsonValue::Undefined, it will cause the key to get removed -
310 from the object. The returned iterator will then point to end() -
311 -
312 \sa remove(), take(), QJsonObject::iterator, end() -
313 */ -
314QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &value) -
315{ -
316 if (value.t == QJsonValue::Undefined) {
evaluated: value.t == QJsonValue::Undefined
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:220
2-220
317 remove(key);
executed (the execution status of this line is deduced): remove(key);
-
318 return end();
executed: return end();
Execution Count:2
2
319 } -
320 -
321 bool latinOrIntValue;
executed (the execution status of this line is deduced): bool latinOrIntValue;
-
322 int valueSize = QJsonPrivate::Value::requiredStorage(value, &latinOrIntValue);
executed (the execution status of this line is deduced): int valueSize = QJsonPrivate::Value::requiredStorage(value, &latinOrIntValue);
-
323 -
324 bool latinKey = QJsonPrivate::useCompressed(key);
executed (the execution status of this line is deduced): bool latinKey = QJsonPrivate::useCompressed(key);
-
325 int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey);
executed (the execution status of this line is deduced): int valueOffset = sizeof(QJsonPrivate::Entry) + QJsonPrivate::qStringSize(key, latinKey);
-
326 int requiredSize = valueOffset + valueSize;
executed (the execution status of this line is deduced): int requiredSize = valueOffset + valueSize;
-
327 -
328 detach(requiredSize + sizeof(QJsonPrivate::offset)); // offset for the new index entry
executed (the execution status of this line is deduced): detach(requiredSize + sizeof(QJsonPrivate::offset));
-
329 -
330 if (!o->length)
evaluated: !o->length
TRUEFALSE
yes
Evaluation Count:71
yes
Evaluation Count:149
71-149
331 o->tableOffset = sizeof(QJsonPrivate::Object);
executed: o->tableOffset = sizeof(QJsonPrivate::Object);
Execution Count:71
71
332 -
333 bool keyExists = false;
executed (the execution status of this line is deduced): bool keyExists = false;
-
334 int pos = o->indexOf(key, &keyExists);
executed (the execution status of this line is deduced): int pos = o->indexOf(key, &keyExists);
-
335 if (keyExists)
evaluated: keyExists
TRUEFALSE
yes
Evaluation Count:93
yes
Evaluation Count:127
93-127
336 ++d->compactionCounter;
executed: ++d->compactionCounter;
Execution Count:93
93
337 -
338 o->reserveSpace(requiredSize, pos, 1, keyExists);
executed (the execution status of this line is deduced): o->reserveSpace(requiredSize, pos, 1, keyExists);
-
339 -
340 QJsonPrivate::Entry *e = o->entryAt(pos);
executed (the execution status of this line is deduced): QJsonPrivate::Entry *e = o->entryAt(pos);
-
341 e->value.type = value.t;
executed (the execution status of this line is deduced): e->value.type = value.t;
-
342 e->value.latinKey = latinKey;
executed (the execution status of this line is deduced): e->value.latinKey = latinKey;
-
343 e->value.latinOrIntValue = latinOrIntValue;
executed (the execution status of this line is deduced): e->value.latinOrIntValue = latinOrIntValue;
-
344 e->value.value = QJsonPrivate::Value::valueToStore(value, (char *)e - (char *)o + valueOffset);
executed (the execution status of this line is deduced): e->value.value = QJsonPrivate::Value::valueToStore(value, (char *)e - (char *)o + valueOffset);
-
345 QJsonPrivate::copyString((char *)(e + 1), key, latinKey);
executed (the execution status of this line is deduced): QJsonPrivate::copyString((char *)(e + 1), key, latinKey);
-
346 if (valueSize)
evaluated: valueSize
TRUEFALSE
yes
Evaluation Count:152
yes
Evaluation Count:68
68-152
347 QJsonPrivate::Value::copyData(value, (char *)e + valueOffset, latinOrIntValue);
executed: QJsonPrivate::Value::copyData(value, (char *)e + valueOffset, latinOrIntValue);
Execution Count:152
152
348 -
349 return iterator(this, pos);
executed: return iterator(this, pos);
Execution Count:220
220
350} -
351 -
352/*! -
353 Removes \a key from the object. -
354 -
355 \sa insert(), take() -
356 */ -
357void QJsonObject::remove(const QString &key) -
358{ -
359 if (!d)
evaluated: !d
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:44
3-44
360 return;
executed: return;
Execution Count:3
3
361 -
362 bool keyExists;
executed (the execution status of this line is deduced): bool keyExists;
-
363 int index = o->indexOf(key, &keyExists);
executed (the execution status of this line is deduced): int index = o->indexOf(key, &keyExists);
-
364 if (!keyExists)
evaluated: !keyExists
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:42
2-42
365 return;
executed: return;
Execution Count:2
2
366 -
367 detach();
executed (the execution status of this line is deduced): detach();
-
368 o->removeItems(index, 1);
executed (the execution status of this line is deduced): o->removeItems(index, 1);
-
369 ++d->compactionCounter;
executed (the execution status of this line is deduced): ++d->compactionCounter;
-
370 if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u)
partially evaluated: d->compactionCounter > 32u
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:42
never evaluated: d->compactionCounter >= unsigned(o->length) / 2u
0-42
371 compact();
never executed: compact();
0
372}
executed: }
Execution Count:42
42
373 -
374/*! -
375 Removes \a key from the object. -
376 -
377 Returns a QJsonValue containing the value referenced by \a key. -
378 If \a key was not contained in the object, the returned QJsonValue -
379 is Undefined. -
380 -
381 \sa insert(), remove(), QJsonValue -
382 */ -
383QJsonValue QJsonObject::take(const QString &key) -
384{ -
385 if (!o)
evaluated: !o
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:3
1-3
386 return QJsonValue(QJsonValue::Undefined);
executed: return QJsonValue(QJsonValue::Undefined);
Execution Count:1
1
387 -
388 bool keyExists;
executed (the execution status of this line is deduced): bool keyExists;
-
389 int index = o->indexOf(key, &keyExists);
executed (the execution status of this line is deduced): int index = o->indexOf(key, &keyExists);
-
390 if (!keyExists)
evaluated: !keyExists
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:2
1-2
391 return QJsonValue(QJsonValue::Undefined);
executed: return QJsonValue(QJsonValue::Undefined);
Execution Count:1
1
392 -
393 QJsonValue v(d, o, o->entryAt(index)->value);
executed (the execution status of this line is deduced): QJsonValue v(d, o, o->entryAt(index)->value);
-
394 detach();
executed (the execution status of this line is deduced): detach();
-
395 o->removeItems(index, 1);
executed (the execution status of this line is deduced): o->removeItems(index, 1);
-
396 ++d->compactionCounter;
executed (the execution status of this line is deduced): ++d->compactionCounter;
-
397 if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u)
partially evaluated: d->compactionCounter > 32u
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:2
never evaluated: d->compactionCounter >= unsigned(o->length) / 2u
0-2
398 compact();
never executed: compact();
0
399 -
400 return v;
executed: return v;
Execution Count:2
2
401} -
402 -
403/*! -
404 Returns \c true if the object contains key \a key. -
405 -
406 \sa insert(), remove(), take() -
407 */ -
408bool QJsonObject::contains(const QString &key) const -
409{ -
410 if (!o)
evaluated: !o
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:9
1-9
411 return false;
executed: return false;
Execution Count:1
1
412 -
413 bool keyExists;
executed (the execution status of this line is deduced): bool keyExists;
-
414 o->indexOf(key, &keyExists);
executed (the execution status of this line is deduced): o->indexOf(key, &keyExists);
-
415 return keyExists;
executed: return keyExists;
Execution Count:9
9
416} -
417 -
418/*! -
419 Returns \c true if \a other is equal to this object -
420 */ -
421bool QJsonObject::operator==(const QJsonObject &other) const -
422{ -
423 if (o == other.o)
evaluated: o == other.o
TRUEFALSE
yes
Evaluation Count:21
yes
Evaluation Count:1313
21-1313
424 return true;
executed: return true;
Execution Count:21
21
425 -
426 if (!o)
evaluated: !o
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1312
1-1312
427 return !other.o->length;
executed: return !other.o->length;
Execution Count:1
1
428 if (!other.o)
evaluated: !other.o
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:1309
3-1309
429 return !o->length;
executed: return !o->length;
Execution Count:3
3
430 if (o->length != other.o->length)
evaluated: o->length != other.o->length
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1308
1-1308
431 return false;
executed: return false;
Execution Count:1
1
432 -
433 for (uint i = 0; i < o->length; ++i) {
evaluated: i < o->length
TRUEFALSE
yes
Evaluation Count:4001
yes
Evaluation Count:1307
1307-4001
434 QJsonPrivate::Entry *e = o->entryAt(i);
executed (the execution status of this line is deduced): QJsonPrivate::Entry *e = o->entryAt(i);
-
435 QJsonValue v(d, o, e->value);
executed (the execution status of this line is deduced): QJsonValue v(d, o, e->value);
-
436 if (other.value(e->key()) != v)
evaluated: other.value(e->key()) != v
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:4000
1-4000
437 return false;
executed: return false;
Execution Count:1
1
438 }
executed: }
Execution Count:4000
4000
439 -
440 return true;
executed: return true;
Execution Count:1307
1307
441} -
442 -
443/*! -
444 Returns \c true if \a other is not equal to this object -
445 */ -
446bool QJsonObject::operator!=(const QJsonObject &other) const -
447{ -
448 return !(*this == other);
executed: return !(*this == other);
Execution Count:3
3
449} -
450 -
451/*! -
452 Removes the (key, value) pair pointed to by the iterator \a it -
453 from the map, and returns an iterator to the next item in the -
454 map. -
455 -
456 \sa remove() -
457 */ -
458QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it) -
459{ -
460 Q_ASSERT(d && d->ref.load() == 1);
executed (the execution status of this line is deduced): qt_noop();
-
461 if (it.o != this || it.i < 0 || it.i >= (int)o->length)
partially evaluated: it.o != this
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:12
partially evaluated: it.i < 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:12
partially evaluated: it.i >= (int)o->length
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:12
0-12
462 return iterator(this, o->length);
never executed: return iterator(this, o->length);
0
463 -
464 int index = it.i;
executed (the execution status of this line is deduced): int index = it.i;
-
465 -
466 o->removeItems(index, 1);
executed (the execution status of this line is deduced): o->removeItems(index, 1);
-
467 ++d->compactionCounter;
executed (the execution status of this line is deduced): ++d->compactionCounter;
-
468 if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u)
partially evaluated: d->compactionCounter > 32u
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:12
never evaluated: d->compactionCounter >= unsigned(o->length) / 2u
0-12
469 compact();
never executed: compact();
0
470 -
471 // iterator hasn't changed -
472 return it;
executed: return it;
Execution Count:12
12
473} -
474 -
475/*! -
476 Returns an iterator pointing to the item with key \a key in the -
477 map. -
478 -
479 If the map contains no item with key \a key, the function -
480 returns end(). -
481 */ -
482QJsonObject::iterator QJsonObject::find(const QString &key) -
483{ -
484 bool keyExists = false;
executed (the execution status of this line is deduced): bool keyExists = false;
-
485 int index = o ? o->indexOf(key, &keyExists) : 0;
partially evaluated: o
TRUEFALSE
yes
Evaluation Count:3
no
Evaluation Count:0
0-3
486 if (!keyExists)
evaluated: !keyExists
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:2
1-2
487 return end();
executed: return end();
Execution Count:1
1
488 detach();
executed (the execution status of this line is deduced): detach();
-
489 return iterator(this, index);
executed: return iterator(this, index);
Execution Count:2
2
490} -
491 -
492/*! \fn QJsonObject::const_iterator QJsonObject::find(const QString &key) const -
493 -
494 \overload -
495*/ -
496 -
497/*! -
498 Returns an const iterator pointing to the item with key \a key in the -
499 map. -
500 -
501 If the map contains no item with key \a key, the function -
502 returns constEnd(). -
503 */ -
504QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const -
505{ -
506 bool keyExists = false;
executed (the execution status of this line is deduced): bool keyExists = false;
-
507 int index = o ? o->indexOf(key, &keyExists) : 0;
partially evaluated: o
TRUEFALSE
yes
Evaluation Count:2
no
Evaluation Count:0
0-2
508 if (!keyExists)
evaluated: !keyExists
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
509 return end();
executed: return end();
Execution Count:1
1
510 return const_iterator(this, index);
executed: return const_iterator(this, index);
Execution Count:1
1
511} -
512 -
513/*! \fn int QJsonObject::count() const -
514 -
515 \overload -
516 -
517 Same as size(). -
518*/ -
519 -
520/*! \fn int QJsonObject::length() const -
521 -
522 \overload -
523 -
524 Same as size(). -
525*/ -
526 -
527/*! \fn QJsonObject::iterator QJsonObject::begin() -
528 -
529 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in -
530 the object. -
531 -
532 \sa constBegin(), end() -
533*/ -
534 -
535/*! \fn QJsonObject::const_iterator QJsonObject::begin() const -
536 -
537 \overload -
538*/ -
539 -
540/*! \fn QJsonObject::const_iterator QJsonObject::constBegin() const -
541 -
542 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item -
543 in the object. -
544 -
545 \sa begin(), constEnd() -
546*/ -
547 -
548/*! \fn QJsonObject::iterator QJsonObject::end() -
549 -
550 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item -
551 after the last item in the object. -
552 -
553 \sa begin(), constEnd() -
554*/ -
555 -
556/*! \fn QJsonObject::const_iterator QJsonObject::end() const -
557 -
558 \overload -
559*/ -
560 -
561/*! \fn QJsonObject::const_iterator QJsonObject::constEnd() const -
562 -
563 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary -
564 item after the last item in the object. -
565 -
566 \sa constBegin(), end() -
567*/ -
568 -
569/*! -
570 \fn bool QJsonObject::empty() const -
571 -
572 This function is provided for STL compatibility. It is equivalent -
573 to isEmpty(), returning \c true if the object is empty; otherwise -
574 returning \c false. -
575*/ -
576 -
577/*! \class QJsonObject::iterator -
578 \inmodule QtCore -
579 \ingroup json -
580 \reentrant -
581 \since 5.0 -
582 -
583 \brief The QJsonObject::iterator class provides an STL-style non-const iterator for QJsonObject. -
584 -
585 QJsonObject::iterator allows you to iterate over a QJsonObject -
586 and to modify the value (but not the key) stored under -
587 a particular key. If you want to iterate over a const QJsonObject, you -
588 should use QJsonObject::const_iterator. It is generally good practice to -
589 use QJsonObject::const_iterator on a non-const QJsonObject as well, unless you -
590 need to change the QJsonObject through the iterator. Const iterators are -
591 slightly faster, and improves code readability. -
592 -
593 The default QJsonObject::iterator constructor creates an uninitialized -
594 iterator. You must initialize it using a QJsonObject function like -
595 QJsonObject::begin(), QJsonObject::end(), or QJsonObject::find() before you can -
596 start iterating. -
597 -
598 Multiple iterators can be used on the same object. Existing iterators will however -
599 become dangling once the object gets modified. -
600 -
601 \sa QJsonObject::const_iterator -
602*/ -
603 -
604/*! \typedef QJsonObject::iterator::difference_type -
605 -
606 \internal -
607*/ -
608 -
609/*! \typedef QJsonObject::iterator::iterator_category -
610 -
611 A synonym for \e {std::bidirectional_iterator_tag} indicating -
612 this iterator is a bidirectional iterator. -
613*/ -
614 -
615/*! \typedef QJsonObject::iterator::reference -
616 -
617 \internal -
618*/ -
619 -
620/*! \typedef QJsonObject::iterator::value_type -
621 -
622 \internal -
623*/ -
624 -
625/*! \fn QJsonObject::iterator::iterator() -
626 -
627 Constructs an uninitialized iterator. -
628 -
629 Functions like key(), value(), and operator++() must not be -
630 called on an uninitialized iterator. Use operator=() to assign a -
631 value to it before using it. -
632 -
633 \sa QJsonObject::begin(), QJsonObject::end() -
634*/ -
635 -
636/*! \fn QJsonObject::iterator::iterator(QJsonObject *obj, int index) -
637 \internal -
638*/ -
639 -
640/*! \fn QString QJsonObject::iterator::key() const -
641 -
642 Returns the current item's key. -
643 -
644 There is no direct way of changing an item's key through an -
645 iterator, although it can be done by calling QJsonObject::erase() -
646 followed by QJsonObject::insert(). -
647 -
648 \sa value() -
649*/ -
650 -
651/*! \fn QJsonValueRef QJsonObject::iterator::value() const -
652 -
653 Returns a modifiable reference to the current item's value. -
654 -
655 You can change the value of an item by using value() on -
656 the left side of an assignment. -
657 -
658 The return value is of type QJsonValueRef, a helper class for QJsonArray -
659 and QJsonObject. When you get an object of type QJsonValueRef, you can -
660 use it as if it were a reference to a QJsonValue. If you assign to it, -
661 the assignment will apply to the character in the QJsonArray of QJsonObject -
662 from which you got the reference. -
663 -
664 \sa key(), operator*() -
665*/ -
666 -
667/*! \fn QJsonValueRef QJsonObject::iterator::operator*() const -
668 -
669 Returns a modifiable reference to the current item's value. -
670 -
671 Same as value(). -
672 -
673 The return value is of type QJsonValueRef, a helper class for QJsonArray -
674 and QJsonObject. When you get an object of type QJsonValueRef, you can -
675 use it as if it were a reference to a QJsonValue. If you assign to it, -
676 the assignment will apply to the character in the QJsonArray of QJsonObject -
677 from which you got the reference. -
678 -
679 \sa key() -
680*/ -
681 -
682/*! -
683 \fn bool QJsonObject::iterator::operator==(const iterator &other) const -
684 \fn bool QJsonObject::iterator::operator==(const const_iterator &other) const -
685 -
686 Returns \c true if \a other points to the same item as this -
687 iterator; otherwise returns \c false. -
688 -
689 \sa operator!=() -
690*/ -
691 -
692/*! -
693 \fn bool QJsonObject::iterator::operator!=(const iterator &other) const -
694 \fn bool QJsonObject::iterator::operator!=(const const_iterator &other) const -
695 -
696 Returns \c true if \a other points to a different item than this -
697 iterator; otherwise returns \c false. -
698 -
699 \sa operator==() -
700*/ -
701 -
702/*! \fn QJsonObject::iterator QJsonObject::iterator::operator++() -
703 -
704 The prefix ++ operator, \c{++i}, advances the iterator to the -
705 next item in the object and returns an iterator to the new current -
706 item. -
707 -
708 Calling this function on QJsonObject::end() leads to undefined results. -
709 -
710 \sa operator--() -
711*/ -
712 -
713/*! \fn QJsonObject::iterator QJsonObject::iterator::operator++(int) -
714 -
715 \overload -
716 -
717 The postfix ++ operator, \c{i++}, advances the iterator to the -
718 next item in the object and returns an iterator to the previously -
719 current item. -
720*/ -
721 -
722/*! \fn QJsonObject::iterator QJsonObject::iterator::operator--() -
723 -
724 The prefix -- operator, \c{--i}, makes the preceding item -
725 current and returns an iterator pointing to the new current item. -
726 -
727 Calling this function on QJsonObject::begin() leads to undefined -
728 results. -
729 -
730 \sa operator++() -
731*/ -
732 -
733/*! \fn QJsonObject::iterator QJsonObject::iterator::operator--(int) -
734 -
735 \overload -
736 -
737 The postfix -- operator, \c{i--}, makes the preceding item -
738 current and returns an iterator pointing to the previously -
739 current item. -
740*/ -
741 -
742/*! \fn QJsonObject::iterator QJsonObject::iterator::operator+(int j) const -
743 -
744 Returns an iterator to the item at \a j positions forward from -
745 this iterator. If \a j is negative, the iterator goes backward. -
746 -
747 \sa operator-() -
748 -
749*/ -
750 -
751/*! \fn QJsonObject::iterator QJsonObject::iterator::operator-(int j) const -
752 -
753 Returns an iterator to the item at \a j positions backward from -
754 this iterator. If \a j is negative, the iterator goes forward. -
755 -
756 \sa operator+() -
757*/ -
758 -
759/*! \fn QJsonObject::iterator &QJsonObject::iterator::operator+=(int j) -
760 -
761 Advances the iterator by \a j items. If \a j is negative, the -
762 iterator goes backward. -
763 -
764 \sa operator-=(), operator+() -
765*/ -
766 -
767/*! \fn QJsonObject::iterator &QJsonObject::iterator::operator-=(int j) -
768 -
769 Makes the iterator go back by \a j items. If \a j is negative, -
770 the iterator goes forward. -
771 -
772 \sa operator+=(), operator-() -
773*/ -
774 -
775/*! -
776 \class QJsonObject::const_iterator -
777 \inmodule QtCore -
778 \brief The QJsonObject::const_iterator class provides an STL-style const iterator for QJsonObject. -
779 -
780 QJsonObject::const_iterator allows you to iterate over a QJsonObject. -
781 If you want to modify the QJsonObject as you iterate -
782 over it, you must use QJsonObject::iterator instead. It is generally -
783 good practice to use QJsonObject::const_iterator on a non-const QJsonObject as -
784 well, unless you need to change the QJsonObject through the iterator. -
785 Const iterators are slightly faster and improves code -
786 readability. -
787 -
788 The default QJsonObject::const_iterator constructor creates an -
789 uninitialized iterator. You must initialize it using a QJsonObject -
790 function like QJsonObject::constBegin(), QJsonObject::constEnd(), or -
791 QJsonObject::find() before you can start iterating. -
792 -
793 Multiple iterators can be used on the same object. Existing iterators -
794 will however become dangling if the object gets modified. -
795 -
796 \sa QJsonObject::iterator -
797*/ -
798 -
799/*! \typedef QJsonObject::const_iterator::difference_type -
800 -
801 \internal -
802*/ -
803 -
804/*! \typedef QJsonObject::const_iterator::iterator_category -
805 -
806 A synonym for \e {std::bidirectional_iterator_tag} indicating -
807 this iterator is a bidirectional iterator. -
808*/ -
809 -
810/*! \typedef QJsonObject::const_iterator::reference -
811 -
812 \internal -
813*/ -
814 -
815/*! \typedef QJsonObject::const_iterator::value_type -
816 -
817 \internal -
818*/ -
819 -
820/*! \fn QJsonObject::const_iterator::const_iterator() -
821 -
822 Constructs an uninitialized iterator. -
823 -
824 Functions like key(), value(), and operator++() must not be -
825 called on an uninitialized iterator. Use operator=() to assign a -
826 value to it before using it. -
827 -
828 \sa QJsonObject::constBegin(), QJsonObject::constEnd() -
829*/ -
830 -
831/*! \fn QJsonObject::const_iterator::const_iterator(const QJsonObject *obj, int index) -
832 \internal -
833*/ -
834 -
835/*! \fn QJsonObject::const_iterator::const_iterator(const iterator &other) -
836 -
837 Constructs a copy of \a other. -
838*/ -
839 -
840/*! \fn QString QJsonObject::const_iterator::key() const -
841 -
842 Returns the current item's key. -
843 -
844 \sa value() -
845*/ -
846 -
847/*! \fn QJsonValue QJsonObject::const_iterator::value() const -
848 -
849 Returns the current item's value. -
850 -
851 \sa key(), operator*() -
852*/ -
853 -
854/*! \fn QJsonValue QJsonObject::const_iterator::operator*() const -
855 -
856 Returns the current item's value. -
857 -
858 Same as value(). -
859 -
860 \sa key() -
861*/ -
862 -
863/*! \fn bool QJsonObject::const_iterator::operator==(const const_iterator &other) const -
864 \fn bool QJsonObject::const_iterator::operator==(const iterator &other) const -
865 -
866 Returns \c true if \a other points to the same item as this -
867 iterator; otherwise returns \c false. -
868 -
869 \sa operator!=() -
870*/ -
871 -
872/*! \fn bool QJsonObject::const_iterator::operator!=(const const_iterator &other) const -
873 \fn bool QJsonObject::const_iterator::operator!=(const iterator &other) const -
874 -
875 Returns \c true if \a other points to a different item than this -
876 iterator; otherwise returns \c false. -
877 -
878 \sa operator==() -
879*/ -
880 -
881/*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator++() -
882 -
883 The prefix ++ operator, \c{++i}, advances the iterator to the -
884 next item in the object and returns an iterator to the new current -
885 item. -
886 -
887 Calling this function on QJsonObject::end() leads to undefined results. -
888 -
889 \sa operator--() -
890*/ -
891 -
892/*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator++(int) -
893 -
894 \overload -
895 -
896 The postfix ++ operator, \c{i++}, advances the iterator to the -
897 next item in the object and returns an iterator to the previously -
898 current item. -
899*/ -
900 -
901/*! \fn QJsonObject::const_iterator &QJsonObject::const_iterator::operator--() -
902 -
903 The prefix -- operator, \c{--i}, makes the preceding item -
904 current and returns an iterator pointing to the new current item. -
905 -
906 Calling this function on QJsonObject::begin() leads to undefined -
907 results. -
908 -
909 \sa operator++() -
910*/ -
911 -
912/*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator--(int) -
913 -
914 \overload -
915 -
916 The postfix -- operator, \c{i--}, makes the preceding item -
917 current and returns an iterator pointing to the previously -
918 current item. -
919*/ -
920 -
921/*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator+(int j) const -
922 -
923 Returns an iterator to the item at \a j positions forward from -
924 this iterator. If \a j is negative, the iterator goes backward. -
925 -
926 This operation can be slow for large \a j values. -
927 -
928 \sa operator-() -
929*/ -
930 -
931/*! \fn QJsonObject::const_iterator QJsonObject::const_iterator::operator-(int j) const -
932 -
933 Returns an iterator to the item at \a j positions backward from -
934 this iterator. If \a j is negative, the iterator goes forward. -
935 -
936 This operation can be slow for large \a j values. -
937 -
938 \sa operator+() -
939*/ -
940 -
941/*! \fn QJsonObject::const_iterator &QJsonObject::const_iterator::operator+=(int j) -
942 -
943 Advances the iterator by \a j items. If \a j is negative, the -
944 iterator goes backward. -
945 -
946 This operation can be slow for large \a j values. -
947 -
948 \sa operator-=(), operator+() -
949*/ -
950 -
951/*! \fn QJsonObject::const_iterator &QJsonObject::const_iterator::operator-=(int j) -
952 -
953 Makes the iterator go back by \a j items. If \a j is negative, -
954 the iterator goes forward. -
955 -
956 This operation can be slow for large \a j values. -
957 -
958 \sa operator+=(), operator-() -
959*/ -
960 -
961 -
962/*! -
963 \internal -
964 */ -
965void QJsonObject::detach(uint reserve) -
966{ -
967 if (!d) {
evaluated: !d
TRUEFALSE
yes
Evaluation Count:38
yes
Evaluation Count:258
38-258
968 d = new QJsonPrivate::Data(reserve, QJsonValue::Object);
executed (the execution status of this line is deduced): d = new QJsonPrivate::Data(reserve, QJsonValue::Object);
-
969 o = static_cast<QJsonPrivate::Object *>(d->header->root());
executed (the execution status of this line is deduced): o = static_cast<QJsonPrivate::Object *>(d->header->root());
-
970 d->ref.ref();
executed (the execution status of this line is deduced): d->ref.ref();
-
971 return;
executed: return;
Execution Count:38
38
972 } -
973 if (reserve == 0 && d->ref.load() == 1)
evaluated: reserve == 0
TRUEFALSE
yes
Evaluation Count:75
yes
Evaluation Count:183
evaluated: d->ref.load() == 1
TRUEFALSE
yes
Evaluation Count:61
yes
Evaluation Count:14
14-183
974 return;
executed: return;
Execution Count:61
61
975 -
976 QJsonPrivate::Data *x = d->clone(o, reserve);
executed (the execution status of this line is deduced): QJsonPrivate::Data *x = d->clone(o, reserve);
-
977 x->ref.ref();
executed (the execution status of this line is deduced): x->ref.ref();
-
978 if (!d->ref.deref())
evaluated: !d->ref.deref()
TRUEFALSE
yes
Evaluation Count:36
yes
Evaluation Count:161
36-161
979 delete d;
executed: delete d;
Execution Count:36
36
980 d = x;
executed (the execution status of this line is deduced): d = x;
-
981 o = static_cast<QJsonPrivate::Object *>(d->header->root());
executed (the execution status of this line is deduced): o = static_cast<QJsonPrivate::Object *>(d->header->root());
-
982}
executed: }
Execution Count:197
197
983 -
984/*! -
985 \internal -
986 */ -
987void QJsonObject::compact() -
988{ -
989 if (!d || !d->compactionCounter)
partially evaluated: !d
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:5
partially evaluated: !d->compactionCounter
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:5
0-5
990 return;
never executed: return;
0
991 -
992 detach();
executed (the execution status of this line is deduced): detach();
-
993 d->compact();
executed (the execution status of this line is deduced): d->compact();
-
994 o = static_cast<QJsonPrivate::Object *>(d->header->root());
executed (the execution status of this line is deduced): o = static_cast<QJsonPrivate::Object *>(d->header->root());
-
995}
executed: }
Execution Count:5
5
996 -
997/*! -
998 \internal -
999 */ -
1000QString QJsonObject::keyAt(int i) const -
1001{ -
1002 Q_ASSERT(o && i >= 0 && i < (int)o->length);
executed (the execution status of this line is deduced): qt_noop();
-
1003 -
1004 QJsonPrivate::Entry *e = o->entryAt(i);
executed (the execution status of this line is deduced): QJsonPrivate::Entry *e = o->entryAt(i);
-
1005 return e->key();
executed: return e->key();
Execution Count:23
23
1006} -
1007 -
1008/*! -
1009 \internal -
1010 */ -
1011QJsonValue QJsonObject::valueAt(int i) const -
1012{ -
1013 if (!o || i < 0 || i >= (int)o->length)
partially evaluated: !o
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:46
partially evaluated: i < 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:46
evaluated: i >= (int)o->length
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:44
0-46
1014 return QJsonValue(QJsonValue::Undefined);
executed: return QJsonValue(QJsonValue::Undefined);
Execution Count:2
2
1015 -
1016 QJsonPrivate::Entry *e = o->entryAt(i);
executed (the execution status of this line is deduced): QJsonPrivate::Entry *e = o->entryAt(i);
-
1017 return QJsonValue(d, o, e->value);
executed: return QJsonValue(d, o, e->value);
Execution Count:44
44
1018} -
1019 -
1020/*! -
1021 \internal -
1022 */ -
1023void QJsonObject::setValueAt(int i, const QJsonValue &val) -
1024{ -
1025 Q_ASSERT(o && i >= 0 && i < (int)o->length);
executed (the execution status of this line is deduced): qt_noop();
-
1026 -
1027 QJsonPrivate::Entry *e = o->entryAt(i);
executed (the execution status of this line is deduced): QJsonPrivate::Entry *e = o->entryAt(i);
-
1028 insert(e->key(), val);
executed (the execution status of this line is deduced): insert(e->key(), val);
-
1029}
executed: }
Execution Count:23
23
1030 -
1031#ifndef QT_NO_DEBUG_STREAM -
1032QDebug operator<<(QDebug dbg, const QJsonObject &o) -
1033{ -
1034 if (!o.o) {
evaluated: !o.o
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:2
2
1035 dbg << "QJsonObject()";
executed (the execution status of this line is deduced): dbg << "QJsonObject()";
-
1036 return dbg;
executed: return dbg;
Execution Count:2
2
1037 } -
1038 QByteArray json;
executed (the execution status of this line is deduced): QByteArray json;
-
1039 QJsonPrivate::Writer::objectToJson(o.o, json, 0, true);
executed (the execution status of this line is deduced): QJsonPrivate::Writer::objectToJson(o.o, json, 0, true);
-
1040 dbg.nospace() << "QJsonObject("
executed (the execution status of this line is deduced): dbg.nospace() << "QJsonObject("
-
1041 << json.constData() // print as utf-8 string without extra quotation marks
executed (the execution status of this line is deduced): << json.constData()
-
1042 << ")";
executed (the execution status of this line is deduced): << ")";
-
1043 return dbg.space();
executed: return dbg.space();
Execution Count:2
2
1044} -
1045#endif -
1046 -
1047QT_END_NAMESPACE -
1048 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial