/**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include #include namespace QtJson { QJsonArray::QJsonArray() : d(0), a(0) { } QJsonArray::QJsonArray(Private::Data *data, Private::Array *array) : d(data), a(array) { d->ref.ref(); } QJsonArray::~QJsonArray() { if (d && !d->ref.deref()) delete d; } QJsonArray::QJsonArray(const QJsonArray &other) { d = other.d; a = other.a; if (d) d->ref.ref(); } QJsonArray &QJsonArray::operator =(const QJsonArray &other) { if (d != other.d) { if (d && !d->ref.deref()) delete d; d = other.d; a = other.a; if (d) d->ref.ref(); } return *this; } QJsonArray QJsonArray::fromStringList(const QStringList &list) { QJsonArray array; for (QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) array.append(QJsonValue(*it)); return array; } QJsonArray QJsonArray::fromVariantList(const QVariantList &list) { QJsonArray array; for (QVariantList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) array.append(QJsonValue::fromVariant(*it)); return array; } QVariantList QJsonArray::toVariantList() const { QVariantList list; if (a) { for (int i = 0; i < (int)a->length; ++i) list.append(QJsonValue(d, a, a->at(i)).toVariant()); } return list; } int QJsonArray::size() const { if (!d) return 0; return (int)a->length; } bool QJsonArray::isEmpty() const { if (!d) return true; return !a->length; } QJsonValue QJsonArray::at(int i) const { if (!a || i < 0 || i >= (int)a->length) return QJsonValue(QJsonValue::Undefined); return QJsonValue(d, a, a->at(i)); } QJsonValue QJsonArray::first() const { return at(0); } QJsonValue QJsonArray::last() const { return at(a ? (a->length - 1) : 0); } void QJsonArray::prepend(const QJsonValue &value) { insert(0, value); } void QJsonArray::append(const QJsonValue &value) { insert(a ? a->length : 0, value); } void QJsonArray::removeAt(int i) { if (!a || i < 0 || i >= (int)a->length) return; detach(); a->removeItems(i, 1); ++d->compactionCounter; if (d->compactionCounter > 32 && d->compactionCounter >= (int)a->length/2) compact(); } QJsonValue QJsonArray::takeAt(int i) { if (!a || i < 0 || i >= (int)a->length) return QJsonValue(QJsonValue::Undefined); detach(); QJsonValue v(d, a, a->at(i)); v.detach(); removeAt(i); return v; } void QJsonArray::insert(int i, const QJsonValue &value) { Q_ASSERT (i >= 0 && i <= (int)(a ? a->length : 0)); bool compressed; int valueSize = value.requiredStorage(&compressed); detach(valueSize + sizeof(Private::Value)); if (!a->length) a->tableOffset = sizeof(Private::Array); int valueOffset = a->reserveSpace(valueSize, i, 1, false); Private::Value &v = (*a)[i]; v.type = (value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t); v.latinOrIntValue = compressed; v.latinKey = false; v.val = value.valueToStore(valueOffset); if (valueSize) value.copyData((char *)a + valueOffset, compressed); } void QJsonArray::replace(int i, const QJsonValue &value) { Q_ASSERT (a && i >= 0 && i < (int)(a->length)); bool compressed; int valueSize = value.requiredStorage(&compressed); detach(valueSize); if (!a->length) a->tableOffset = sizeof(Private::Array); int valueOffset = a->reserveSpace(valueSize, i, 1, true); Private::Value &v = (*a)[i]; v.type = (value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t); v.latinOrIntValue = compressed; v.latinKey = false; v.val = value.valueToStore(valueOffset); if (valueSize) value.copyData((char *)a + valueOffset, compressed); ++d->compactionCounter; if (d->compactionCounter > 32 && d->compactionCounter >= (int)a->length/2) compact(); } bool QJsonArray::contains(const QJsonValue &element) const { for (int i = 0; i < size(); i++) { if (at(i) == element) return true; } return false; } QJsonValueRef QJsonArray::operator [](int i) { Q_ASSERT(a && i >= 0 && i < (int)a->length); return QJsonValueRef(this, i); } QJsonValue QJsonArray::operator[](int i) const { return at(i); } bool QJsonArray::operator==(const QJsonArray &other) const { if (a == other.a) return true; if (!a) return !other.a->length; if (!other.a) return !a->length; if (a->length != other.a->length) return false; for (int i = 0; i < (int)a->length; ++i) { if (QJsonValue(d, a, a->at(i)) != QJsonValue(other.d, other.a, other.a->at(i))) return false; } return true; } bool QJsonArray::operator!=(const QJsonArray &other) const { return !(*this == other); } void QJsonArray::detach(uint reserve) { if (!d) { d = new Private::Data(reserve, QJsonValue::Array); a = static_cast(d->header->root()); d->ref.ref(); return; } if (reserve == 0 && d->ref.load() == 1) return; Private::Data *x = d->detach(a, reserve); x->ref.ref(); if (!d->ref.deref()) delete d; d = x; a = static_cast(d->header->root()); } void QJsonArray::compact() const { if (!d || !d->compactionCounter) return; const_cast(this)->detach(); d->compact(); const_cast(this)->a = static_cast(d->header->root()); } } // namespace QtJson QT_BEGIN_NAMESPACE QDebug operator<<(QDebug dbg, const QtJson::QJsonArray &a) { if (!a.a) { dbg << "QJsonArray()"; return dbg; } QByteArray json; QtJson::QJsonWriter::arrayToJson(a.a, json, 0, true); dbg.nospace() << "QJsonArray(" << json.constData() // print as utf-8 string without extra quotation marks << ")"; return dbg.space(); } QT_END_NAMESPACE