1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <qjsonobject.h>
41#include <qjsonvalue.h>
42#include <qjsonarray.h>
43#include <qstringlist.h>
44#include <qvariant.h>
45#include <qdebug.h>
46
47#include "qjsonwriter_p.h"
48#include "qjson_p.h"
49
50QT_BEGIN_NAMESPACE
51
52/*!
53 \class QJsonArray
54 \inmodule QtCore
55 \ingroup json
56 \ingroup shared
57 \reentrant
58 \since 5.0
59
60 \brief The QJsonArray class encapsulates a JSON array.
61
62 A JSON array is a list of values. The list can be manipulated by inserting and
63 removing QJsonValue's from the array.
64
65 A QJsonArray can be converted to and from a QVariantList. You can query the
66 number of entries with size(), insert(), and removeAt() entries from it
67 and iterate over its content using the standard C++ iterator pattern.
68
69 QJsonArray 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 \sa {JSON Support in Qt}, {JSON Save Game Example}
75*/
76
77/*!
78 \typedef QJsonArray::Iterator
79
80 Qt-style synonym for QJsonArray::iterator.
81*/
82
83/*!
84 \typedef QJsonArray::ConstIterator
85
86 Qt-style synonym for QJsonArray::const_iterator.
87*/
88
89/*!
90 \typedef QJsonArray::size_type
91
92 Typedef for int. Provided for STL compatibility.
93*/
94
95/*!
96 \typedef QJsonArray::value_type
97
98 Typedef for QJsonValue. Provided for STL compatibility.
99*/
100
101/*!
102 \typedef QJsonArray::difference_type
103
104 Typedef for int. Provided for STL compatibility.
105*/
106
107/*!
108 \typedef QJsonArray::pointer
109
110 Typedef for QJsonValue *. Provided for STL compatibility.
111*/
112
113/*!
114 \typedef QJsonArray::const_pointer
115
116 Typedef for const QJsonValue *. Provided for STL compatibility.
117*/
118
119/*!
120 \typedef QJsonArray::reference
121
122 Typedef for QJsonValue &. Provided for STL compatibility.
123*/
124
125/*!
126 \typedef QJsonArray::const_reference
127
128 Typedef for const QJsonValue &. Provided for STL compatibility.
129*/
130
131/*!
132 Creates an empty array.
133 */
134QJsonArray::QJsonArray()
135 : d(nullptr), a(nullptr)
136{
137}
138
139/*!
140 \fn QJsonArray::QJsonArray(std::initializer_list<QJsonValue> args)
141 \since 5.4
142 Creates an array initialized from \a args initialization list.
143
144 QJsonArray can be constructed in a way similar to JSON notation,
145 for example:
146 \code
147 QJsonArray array = { 1, 2.2, QString() };
148 \endcode
149 */
150
151/*!
152 \internal
153 */
154QJsonArray::QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array)
155 : d(data), a(array)
156{
157 Q_ASSERT(data);
158 Q_ASSERT(array);
159 d->ref.ref();
160}
161
162/*!
163 This method replaces part of QJsonArray(std::initializer_list<QJsonValue> args) .
164 The constructor needs to be inline, but we do not want to leak implementation details
165 of this class.
166 \note this method is called for an uninitialized object
167 \internal
168 */
169void QJsonArray::initialize()
170{
171 d = nullptr;
172 a = nullptr;
173}
174
175/*!
176 Deletes the array.
177 */
178QJsonArray::~QJsonArray()
179{
180 if (d && !d->ref.deref())
181 delete d;
182}
183
184/*!
185 Creates a copy of \a other.
186
187 Since QJsonArray is implicitly shared, the copy is shallow
188 as long as the object doesn't get modified.
189 */
190QJsonArray::QJsonArray(const QJsonArray &other)
191{
192 d = other.d;
193 a = other.a;
194 if (d)
195 d->ref.ref();
196}
197
198/*!
199 Assigns \a other to this array.
200 */
201QJsonArray &QJsonArray::operator =(const QJsonArray &other)
202{
203 if (d != other.d) {
204 if (d && !d->ref.deref())
205 delete d;
206 d = other.d;
207 if (d)
208 d->ref.ref();
209 }
210 a = other.a;
211
212 return *this;
213}
214
215/*!
216 \fn QJsonArray::QJsonArray(QJsonArray &&other)
217 \since 5.10
218
219 Move-constructs a QJsonArray from \a other.
220*/
221
222/*!
223 \fn QJsonArray &QJsonArray::operator =(QJsonArray &&other)
224 \since 5.10
225
226 Move-assigns \a other to this array.
227*/
228
229/*!
230 \fn void QJsonArray::swap(QJsonArray &other)
231 \since 5.10
232
233 Swaps the array \a other with this. This operation is very fast and never fails.
234*/
235
236/*! \fn QJsonArray &QJsonArray::operator+=(const QJsonValue &value)
237
238 Appends \a value to the array, and returns a reference to the array itself.
239
240 \since 5.3
241 \sa append(), operator<<()
242*/
243
244/*! \fn QJsonArray QJsonArray::operator+(const QJsonValue &value) const
245
246 Returns an array that contains all the items in this array followed
247 by the provided \a value.
248
249 \since 5.3
250 \sa operator+=()
251*/
252
253/*! \fn QJsonArray &QJsonArray::operator<<(const QJsonValue &value)
254
255 Appends \a value to the array, and returns a reference to the array itself.
256
257 \since 5.3
258 \sa operator+=(), append()
259*/
260
261/*!
262 Converts the string list \a list to a QJsonArray.
263
264 The values in \a list will be converted to JSON values.
265
266 \sa toVariantList(), QJsonValue::fromVariant()
267 */
268QJsonArray QJsonArray::fromStringList(const QStringList &list)
269{
270 QJsonArray array;
271 for (QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it)
272 array.append(QJsonValue(*it));
273 return array;
274}
275
276/*!
277 Converts the variant list \a list to a QJsonArray.
278
279 The QVariant values in \a list will be converted to JSON values.
280
281 \sa toVariantList(), QJsonValue::fromVariant()
282 */
283QJsonArray QJsonArray::fromVariantList(const QVariantList &list)
284{
285 QJsonArray array;
286 if (list.isEmpty())
287 return array;
288
289 array.detach2(1024);
290
291 QVector<QJsonPrivate::Value> values;
292 values.resize(list.size());
293 QJsonPrivate::Value *valueData = values.data();
294 uint currentOffset = sizeof(QJsonPrivate::Base);
295
296 for (int i = 0; i < list.size(); ++i) {
297 QJsonValue val = QJsonValue::fromVariant(list.at(i));
298
299 bool latinOrIntValue;
300 int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue);
301
302 if (!array.detach2(valueSize))
303 return QJsonArray();
304
305 QJsonPrivate::Value *v = valueData + i;
306 v->type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t);
307 v->latinOrIntValue = latinOrIntValue;
308 v->latinKey = false;
309 v->value = QJsonPrivate::Value::valueToStore(val, currentOffset);
310 if (valueSize)
311 QJsonPrivate::Value::copyData(val, (char *)array.a + currentOffset, latinOrIntValue);
312
313 currentOffset += valueSize;
314 array.a->size = currentOffset;
315 }
316
317 // write table
318 array.a->tableOffset = currentOffset;
319 if (!array.detach2(sizeof(QJsonPrivate::offset)*values.size()))
320 return QJsonArray();
321 memcpy(static_cast<void *>(array.a->table()),
322 static_cast<const void *>(values.constData()), values.size()*sizeof(uint));
323 array.a->length = values.size();
324 array.a->size = currentOffset + sizeof(QJsonPrivate::offset)*values.size();
325
326 return array;
327}
328
329/*!
330 Converts this object to a QVariantList.
331
332 Returns the created map.
333 */
334QVariantList QJsonArray::toVariantList() const
335{
336 QVariantList list;
337
338 if (a) {
339 list.reserve(a->length);
340 for (int i = 0; i < (int)a->length; ++i)
341 list.append(QJsonValue(d, a, a->at(i)).toVariant());
342 }
343 return list;
344}
345
346
347/*!
348 Returns the number of values stored in the array.
349 */
350int QJsonArray::size() const
351{
352 if (!d)
353 return 0;
354
355 return (int)a->length;
356}
357
358/*!
359 \fn QJsonArray::count() const
360
361 Same as size().
362
363 \sa size()
364*/
365
366/*!
367 Returns \c true if the object is empty. This is the same as size() == 0.
368
369 \sa size()
370 */
371bool QJsonArray::isEmpty() const
372{
373 if (!d)
374 return true;
375
376 return !a->length;
377}
378
379/*!
380 Returns a QJsonValue representing the value for index \a i.
381
382 The returned QJsonValue is \c Undefined, if \a i is out of bounds.
383
384 */
385QJsonValue QJsonArray::at(int i) const
386{
387 if (!a || i < 0 || i >= (int)a->length)
388 return QJsonValue(QJsonValue::Undefined);
389
390 return QJsonValue(d, a, a->at(i));
391}
392
393/*!
394 Returns the first value stored in the array.
395
396 Same as \c at(0).
397
398 \sa at()
399 */
400QJsonValue QJsonArray::first() const
401{
402 return at(0);
403}
404
405/*!
406 Returns the last value stored in the array.
407
408 Same as \c{at(size() - 1)}.
409
410 \sa at()
411 */
412QJsonValue QJsonArray::last() const
413{
414 return at(a ? (a->length - 1) : 0);
415}
416
417/*!
418 Inserts \a value at the beginning of the array.
419
420 This is the same as \c{insert(0, value)} and will prepend \a value to the array.
421
422 \sa append(), insert()
423 */
424void QJsonArray::prepend(const QJsonValue &value)
425{
426 insert(0, value);
427}
428
429/*!
430 Inserts \a value at the end of the array.
431
432 \sa prepend(), insert()
433 */
434void QJsonArray::append(const QJsonValue &value)
435{
436 insert(a ? (int)a->length : 0, value);
437}
438
439/*!
440 Removes the value at index position \a i. \a i must be a valid
441 index position in the array (i.e., \c{0 <= i < size()}).
442
443 \sa insert(), replace()
444 */
445void QJsonArray::removeAt(int i)
446{
447 if (!a || i < 0 || i >= (int)a->length)
448 return;
449
450 detach2();
451 a->removeItems(i, 1);
452 ++d->compactionCounter;
453 if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u)
454 compact();
455}
456
457/*! \fn void QJsonArray::removeFirst()
458
459 Removes the first item in the array. Calling this function is
460 equivalent to calling \c{removeAt(0)}. The array must not be empty. If
461 the array can be empty, call isEmpty() before calling this
462 function.
463
464 \sa removeAt(), removeLast()
465*/
466
467/*! \fn void QJsonArray::removeLast()
468
469 Removes the last item in the array. Calling this function is
470 equivalent to calling \c{removeAt(size() - 1)}. The array must not be
471 empty. If the array can be empty, call isEmpty() before calling
472 this function.
473
474 \sa removeAt(), removeFirst()
475*/
476
477/*!
478 Removes the item at index position \a i and returns it. \a i must
479 be a valid index position in the array (i.e., \c{0 <= i < size()}).
480
481 If you don't use the return value, removeAt() is more efficient.
482
483 \sa removeAt()
484 */
485QJsonValue QJsonArray::takeAt(int i)
486{
487 if (!a || i < 0 || i >= (int)a->length)
488 return QJsonValue(QJsonValue::Undefined);
489
490 QJsonValue v(d, a, a->at(i));
491 removeAt(i); // detaches
492 return v;
493}
494
495/*!
496 Inserts \a value at index position \a i in the array. If \a i
497 is \c 0, the value is prepended to the array. If \a i is size(), the
498 value is appended to the array.
499
500 \sa append(), prepend(), replace(), removeAt()
501 */
502void QJsonArray::insert(int i, const QJsonValue &value)
503{
504 Q_ASSERT (i >= 0 && i <= (a ? (int)a->length : 0));
505 QJsonValue val = value;
506
507 bool compressed;
508 int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed);
509
510 if (!detach2(valueSize + sizeof(QJsonPrivate::Value)))
511 return;
512
513 if (!a->length)
514 a->tableOffset = sizeof(QJsonPrivate::Array);
515
516 int valueOffset = a->reserveSpace(valueSize, i, 1, false);
517 if (!valueOffset)
518 return;
519
520 QJsonPrivate::Value &v = (*a)[i];
521 v.type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t);
522 v.latinOrIntValue = compressed;
523 v.latinKey = false;
524 v.value = QJsonPrivate::Value::valueToStore(val, valueOffset);
525 if (valueSize)
526 QJsonPrivate::Value::copyData(val, (char *)a + valueOffset, compressed);
527}
528
529/*!
530 \fn QJsonArray::iterator QJsonArray::insert(iterator before, const QJsonValue &value)
531
532 Inserts \a value before the position pointed to by \a before, and returns an iterator
533 pointing to the newly inserted item.
534
535 \sa erase(), insert()
536*/
537
538/*!
539 \fn QJsonArray::iterator QJsonArray::erase(iterator it)
540
541 Removes the item pointed to by \a it, and returns an iterator pointing to the
542 next item.
543
544 \sa removeAt()
545*/
546
547/*!
548 Replaces the item at index position \a i with \a value. \a i must
549 be a valid index position in the array (i.e., \c{0 <= i < size()}).
550
551 \sa operator[](), removeAt()
552 */
553void QJsonArray::replace(int i, const QJsonValue &value)
554{
555 Q_ASSERT (a && i >= 0 && i < (int)(a->length));
556 QJsonValue val = value;
557
558 bool compressed;
559 int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed);
560
561 if (!detach2(valueSize))
562 return;
563
564 if (!a->length)
565 a->tableOffset = sizeof(QJsonPrivate::Array);
566
567 int valueOffset = a->reserveSpace(valueSize, i, 1, true);
568 if (!valueOffset)
569 return;
570
571 QJsonPrivate::Value &v = (*a)[i];
572 v.type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t);
573 v.latinOrIntValue = compressed;
574 v.latinKey = false;
575 v.value = QJsonPrivate::Value::valueToStore(val, valueOffset);
576 if (valueSize)
577 QJsonPrivate::Value::copyData(val, (char *)a + valueOffset, compressed);
578
579 ++d->compactionCounter;
580 if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u)
581 compact();
582}
583
584/*!
585 Returns \c true if the array contains an occurrence of \a value, otherwise \c false.
586
587 \sa count()
588 */
589bool QJsonArray::contains(const QJsonValue &value) const
590{
591 for (int i = 0; i < size(); i++) {
592 if (at(i) == value)
593 return true;
594 }
595 return false;
596}
597
598/*!
599 Returns the value at index position \a i as a modifiable reference.
600 \a i must be a valid index position in the array (i.e., \c{0 <= i <
601 size()}).
602
603 The return value is of type QJsonValueRef, a helper class for QJsonArray
604 and QJsonObject. When you get an object of type QJsonValueRef, you can
605 use it as if it were a reference to a QJsonValue. If you assign to it,
606 the assignment will apply to the character in the QJsonArray of QJsonObject
607 from which you got the reference.
608
609 \sa at()
610 */
611QJsonValueRef QJsonArray::operator [](int i)
612{
613 Q_ASSERT(a && i >= 0 && i < (int)a->length);
614 return QJsonValueRef(this, i);
615}
616
617/*!
618 \overload
619
620 Same as at().
621 */
622QJsonValue QJsonArray::operator[](int i) const
623{
624 return at(i);
625}
626
627/*!
628 Returns \c true if this array is equal to \a other.
629 */
630bool QJsonArray::operator==(const QJsonArray &other) const
631{
632 if (a == other.a)
633 return true;
634
635 if (!a)
636 return !other.a->length;
637 if (!other.a)
638 return !a->length;
639 if (a->length != other.a->length)
640 return false;
641
642 for (int i = 0; i < (int)a->length; ++i) {
643 if (QJsonValue(d, a, a->at(i)) != QJsonValue(other.d, other.a, other.a->at(i)))
644 return false;
645 }
646 return true;
647}
648
649/*!
650 Returns \c true if this array is not equal to \a other.
651 */
652bool QJsonArray::operator!=(const QJsonArray &other) const
653{
654 return !(*this == other);
655}
656
657/*! \fn QJsonArray::iterator QJsonArray::begin()
658
659 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in
660 the array.
661
662 \sa constBegin(), end()
663*/
664
665/*! \fn QJsonArray::const_iterator QJsonArray::begin() const
666
667 \overload
668*/
669
670/*! \fn QJsonArray::const_iterator QJsonArray::constBegin() const
671
672 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
673 in the array.
674
675 \sa begin(), constEnd()
676*/
677
678/*! \fn QJsonArray::const_iterator QJsonArray::cbegin() const
679
680 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
681 in the array.
682
683 \sa begin(), cend()
684*/
685
686/*! \fn QJsonArray::iterator QJsonArray::end()
687
688 Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
689 after the last item in the array.
690
691 \sa begin(), constEnd()
692*/
693
694/*! \fn const_iterator QJsonArray::end() const
695
696 \overload
697*/
698
699/*! \fn QJsonArray::const_iterator QJsonArray::constEnd() const
700
701 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
702 item after the last item in the array.
703
704 \sa constBegin(), end()
705*/
706
707/*! \fn QJsonArray::const_iterator QJsonArray::cend() const
708
709 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
710 item after the last item in the array.
711
712 \sa cbegin(), end()
713*/
714
715/*! \fn void QJsonArray::push_back(const QJsonValue &value)
716
717 This function is provided for STL compatibility. It is equivalent
718 to \l{QJsonArray::append()}{append(value)} and will append \a value to the array.
719*/
720
721/*! \fn void QJsonArray::push_front(const QJsonValue &value)
722
723 This function is provided for STL compatibility. It is equivalent
724 to \l{QJsonArray::prepend()}{prepend(value)} and will prepend \a value to the array.
725*/
726
727/*! \fn void QJsonArray::pop_front()
728
729 This function is provided for STL compatibility. It is equivalent
730 to removeFirst(). The array must not be empty. If the array can be
731 empty, call isEmpty() before calling this function.
732*/
733
734/*! \fn void QJsonArray::pop_back()
735
736 This function is provided for STL compatibility. It is equivalent
737 to removeLast(). The array must not be empty. If the array can be
738 empty, call isEmpty() before calling this function.
739*/
740
741/*! \fn bool QJsonArray::empty() const
742
743 This function is provided for STL compatibility. It is equivalent
744 to isEmpty() and returns \c true if the array is empty.
745*/
746
747/*! \class QJsonArray::iterator
748 \inmodule QtCore
749 \brief The QJsonArray::iterator class provides an STL-style non-const iterator for QJsonArray.
750
751 QJsonArray::iterator allows you to iterate over a QJsonArray
752 and to modify the array item associated with the
753 iterator. If you want to iterate over a const QJsonArray, use
754 QJsonArray::const_iterator instead. It is generally a good practice to
755 use QJsonArray::const_iterator on a non-const QJsonArray as well, unless
756 you need to change the QJsonArray through the iterator. Const
757 iterators are slightly faster and improves code readability.
758
759 The default QJsonArray::iterator constructor creates an uninitialized
760 iterator. You must initialize it using a QJsonArray function like
761 QJsonArray::begin(), QJsonArray::end(), or QJsonArray::insert() before you can
762 start iterating.
763
764 Most QJsonArray functions accept an integer index rather than an
765 iterator. For that reason, iterators are rarely useful in
766 connection with QJsonArray. One place where STL-style iterators do
767 make sense is as arguments to \l{generic algorithms}.
768
769 Multiple iterators can be used on the same array. However, be
770 aware that any non-const function call performed on the QJsonArray
771 will render all existing iterators undefined.
772
773 \sa QJsonArray::const_iterator
774*/
775
776/*! \typedef QJsonArray::iterator::iterator_category
777
778 A synonym for \e {std::random_access_iterator_tag} indicating
779 this iterator is a random access iterator.
780*/
781
782/*! \typedef QJsonArray::iterator::difference_type
783
784 \internal
785*/
786
787/*! \typedef QJsonArray::iterator::value_type
788
789 \internal
790*/
791
792/*! \typedef QJsonArray::iterator::reference
793
794 \internal
795*/
796
797/*! \typedef QJsonArray::iterator::pointer
798
799 \internal
800*/
801
802/*! \fn QJsonArray::iterator::iterator()
803
804 Constructs an uninitialized iterator.
805
806 Functions like operator*() and operator++() should not be called
807 on an uninitialized iterator. Use operator=() to assign a value
808 to it before using it.
809
810 \sa QJsonArray::begin(), QJsonArray::end()
811*/
812
813/*! \fn QJsonArray::iterator::iterator(QJsonArray *array, int index)
814 \internal
815*/
816
817/*! \fn QJsonValueRef QJsonArray::iterator::operator*() const
818
819
820 Returns a modifiable reference to the current item.
821
822 You can change the value of an item by using operator*() on the
823 left side of an assignment.
824
825 The return value is of type QJsonValueRef, a helper class for QJsonArray
826 and QJsonObject. When you get an object of type QJsonValueRef, you can
827 use it as if it were a reference to a QJsonValue. If you assign to it,
828 the assignment will apply to the character in the QJsonArray of QJsonObject
829 from which you got the reference.
830*/
831
832/*! \fn QJsonValueRef *QJsonArray::iterator::operator->() const
833
834 Returns a pointer to a modifiable reference to the current item.
835*/
836
837/*! \fn QJsonValueRef QJsonArray::iterator::operator[](int j) const
838
839 Returns a modifiable reference to the item at offset \a j from the
840 item pointed to by this iterator (the item at position \c{*this + j}).
841
842 This function is provided to make QJsonArray iterators behave like C++
843 pointers.
844
845 The return value is of type QJsonValueRef, a helper class for QJsonArray
846 and QJsonObject. When you get an object of type QJsonValueRef, you can
847 use it as if it were a reference to a QJsonValue. If you assign to it,
848 the assignment will apply to the element in the QJsonArray or QJsonObject
849 from which you got the reference.
850
851 \sa operator+()
852*/
853
854/*!
855 \fn bool QJsonArray::iterator::operator==(const iterator &other) const
856 \fn bool QJsonArray::iterator::operator==(const const_iterator &other) const
857
858 Returns \c true if \a other points to the same item as this
859 iterator; otherwise returns \c false.
860
861 \sa operator!=()
862*/
863
864/*!
865 \fn bool QJsonArray::iterator::operator!=(const iterator &other) const
866 \fn bool QJsonArray::iterator::operator!=(const const_iterator &other) const
867
868 Returns \c true if \a other points to a different item than this
869 iterator; otherwise returns \c false.
870
871 \sa operator==()
872*/
873
874/*!
875 \fn bool QJsonArray::iterator::operator<(const iterator& other) const
876 \fn bool QJsonArray::iterator::operator<(const const_iterator& other) const
877
878 Returns \c true if the item pointed to by this iterator is less than
879 the item pointed to by the \a other iterator.
880*/
881
882/*!
883 \fn bool QJsonArray::iterator::operator<=(const iterator& other) const
884 \fn bool QJsonArray::iterator::operator<=(const const_iterator& other) const
885
886 Returns \c true if the item pointed to by this iterator is less than
887 or equal to the item pointed to by the \a other iterator.
888*/
889
890/*!
891 \fn bool QJsonArray::iterator::operator>(const iterator& other) const
892 \fn bool QJsonArray::iterator::operator>(const const_iterator& other) const
893
894 Returns \c true if the item pointed to by this iterator is greater
895 than the item pointed to by the \a other iterator.
896*/
897
898/*!
899 \fn bool QJsonArray::iterator::operator>=(const iterator& other) const
900 \fn bool QJsonArray::iterator::operator>=(const const_iterator& other) const
901
902 Returns \c true if the item pointed to by this iterator is greater
903 than or equal to the item pointed to by the \a other iterator.
904*/
905
906/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator++()
907
908 The prefix ++ operator, \c{++it}, advances the iterator to the
909 next item in the array and returns an iterator to the new current
910 item.
911
912 Calling this function on QJsonArray::end() leads to undefined results.
913
914 \sa operator--()
915*/
916
917/*! \fn QJsonArray::iterator QJsonArray::iterator::operator++(int)
918
919 \overload
920
921 The postfix ++ operator, \c{it++}, advances the iterator to the
922 next item in the array and returns an iterator to the previously
923 current item.
924*/
925
926/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator--()
927
928 The prefix -- operator, \c{--it}, makes the preceding item
929 current and returns an iterator to the new current item.
930
931 Calling this function on QJsonArray::begin() leads to undefined results.
932
933 \sa operator++()
934*/
935
936/*! \fn QJsonArray::iterator QJsonArray::iterator::operator--(int)
937
938 \overload
939
940 The postfix -- operator, \c{it--}, makes the preceding item
941 current and returns an iterator to the previously current item.
942*/
943
944/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator+=(int j)
945
946 Advances the iterator by \a j items. If \a j is negative, the
947 iterator goes backward.
948
949 \sa operator-=(), operator+()
950*/
951
952/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator-=(int j)
953
954 Makes the iterator go back by \a j items. If \a j is negative,
955 the iterator goes forward.
956
957 \sa operator+=(), operator-()
958*/
959
960/*! \fn QJsonArray::iterator QJsonArray::iterator::operator+(int j) const
961
962 Returns an iterator to the item at \a j positions forward from
963 this iterator. If \a j is negative, the iterator goes backward.
964
965 \sa operator-(), operator+=()
966*/
967
968/*! \fn QJsonArray::iterator QJsonArray::iterator::operator-(int j) const
969
970 Returns an iterator to the item at \a j positions backward from
971 this iterator. If \a j is negative, the iterator goes forward.
972
973 \sa operator+(), operator-=()
974*/
975
976/*! \fn int QJsonArray::iterator::operator-(iterator other) const
977
978 Returns the number of items between the item pointed to by \a
979 other and the item pointed to by this iterator.
980*/
981
982/*! \class QJsonArray::const_iterator
983 \inmodule QtCore
984 \brief The QJsonArray::const_iterator class provides an STL-style const iterator for QJsonArray.
985
986 QJsonArray::const_iterator allows you to iterate over a
987 QJsonArray. If you want to modify the QJsonArray as
988 you iterate over it, use QJsonArray::iterator instead. It is generally a
989 good practice to use QJsonArray::const_iterator on a non-const QJsonArray
990 as well, unless you need to change the QJsonArray through the
991 iterator. Const iterators are slightly faster and improves
992 code readability.
993
994 The default QJsonArray::const_iterator constructor creates an
995 uninitialized iterator. You must initialize it using a QJsonArray
996 function like QJsonArray::constBegin(), QJsonArray::constEnd(), or
997 QJsonArray::insert() before you can start iterating.
998
999 Most QJsonArray functions accept an integer index rather than an
1000 iterator. For that reason, iterators are rarely useful in
1001 connection with QJsonArray. One place where STL-style iterators do
1002 make sense is as arguments to \l{generic algorithms}.
1003
1004 Multiple iterators can be used on the same array. However, be
1005 aware that any non-const function call performed on the QJsonArray
1006 will render all existing iterators undefined.
1007
1008 \sa QJsonArray::iterator
1009*/
1010
1011/*! \fn QJsonArray::const_iterator::const_iterator()
1012
1013 Constructs an uninitialized iterator.
1014
1015 Functions like operator*() and operator++() should not be called
1016 on an uninitialized iterator. Use operator=() to assign a value
1017 to it before using it.
1018
1019 \sa QJsonArray::constBegin(), QJsonArray::constEnd()
1020*/
1021
1022/*! \fn QJsonArray::const_iterator::const_iterator(const QJsonArray *array, int index)
1023 \internal
1024*/
1025
1026/*! \typedef QJsonArray::const_iterator::iterator_category
1027
1028 A synonym for \e {std::random_access_iterator_tag} indicating
1029 this iterator is a random access iterator.
1030*/
1031
1032/*! \typedef QJsonArray::const_iterator::difference_type
1033
1034 \internal
1035*/
1036
1037/*! \typedef QJsonArray::const_iterator::value_type
1038
1039 \internal
1040*/
1041
1042/*! \typedef QJsonArray::const_iterator::reference
1043
1044 \internal
1045*/
1046
1047/*! \typedef QJsonArray::const_iterator::pointer
1048
1049 \internal
1050*/
1051
1052/*! \fn QJsonArray::const_iterator::const_iterator(const const_iterator &other)
1053
1054 Constructs a copy of \a other.
1055*/
1056
1057/*! \fn QJsonArray::const_iterator::const_iterator(const iterator &other)
1058
1059 Constructs a copy of \a other.
1060*/
1061
1062/*! \fn QJsonValue QJsonArray::const_iterator::operator*() const
1063
1064 Returns the current item.
1065*/
1066
1067/*! \fn QJsonValue *QJsonArray::const_iterator::operator->() const
1068
1069 Returns a pointer to the current item.
1070*/
1071
1072/*! \fn QJsonValue QJsonArray::const_iterator::operator[](int j) const
1073
1074 Returns the item at offset \a j from the item pointed to by this iterator (the item at
1075 position \c{*this + j}).
1076
1077 This function is provided to make QJsonArray iterators behave like C++
1078 pointers.
1079
1080 \sa operator+()
1081*/
1082
1083/*! \fn bool QJsonArray::const_iterator::operator==(const const_iterator &other) const
1084
1085 Returns \c true if \a other points to the same item as this
1086 iterator; otherwise returns \c false.
1087
1088 \sa operator!=()
1089*/
1090
1091/*! \fn bool QJsonArray::const_iterator::operator!=(const const_iterator &other) const
1092
1093 Returns \c true if \a other points to a different item than this
1094 iterator; otherwise returns \c false.
1095
1096 \sa operator==()
1097*/
1098
1099/*!
1100 \fn bool QJsonArray::const_iterator::operator<(const const_iterator& other) const
1101
1102 Returns \c true if the item pointed to by this iterator is less than
1103 the item pointed to by the \a other iterator.
1104*/
1105
1106/*!
1107 \fn bool QJsonArray::const_iterator::operator<=(const const_iterator& other) const
1108
1109 Returns \c true if the item pointed to by this iterator is less than
1110 or equal to the item pointed to by the \a other iterator.
1111*/
1112
1113/*!
1114 \fn bool QJsonArray::const_iterator::operator>(const const_iterator& other) const
1115
1116 Returns \c true if the item pointed to by this iterator is greater
1117 than the item pointed to by the \a other iterator.
1118*/
1119
1120/*!
1121 \fn bool QJsonArray::const_iterator::operator>=(const const_iterator& other) const
1122
1123 Returns \c true if the item pointed to by this iterator is greater
1124 than or equal to the item pointed to by the \a other iterator.
1125*/
1126
1127/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator++()
1128
1129 The prefix ++ operator, \c{++it}, advances the iterator to the
1130 next item in the array and returns an iterator to the new current
1131 item.
1132
1133 Calling this function on QJsonArray::end() leads to undefined results.
1134
1135 \sa operator--()
1136*/
1137
1138/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator++(int)
1139
1140 \overload
1141
1142 The postfix ++ operator, \c{it++}, advances the iterator to the
1143 next item in the array and returns an iterator to the previously
1144 current item.
1145*/
1146
1147/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator--()
1148
1149 The prefix -- operator, \c{--it}, makes the preceding item
1150 current and returns an iterator to the new current item.
1151
1152 Calling this function on QJsonArray::begin() leads to undefined results.
1153
1154 \sa operator++()
1155*/
1156
1157/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator--(int)
1158
1159 \overload
1160
1161 The postfix -- operator, \c{it--}, makes the preceding item
1162 current and returns an iterator to the previously current item.
1163*/
1164
1165/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator+=(int j)
1166
1167 Advances the iterator by \a j items. If \a j is negative, the
1168 iterator goes backward.
1169
1170 \sa operator-=(), operator+()
1171*/
1172
1173/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator-=(int j)
1174
1175 Makes the iterator go back by \a j items. If \a j is negative,
1176 the iterator goes forward.
1177
1178 \sa operator+=(), operator-()
1179*/
1180
1181/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator+(int j) const
1182
1183 Returns an iterator to the item at \a j positions forward from
1184 this iterator. If \a j is negative, the iterator goes backward.
1185
1186 \sa operator-(), operator+=()
1187*/
1188
1189/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator-(int j) const
1190
1191 Returns an iterator to the item at \a j positions backward from
1192 this iterator. If \a j is negative, the iterator goes forward.
1193
1194 \sa operator+(), operator-=()
1195*/
1196
1197/*! \fn int QJsonArray::const_iterator::operator-(const_iterator other) const
1198
1199 Returns the number of items between the item pointed to by \a
1200 other and the item pointed to by this iterator.
1201*/
1202
1203
1204/*!
1205 \internal
1206 */
1207void QJsonArray::detach(uint reserve)
1208{
1209 Q_UNUSED(reserve)
1210 Q_ASSERT(!reserve);
1211 detach2(0);
1212}
1213
1214/*!
1215 \internal
1216 */
1217bool QJsonArray::detach2(uint reserve)
1218{
1219 if (!d) {
1220 if (reserve >= QJsonPrivate::Value::MaxSize) {
1221 qWarning("QJson: Document too large to store in data structure");
1222 return false;
1223 }
1224 d = new QJsonPrivate::Data(reserve, QJsonValue::Array);
1225 a = static_cast<QJsonPrivate::Array *>(d->header->root());
1226 d->ref.ref();
1227 return true;
1228 }
1229 if (reserve == 0 && d->ref.loadRelaxed() == 1)
1230 return true;
1231
1232 QJsonPrivate::Data *x = d->clone(a, reserve);
1233 if (!x)
1234 return false;
1235 x->ref.ref();
1236 if (!d->ref.deref())
1237 delete d;
1238 d = x;
1239 a = static_cast<QJsonPrivate::Array *>(d->header->root());
1240 return true;
1241}
1242
1243/*!
1244 \internal
1245 */
1246void QJsonArray::compact()
1247{
1248 if (!d || !d->compactionCounter)
1249 return;
1250
1251 detach2();
1252 d->compact();
1253 a = static_cast<QJsonPrivate::Array *>(d->header->root());
1254}
1255
1256uint qHash(const QJsonArray &array, uint seed)
1257{
1258 return qHashRange(array.begin(), array.end(), seed);
1259}
1260
1261#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
1262QDebug operator<<(QDebug dbg, const QJsonArray &a)
1263{
1264 QDebugStateSaver saver(dbg);
1265 if (!a.a) {
1266 dbg << "QJsonArray()";
1267 return dbg;
1268 }
1269 QByteArray json;
1270 QJsonPrivate::Writer::arrayToJson(a.a, json, 0, true);
1271 dbg.nospace() << "QJsonArray("
1272 << json.constData() // print as utf-8 string without extra quotation marks
1273 << ")";
1274 return dbg;
1275}
1276#endif
1277
1278#ifndef QT_NO_DATASTREAM
1279QDataStream &operator<<(QDataStream &stream, const QJsonArray &array)
1280{
1281 QJsonDocument doc{array};
1282 stream << doc.toJson(QJsonDocument::Compact);
1283 return stream;
1284}
1285
1286QDataStream &operator>>(QDataStream &stream, QJsonArray &array)
1287{
1288 QJsonDocument doc;
1289 stream >> doc;
1290 array = doc.array();
1291 return stream;
1292}
1293#endif
1294
1295QT_END_NAMESPACE
1296
1297