summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2012-01-09 14:57:42 +0100
committerLars Knoll <lars.knoll@nokia.com>2012-01-11 14:58:00 +0100
commit1fca88779c35a9adc848e482be2ddaca5e54a3db (patch)
treeb3190a354302c4660e130e9d7c4d298bceb493e0
parent0d8eba82a4a5307ff785d157749adf66341a896a (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.cpp12
-rw-r--r--src/qjsonarray.h2
-rw-r--r--src/qjsonglobal.h1
-rw-r--r--src/qjsonobject.cpp49
-rw-r--r--src/qjsonobject.h12
-rw-r--r--src/qjsonvalue.cpp29
-rw-r--r--src/qjsonvalue.h42
-rw-r--r--tests/auto/tst_qtjson.cpp28
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;