summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamey Hicks <jamey.hicks@nokia.com>2012-01-02 18:21:58 -0800
committerLars Knoll <lars.knoll@nokia.com>2012-01-03 10:22:26 +0100
commit1a826d7fd78b902e5602a69271c41a103a07e8be (patch)
tree2106864bc906ceee225d5c813a6acb810c5e9c7b
parentf98a7f10d295be310368c1822281a07f11da5f3d (diff)
Detach nested objects or arrays when making JsonDocuments from them.
JsonDocument does not track the offset within an object, so making a JsonDocument from a nested object had the effect of making a document from the outermost containing object. Even more disconcerting, making a document from a nested array yielded the outermost container, which might have been an object. Change-Id: I5cc1db26ff601dc81c9983b5a07b3fee7a7c65ce Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
-rw-r--r--src/qjsondocument.cpp28
-rw-r--r--tests/auto/tst_qtjson.cpp30
2 files changed, 58 insertions, 0 deletions
diff --git a/src/qjsondocument.cpp b/src/qjsondocument.cpp
index ef0a8b9..c7833f4 100644
--- a/src/qjsondocument.cpp
+++ b/src/qjsondocument.cpp
@@ -18,6 +18,13 @@ JsonDocument::JsonDocument()
JsonDocument::JsonDocument(const JsonObject &object)
: d(object.d)
{
+ if (object.d && (object.o != object.d->header->root())) {
+ JsonObject detached(object);
+ detached.detach();
+ d = detached.d;
+ d->ref.ref();
+ return;
+ }
if (!d)
d = new Data(0, ObjectValue);
d->ref.ref();
@@ -26,6 +33,13 @@ JsonDocument::JsonDocument(const JsonObject &object)
JsonDocument::JsonDocument(const JsonArray &array)
: d(array.d)
{
+ if (array.d && (array.a != array.d->header->root())) {
+ JsonArray detached(array);
+ detached.detach();
+ d = detached.d;
+ d->ref.ref();
+ return;
+ }
if (!d)
d = new Data(0, ArrayValue);
d->ref.ref();
@@ -176,6 +190,13 @@ void JsonDocument::setObject(const JsonObject &object)
if (d && !d->ref.deref())
delete d;
+ if (object.o && (object.o != object.d->header->root())) {
+ JsonObject detached(object);
+ detached.detach();
+ d = detached.d;
+ d->ref.ref();
+ return;
+ }
d = object.d;
if (!d)
d = new Data(0, ObjectValue);
@@ -187,6 +208,13 @@ void JsonDocument::setArray(const JsonArray &array)
if (d && !d->ref.deref())
delete d;
+ if (array.d && (array.a != array.d->header->root())) {
+ JsonArray detached(array);
+ detached.detach();
+ d = detached.d;
+ d->ref.ref();
+ return;
+ }
d = array.d;
if (!d)
d = new Data(0, ArrayValue);
diff --git a/tests/auto/tst_qtjson.cpp b/tests/auto/tst_qtjson.cpp
index c506754..1d06dd9 100644
--- a/tests/auto/tst_qtjson.cpp
+++ b/tests/auto/tst_qtjson.cpp
@@ -479,6 +479,36 @@ void TestQtJson::testDocument()
QCOMPARE(doc.type(), ArrayValue);
QVERIFY(doc.array() == array);
QVERIFY(doc.object() == JsonObject());
+
+ JsonObject outer;
+ outer.insert(QLatin1String("outerKey"), 22);
+ JsonObject inner;
+ inner.insert(QLatin1String("innerKey"), 42);
+ outer.insert(QLatin1String("innter"), inner);
+ JsonArray innerArray;
+ innerArray.append(23);
+ outer.insert(QLatin1String("innterArray"), innerArray);
+
+ JsonDocument doc2(outer.value(QLatin1String("innter")).toObject());
+ QVERIFY(doc2.object().contains(QLatin1String("innerKey")));
+ QCOMPARE(doc2.object().value(QLatin1String("innerKey")), JsonValue(42));
+
+ JsonDocument doc3;
+ doc3.setObject(outer.value(QLatin1String("innter")).toObject());
+ QCOMPARE(doc3.type(), ObjectValue);
+ QVERIFY(doc3.object().contains(QLatin1String("innerKey")));
+ QCOMPARE(doc3.object().value(QLatin1String("innerKey")), JsonValue(42));
+
+ JsonDocument doc4(outer.value(QLatin1String("innterArray")).toArray());
+ QCOMPARE(doc4.type(), ArrayValue);
+ QCOMPARE(doc4.array().size(), 1);
+ QCOMPARE(doc4.array().at(0), JsonValue(23));
+
+ JsonDocument doc5;
+ doc5.setArray(outer.value(QLatin1String("innterArray")).toArray());
+ QCOMPARE(doc5.type(), ArrayValue);
+ QCOMPARE(doc5.array().size(), 1);
+ QCOMPARE(doc5.array().at(0), JsonValue(23));
}
void TestQtJson::nullValues()