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
4#include "qbinaryjsonarray_p.h"
5#include "qbinaryjson_p.h"
6
7#include <qjsonarray.h>
8
9QT_BEGIN_NAMESPACE
10
11QBinaryJsonArray::~QBinaryJsonArray()
12{
13 if (d && !d->ref.deref())
14 delete d;
15}
16
17QBinaryJsonArray QBinaryJsonArray::fromJsonArray(const QJsonArray &array)
18{
19 QBinaryJsonArray binary;
20 for (const QJsonValue value : array)
21 binary.append(value: QBinaryJsonValue::fromJsonValue(json: value));
22 if (binary.d) // We want to compact it as it is a root item now
23 binary.d->compactionCounter++;
24 binary.compact();
25 return binary;
26}
27
28void QBinaryJsonArray::append(const QBinaryJsonValue &value)
29{
30 const uint i = a ? a->length() : 0;
31
32 bool compressed;
33 uint valueSize = QBinaryJsonPrivate::Value::requiredStorage(v: value, compressed: &compressed);
34
35 if (!detach(reserve: valueSize + sizeof(QBinaryJsonPrivate::Value)))
36 return;
37
38 if (!a->length())
39 a->tableOffset = sizeof(QBinaryJsonPrivate::Array);
40
41 uint valueOffset = a->reserveSpace(dataSize: valueSize, posInTable: i, numItems: 1, replace: false);
42 if (!valueOffset)
43 return;
44
45 QBinaryJsonPrivate::Value *v = a->at(i);
46 v->setType(value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
47 v->setIsLatinOrIntValue(compressed);
48 v->setIsLatinKey(false);
49 v->setValue(QBinaryJsonPrivate::Value::valueToStore(v: value, offset: valueOffset));
50 if (valueSize) {
51 QBinaryJsonPrivate::Value::copyData(v: value, dest: reinterpret_cast<char *>(a) + valueOffset,
52 compressed);
53 }
54}
55
56char *QBinaryJsonArray::takeRawData(uint *size)
57{
58 if (d)
59 return d->takeRawData(size);
60 *size = 0;
61 return nullptr;
62}
63
64bool QBinaryJsonArray::detach(uint reserve)
65{
66 if (!d) {
67 if (reserve >= QBinaryJsonPrivate::Value::MaxSize) {
68 qWarning(msg: "QBinaryJson: Document too large to store in data structure");
69 return false;
70 }
71 d = new QBinaryJsonPrivate::MutableData(reserve, QJsonValue::Array);
72 a = static_cast<QBinaryJsonPrivate::Array *>(d->header->root());
73 d->ref.ref();
74 return true;
75 }
76 if (reserve == 0 && d->ref.loadRelaxed() == 1)
77 return true;
78
79 QBinaryJsonPrivate::MutableData *x = d->clone(b: a, reserve);
80 if (!x)
81 return false;
82 x->ref.ref();
83 if (!d->ref.deref())
84 delete d;
85 d = x;
86 a = static_cast<QBinaryJsonPrivate::Array *>(d->header->root());
87 return true;
88}
89
90void QBinaryJsonArray::compact()
91{
92 if (!d || !d->compactionCounter)
93 return;
94
95 detach();
96 d->compact();
97 a = static_cast<QBinaryJsonPrivate::Array *>(d->header->root());
98}
99
100QT_END_NAMESPACE
101
102

source code of qt5compat/src/core5/serialization/qbinaryjsonarray.cpp