diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-01-09 14:57:42 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2012-01-11 14:58:00 +0100 |
commit | 1fca88779c35a9adc848e482be2ddaca5e54a3db (patch) | |
tree | b3190a354302c4660e130e9d7c4d298bceb493e0 | |
parent | 0d8eba82a4a5307ff785d157749adf66341a896a (diff) |
Add non const QJsonArray/Object::operator[]
Added a QJsonValueRef helper class to implement
this with the correct semantics.
Change-Id: Ifa5d4ce15b36c4bd054272c4acb9e13a646a98fd
Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Denis Dzyubenko <denis.dzyubenko@nokia.com>
-rw-r--r-- | src/qjsonarray.cpp | 12 | ||||
-rw-r--r-- | src/qjsonarray.h | 2 | ||||
-rw-r--r-- | src/qjsonglobal.h | 1 | ||||
-rw-r--r-- | src/qjsonobject.cpp | 49 | ||||
-rw-r--r-- | src/qjsonobject.h | 12 | ||||
-rw-r--r-- | src/qjsonvalue.cpp | 29 | ||||
-rw-r--r-- | src/qjsonvalue.h | 42 | ||||
-rw-r--r-- | tests/auto/tst_qtjson.cpp | 28 |
8 files changed, 157 insertions, 18 deletions
diff --git a/src/qjsonarray.cpp b/src/qjsonarray.cpp index f481eb4..fd27763 100644 --- a/src/qjsonarray.cpp +++ b/src/qjsonarray.cpp @@ -246,12 +246,11 @@ bool QJsonArray::contains(const QJsonValue &element) const return false; } -//JsonValue &JsonArray::operator[](int i) -//{ -// Q_ASSERT(i >= 0 && i < a->length); -// detach(); - -//} +QJsonValueRef QJsonArray::operator [](int i) +{ + Q_ASSERT(a && i >= 0 && i < (int)a->length); + return QJsonValueRef(this, i); +} QJsonValue QJsonArray::operator[](int i) const { @@ -330,3 +329,4 @@ QDebug operator<<(QDebug dbg, const QtJson::QJsonArray &a) } QT_END_NAMESPACE + diff --git a/src/qjsonarray.h b/src/qjsonarray.h index 94296cf..29ed254 100644 --- a/src/qjsonarray.h +++ b/src/qjsonarray.h @@ -83,7 +83,7 @@ public: void replace(int i, const QJsonValue &value); bool contains(const QJsonValue &element) const; - // ### JsonValueRef &operator[](int i); + QJsonValueRef operator[](int i); QJsonValue operator[](int i) const; bool operator==(const QJsonArray &other) const; diff --git a/src/qjsonglobal.h b/src/qjsonglobal.h index 5295061..ff7afcb 100644 --- a/src/qjsonglobal.h +++ b/src/qjsonglobal.h @@ -63,6 +63,7 @@ namespace QtJson }; class QJsonValue; + class QJsonValueRef; class QJsonObject; class QJsonArray; class QJsonDocument; diff --git a/src/qjsonobject.cpp b/src/qjsonobject.cpp index 219790e..613d382 100644 --- a/src/qjsonobject.cpp +++ b/src/qjsonobject.cpp @@ -149,17 +149,27 @@ QJsonValue QJsonObject::value(const QString &key) const for (uint i = 0; i < o->length; ++i) { Private::Entry *e = o->entryAt(i); - if (e->value.latinKey) { - if (e->shallowLatin1Key() == key) - return QJsonValue(d, o, e->value); - } else { - if (e->shallowKey() == key) - return QJsonValue(d, o, e->value); - } + if (e->matchesKey(key)) + return QJsonValue(d, o, e->value); } return QJsonValue(QJsonValue::Undefined); } +QJsonValue QJsonObject::operator [](const QString &key) const +{ + return value(key); +} + +QJsonValueRef QJsonObject::operator [](const QString &key) +{ + int index = o ? o->indexOf(key) : -1; + if (index < 0) { + insert(key, QJsonValue()); + index = o->indexOf(key); + } + return QJsonValueRef(this, index); +} + void QJsonObject::insert(const QString &key, const QJsonValue &value) { if (value.t == QJsonValue::Undefined) { @@ -298,6 +308,31 @@ void QJsonObject::compact() const const_cast<QJsonObject *>(this)->o = static_cast<Private::Object *>(d->header->root()); } +QString QJsonObject::keyAt(int i) +{ + Q_ASSERT(o && i >= 0 && i < (int)o->length); + + Private::Entry *e = o->entryAt(i); + return e->key(); +} + +QJsonValue QJsonObject::valueAt(int i) +{ + Q_ASSERT(o && i >= 0 && i < (int)o->length); + + Private::Entry *e = o->entryAt(i); + return QJsonValue(d, o, e->value); +} + +void QJsonObject::setValueAt(int i, const QJsonValue &val) +{ + Q_ASSERT(o && i >= 0 && i < (int)o->length); + + Private::Entry *e = o->entryAt(i); + insert(e->key(), val); +} + + } // namespace QtJson QT_BEGIN_NAMESPACE diff --git a/src/qjsonobject.h b/src/qjsonobject.h index 7b3cae7..dff0e9e 100644 --- a/src/qjsonobject.h +++ b/src/qjsonobject.h @@ -69,11 +69,9 @@ public: inline int count() const { return size(); } bool isEmpty() const; - // ### rather use an iterator? -// QString keyAt(int); -// QSonValue valueAt(int) - QJsonValue value(const QString &key) const; + QJsonValue operator[] (const QString &key) const; + QJsonValueRef operator[] (const QString &key); void insert(const QString &key, const QJsonValue &value); void remove(const QString &key); @@ -88,12 +86,18 @@ private: friend class QJsonValue; friend class QJsonDocument; friend class QJsonParser; + friend class QJsonValueRef; + friend QT_PREPEND_NAMESPACE(QDebug) (QT_PREPEND_NAMESPACE(operator<<)) (QT_PREPEND_NAMESPACE(QDebug) dbg, const QJsonObject &o); QJsonObject(Private::Data *data, Private::Object *object); void detach(uint reserve = 0); void compact() const; + QString keyAt(int i); + QJsonValue valueAt(int i); + void setValueAt(int i, const QJsonValue &val); + Private::Data *d; Private::Object *o; }; diff --git a/src/qjsonvalue.cpp b/src/qjsonvalue.cpp index 1e402de..0756e35 100644 --- a/src/qjsonvalue.cpp +++ b/src/qjsonvalue.cpp @@ -402,6 +402,35 @@ void QJsonValue::copyData(char *dest, bool compressed) const } } + +QJsonValueRef &QJsonValueRef::operator =(const QJsonValue &val) +{ + if (is_object) { + o->setValueAt(index, val); + } else { + a->replace(index, val); + } + return *this; +} + +QJsonArray QJsonValueRef::toArray() const +{ + return toValue().toArray(); +} + +QJsonObject QJsonValueRef::toObject() const +{ + return toValue().toObject(); +} + +QJsonValue QJsonValueRef::toValue() const +{ + if (!is_object) + return a->at(index); + return o->valueAt(index); +} + + } // namespace QtJson QT_BEGIN_NAMESPACE diff --git a/src/qjsonvalue.h b/src/qjsonvalue.h index 9c62f78..4f5b7da 100644 --- a/src/qjsonvalue.h +++ b/src/qjsonvalue.h @@ -135,5 +135,47 @@ private: }; }; +class Q_JSON_EXPORT QJsonValueRef +{ +public: + QJsonValueRef(QJsonArray *array, int idx) + : a(array), is_object(false), index(idx) {} + QJsonValueRef(QJsonObject *object, int idx) + : o(object), is_object(true), index(idx) {} + + inline operator QJsonValue() const { return toValue(); } + QJsonValueRef &operator = (const QJsonValue &val); + + inline QJsonValue::Type type() const { return toValue().type(); } + inline bool isNull() const { return type() == QJsonValue::Null; } + inline bool isBool() const { return type() == QJsonValue::Bool; } + inline bool isNumber() const { return type() == QJsonValue::Number; } + inline bool isString() const { return type() == QJsonValue::String; } + inline bool isArray() const { return type() == QJsonValue::Array; } + inline bool isObject() const { return type() == QJsonValue::Object; } + inline bool isUndefined() const { return type() == QJsonValue::Undefined; } + + inline bool toBool() const { return toValue().toBool(); } + inline double toNumber() const { return toValue().toNumber(); } + inline int toInt() const { return toValue().toInt(); } + inline QString toString() const { return toValue().toString(); } + inline QJsonArray toArray() const; + inline QJsonObject toObject() const; + + inline bool operator==(const QJsonValue &other) const { return toValue() == other; } + inline bool operator!=(const QJsonValue &other) const { return toValue() != other; } + +private: + QJsonValue toValue() const; + + union { + QJsonArray *a; + QJsonObject *o; + }; + uint is_object : 1; + uint index : 31; +}; + + } #endif // QJSONVALUE_H diff --git a/tests/auto/tst_qtjson.cpp b/tests/auto/tst_qtjson.cpp index 84243d4..735c892 100644 --- a/tests/auto/tst_qtjson.cpp +++ b/tests/auto/tst_qtjson.cpp @@ -69,6 +69,8 @@ private Q_SLOTS: void testArrayNestedEmpty(); void testObjectNestedEmpty(); + void testValueRef(); + void testDocument(); void nullValues(); @@ -469,6 +471,32 @@ void TestQtJson::testObjectNestedEmpty() QCOMPARE(reconstituted.value("inner2").type(), QJsonValue::Object); } +void TestQtJson::testValueRef() +{ + QJsonArray array; + array.append(1.); + array.append(2.); + array.append(3.); + array[1] = false; + + QCOMPARE(array.size(), 3); + QCOMPARE(array.at(0).toNumber(), 1.); + QCOMPARE(array.at(2).toNumber(), 3.); + QCOMPARE(array.at(1).type(), QJsonValue::Bool); + QCOMPARE(array.at(1).toBool(), false); + + QJsonObject object; + object[QLatin1String("key")] = true; + QCOMPARE(object.size(), 1); + object.insert(QLatin1String("null"), QJsonValue()); + QCOMPARE(object.value(QLatin1String("null")), QJsonValue()); + object[QLatin1String("null")] = 100.; + QCOMPARE(object.value(QLatin1String("null")).type(), QJsonValue::Number); + QJsonValue val = object[QLatin1String("null")]; + QCOMPARE(val.toNumber(), 100.); + QCOMPARE(object.size(), 2); +} + void TestQtJson::testDocument() { QJsonDocument doc; |