diff options
author | Jamey Hicks <jamey.hicks@nokia.com> | 2012-01-02 18:21:58 -0800 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2012-01-03 10:22:26 +0100 |
commit | 1a826d7fd78b902e5602a69271c41a103a07e8be (patch) | |
tree | 2106864bc906ceee225d5c813a6acb810c5e9c7b | |
parent | f98a7f10d295be310368c1822281a07f11da5f3d (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.cpp | 28 | ||||
-rw-r--r-- | tests/auto/tst_qtjson.cpp | 30 |
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() |