summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2011-12-08 11:07:35 +0100
committerHicks James <jamey.hicks@nokia.com>2011-12-08 15:20:40 +0100
commit3105e87528a0ba786ef6b15265dec5e597317dac (patch)
tree5997a4c50c33112b42c5a905e7c1e14a4bfaadc4
parentd168fcbfdc0e9d5357209a0e7f06a6b8c02308a8 (diff)
Add an explicit UndefinedValue type
The type is required to distinguish between a null entry and a non existant entry in objects and arrays. Now trying to read a non existant key or an out of bounds value in the array will return an undefined JsonValue. Also added a private constructor to JsonValue to avoid implicit conversions from const char * to bool when constructing values. Change-Id: Icbb065503af0eb828f8c1fc681b329be8b23cb46 Reviewed-by: Hicks James <jamey.hicks@nokia.com>
-rw-r--r--src/qjsonarray.cpp6
-rw-r--r--src/qjsonglobal.h3
-rw-r--r--src/qjsonobject.cpp11
-rw-r--r--src/qjsonvalue.cpp9
-rw-r--r--src/qjsonvalue.h7
-rw-r--r--tests/auto/tst_qtjson.cpp57
6 files changed, 65 insertions, 28 deletions
diff --git a/src/qjsonarray.cpp b/src/qjsonarray.cpp
index 6c54cb6..b9a0dd2 100644
--- a/src/qjsonarray.cpp
+++ b/src/qjsonarray.cpp
@@ -94,7 +94,7 @@ bool JsonArray::isEmpty() const
JsonValue JsonArray::at(int i) const
{
if (!a || i < 0 || i >= (int)a->length)
- return JsonValue();
+ return JsonValue(UndefinedValue);
return JsonValue(d, a, a->at(i));
}
@@ -127,7 +127,7 @@ void JsonArray::removeAt(int i)
JsonValue JsonArray::takeAt(int i)
{
if (!a || i < 0 || i >= (int)a->length)
- return JsonValue();
+ return JsonValue(UndefinedValue);
detach();
@@ -153,7 +153,7 @@ void JsonArray::insert(int i, const JsonValue &value)
int valueOffset = a->reserveSpace(valueSize, i, 1);
Value &v = (*a)[i];
- v.type = value.t;
+ v.type = (value.t == UndefinedValue ? NullValue : value.t);
v.compressed = compressed;
v.val = value.valueToStore(valueOffset);
if (valueSize)
diff --git a/src/qjsonglobal.h b/src/qjsonglobal.h
index 09cc9fb..970a8f2 100644
--- a/src/qjsonglobal.h
+++ b/src/qjsonglobal.h
@@ -27,7 +27,8 @@ namespace QtJson
NumberValue = 0x2,
StringValue = 0x3,
ArrayValue = 0x4,
- ObjectValue = 0x5
+ ObjectValue = 0x5,
+ UndefinedValue = 0x80
};
}
diff --git a/src/qjsonobject.cpp b/src/qjsonobject.cpp
index 0b02dea..209a5d7 100644
--- a/src/qjsonobject.cpp
+++ b/src/qjsonobject.cpp
@@ -136,7 +136,7 @@ JsonValue JsonObject::value(const QString &key) const
return JsonValue(d, o, e->value);
}
}
- return JsonValue();
+ return JsonValue(UndefinedValue);
}
static bool useCompressed(const QString &s)
@@ -155,6 +155,11 @@ static bool useCompressed(const QString &s)
void JsonObject::insert(const QString &key, const JsonValue &value)
{
+ if (value.t == UndefinedValue) {
+ remove(key);
+ return;
+ }
+
bool compressed;
int valueSize = value.requiredStorage(&compressed);
@@ -208,11 +213,11 @@ void JsonObject::remove(const QString &key)
JsonValue JsonObject::take(const QString &key)
{
if (!o)
- return JsonValue();
+ return JsonValue(UndefinedValue);
int index = o->indexOf(key);
if (index < 0)
- return JsonValue();
+ return JsonValue(UndefinedValue);
Entry *e = o->entryAt(index);
o->removeItems(index, 1);
diff --git a/src/qjsonvalue.cpp b/src/qjsonvalue.cpp
index 2527500..15d248a 100644
--- a/src/qjsonvalue.cpp
+++ b/src/qjsonvalue.cpp
@@ -12,8 +12,8 @@ using namespace QtJson;
static const Base emptyBase = { sizeof(Base), 0, 0, 0 };
-JsonValue::JsonValue()
- : t(NullValue), d(0), dbl(0.)
+JsonValue::JsonValue(ValueType type)
+ : t(type), d(0), dbl(0.)
{
}
@@ -22,6 +22,7 @@ JsonValue::JsonValue(Data *data, Base *base, const Value &v)
{
t = (ValueType)v.type;
switch (t) {
+ case UndefinedValue:
case NullValue:
dbl = 0;
break;
@@ -191,6 +192,7 @@ QVariant JsonValue::toVariant() const
case ObjectValue:
return JsonObject(d, object).toVariantMap();
case NullValue:
+ case UndefinedValue:
break;
}
return QVariant();
@@ -288,6 +290,7 @@ bool JsonValue::operator==(const JsonValue &other) const
return false;
switch (t) {
+ case UndefinedValue:
case NullValue:
break;
case BooleanValue:
@@ -347,6 +350,7 @@ int JsonValue::requiredStorage(bool *compressed) const
return array ? array->size : sizeof(Array);
case ObjectValue:
return object ? object->size : sizeof(Object);
+ case UndefinedValue:
case NullValue:
case BooleanValue:
break;
@@ -357,6 +361,7 @@ int JsonValue::requiredStorage(bool *compressed) const
uint JsonValue::valueToStore(uint offset) const
{
switch (t) {
+ case UndefinedValue:
case NullValue:
break;
case BooleanValue:
diff --git a/src/qjsonvalue.h b/src/qjsonvalue.h
index 74f2702..6ace201 100644
--- a/src/qjsonvalue.h
+++ b/src/qjsonvalue.h
@@ -9,7 +9,7 @@ namespace QtJson {
class JsonValue {
public:
- JsonValue();
+ JsonValue(ValueType = NullValue);
JsonValue(bool b);
JsonValue(double n);
JsonValue(int n);
@@ -27,8 +27,7 @@ public:
QVariant toVariant() const;
ValueType type() const;
-
-// template <> value() const;
+ inline bool isUndefined() const { return type() == UndefinedValue; }
void setValue(bool);
void setValue(double);
@@ -51,6 +50,8 @@ public:
void detach();
private:
+ // avoid implicit conversions from char * to bool
+ inline JsonValue(const void *) {}
friend class Data;
friend class Value;
friend class JsonArray;
diff --git a/tests/auto/tst_qtjson.cpp b/tests/auto/tst_qtjson.cpp
index da1cc57..8926a4c 100644
--- a/tests/auto/tst_qtjson.cpp
+++ b/tests/auto/tst_qtjson.cpp
@@ -73,6 +73,8 @@ private Q_SLOTS:
void nullArrays();
void nullObject();
+ void undefinedValues();
+
void fromVariantMap();
void toVariantMap();
@@ -163,7 +165,7 @@ void TestQtJson::testObjectSimple()
// if we put a JsonValue into the JsonObject and retreive
// it, it should be identical.
- JsonValue value("foo");
+ JsonValue value(QLatin1String("foo"));
object.insert("value", value);
QCOMPARE(object.value("value"), value);
@@ -196,7 +198,7 @@ void TestQtJson::testArraySimple()
// if we put a JsonValue into the JsonArray and retreive
// it, it should be identical.
- JsonValue value("foo");
+ JsonValue value(QLatin1String("foo"));
array.append(value);
QCOMPARE(array.at(3), value);
@@ -217,15 +219,15 @@ void TestQtJson::testArraySimple()
QCOMPARE(array.last().type(), NullValue);
QCOMPARE(array.last(), JsonValue());
- QCOMPARE(array.at(-1), JsonValue());
- QCOMPARE(array.at(array.size()), JsonValue());
+ QCOMPARE(array.at(-1), JsonValue(UndefinedValue));
+ QCOMPARE(array.at(array.size()), JsonValue(UndefinedValue));
}
void TestQtJson::testValueObject()
{
JsonObject object;
object.insert("number", 999.);
- object.insert("string", "test");
+ object.insert("string", QLatin1String("test"));
object.insert("boolean", true);
JsonValue value(object);
@@ -243,7 +245,7 @@ void TestQtJson::testValueArray()
{
JsonArray array;
array.append(999.);
- array.append("test");
+ array.append(QLatin1String("test"));
array.append(true);
JsonValue value(array);
@@ -253,7 +255,7 @@ void TestQtJson::testValueArray()
QCOMPARE(value.toArray(), array);
// if we modify the original array, it should detach
- array.append("test");
+ array.append(QLatin1String("test"));
QVERIFY2(value.toArray() != array, "array should have detached");
}
@@ -379,7 +381,7 @@ void TestQtJson::testDocument()
QCOMPARE(doc.isEmpty(), false);
QCOMPARE(doc.type(), ObjectValue);
- object.insert(QLatin1String("Key"), "Value");
+ object.insert(QLatin1String("Key"), QLatin1String("Value"));
doc.setObject(object);
QCOMPARE(doc.isEmpty(), false);
QCOMPARE(doc.type(), ObjectValue);
@@ -429,9 +431,9 @@ void TestQtJson::nullArrays()
QVERIFY(nonNull != nullArray);
QCOMPARE(nullArray.size(), 0);
- QCOMPARE(nullArray.takeAt(0), JsonValue());
- QCOMPARE(nullArray.first(), JsonValue());
- QCOMPARE(nullArray.last(), JsonValue());
+ QCOMPARE(nullArray.takeAt(0), JsonValue(UndefinedValue));
+ QCOMPARE(nullArray.first(), JsonValue(UndefinedValue));
+ QCOMPARE(nullArray.last(), JsonValue(UndefinedValue));
nullArray.removeAt(0);
nullArray.removeAt(-1);
@@ -439,9 +441,9 @@ void TestQtJson::nullArrays()
nullArray.removeAt(0);
QCOMPARE(nullArray.size(), 0);
- QCOMPARE(nullArray.takeAt(0), JsonValue());
- QCOMPARE(nullArray.first(), JsonValue());
- QCOMPARE(nullArray.last(), JsonValue());
+ QCOMPARE(nullArray.takeAt(0), JsonValue(UndefinedValue));
+ QCOMPARE(nullArray.first(), JsonValue(UndefinedValue));
+ QCOMPARE(nullArray.last(), JsonValue(UndefinedValue));
nullArray.removeAt(0);
nullArray.removeAt(-1);
@@ -463,7 +465,7 @@ void TestQtJson::nullObject()
QCOMPARE(nullObject.keys(), QStringList());
nullObject.remove("foo");
QCOMPARE(nullObject, JsonObject());
- QCOMPARE(nullObject.take("foo"), JsonValue());
+ QCOMPARE(nullObject.take("foo"), JsonValue(UndefinedValue));
QCOMPARE(nullObject.contains("foo"), false);
nullObject.detach(16);
@@ -476,10 +478,33 @@ void TestQtJson::nullObject()
QCOMPARE(nullObject.keys(), QStringList());
nullObject.remove("foo");
QCOMPARE(nullObject, JsonObject());
- QCOMPARE(nullObject.take("foo"), JsonValue());
+ QCOMPARE(nullObject.take("foo"), JsonValue(UndefinedValue));
QCOMPARE(nullObject.contains("foo"), false);
}
+void TestQtJson::undefinedValues()
+{
+ JsonObject object;
+ object.insert("Key", JsonValue(UndefinedValue));
+ QCOMPARE(object.numKeys(), 0);
+
+ object.insert("Key", QLatin1String("Value"));
+ QCOMPARE(object.numKeys(), 1);
+ QCOMPARE(object.value("Key").type(), StringValue);
+ QCOMPARE(object.value("foo").type(), UndefinedValue);
+ object.insert("Key", JsonValue(UndefinedValue));
+ QCOMPARE(object.numKeys(), 0);
+ QCOMPARE(object.value("Key").type(), UndefinedValue);
+
+ JsonArray array;
+ array.append(JsonValue(UndefinedValue));
+ QCOMPARE(array.size(), 1);
+ QCOMPARE(array.at(0).type(), NullValue);
+
+ QCOMPARE(array.at(1).type(), UndefinedValue);
+ QCOMPARE(array.at(-1).type(), UndefinedValue);
+}
+
void TestQtJson::fromVariantMap()
{