Commit 7b92371a authored by Branislav Katreniak's avatar Branislav Katreniak

json: address review comments 2

parent 15453393
...@@ -323,7 +323,7 @@ KJ_TEST("decode test message") { ...@@ -323,7 +323,7 @@ KJ_TEST("decode test message") {
auto decodedRoot = decodedMessage.initRoot<TestAllTypes>(); auto decodedRoot = decodedMessage.initRoot<TestAllTypes>();
json.decode(encoded, decodedRoot); json.decode(encoded, decodedRoot);
//json encode serializes nan, inf and -inf as null. // json encode serializes nan, inf and -inf as null.
auto float32List = decodedRoot.getFloat32List(); auto float32List = decodedRoot.getFloat32List();
auto float64List = decodedRoot.getFloat64List(); auto float64List = decodedRoot.getFloat64List();
KJ_EXPECT(kj::isNaN(float32List[1])); KJ_EXPECT(kj::isNaN(float32List[1]));
......
...@@ -409,103 +409,129 @@ double parseFloat64(kj::StringPtr s) { ...@@ -409,103 +409,129 @@ double parseFloat64(kj::StringPtr s) {
template <typename SetFn, typename DecodeArrayFn, typename DecodeObjectFn> template <typename SetFn, typename DecodeArrayFn, typename DecodeObjectFn>
void decodeField(Type type, JsonValue::Reader value, SetFn setFn, DecodeArrayFn decodeArrayFn, void decodeField(Type type, JsonValue::Reader value, SetFn setFn, DecodeArrayFn decodeArrayFn,
DecodeObjectFn decodeObjectFn) { DecodeObjectFn decodeObjectFn) {
//This code relies on conversions in DynamicValue::Reader::as<T>. // This code relies on conversions in DynamicValue::Reader::as<T>.
switch(type.which()) { switch(type.which()) {
case schema::Type::VOID: case schema::Type::VOID:
break; break;
case schema::Type::BOOL: case schema::Type::BOOL:
if (value.isBoolean()) { switch (value.which()) {
setFn(value.getBoolean()); case JsonValue::BOOLEAN:
} else { setFn(value.getBoolean());
KJ_FAIL_REQUIRE("Expected boolean value"); break;
default:
KJ_FAIL_REQUIRE("Expected boolean value");
} }
break; break;
case schema::Type::INT8: case schema::Type::INT8:
case schema::Type::INT16: case schema::Type::INT16:
case schema::Type::INT32: case schema::Type::INT32:
case schema::Type::INT64: case schema::Type::INT64:
//Rellies on range check in DynamicValue::Reader::as<IntType> // Relies on range check in DynamicValue::Reader::as<IntType>
if (value.isNumber()) { switch (value.which()) {
setFn(value.getNumber()); case JsonValue::NUMBER:
} else if (value.isString()) { setFn(value.getNumber());
setFn(parseInt64(value.getString())); break;
} else { case JsonValue::STRING:
KJ_FAIL_REQUIRE("Expected numeric value"); setFn(parseInt64(value.getString()));
break;
default:
KJ_FAIL_REQUIRE("Expected integer value");
} }
break; break;
case schema::Type::UINT8: case schema::Type::UINT8:
case schema::Type::UINT16: case schema::Type::UINT16:
case schema::Type::UINT32: case schema::Type::UINT32:
case schema::Type::UINT64: case schema::Type::UINT64:
//Rellies on range check in DynamicValue::Reader::as<IntType> // Relies on range check in DynamicValue::Reader::as<IntType>
if (value.isNumber()) { switch (value.which()) {
setFn(value.getNumber()); case JsonValue::NUMBER:
} else if (value.isString()) { setFn(value.getNumber());
setFn(parseUInt64(value.getString())); break;
} else { case JsonValue::STRING:
KJ_FAIL_REQUIRE("Expected numeric value"); setFn(parseUInt64(value.getString()));
break;
default:
KJ_FAIL_REQUIRE("Expected integer value");
} }
break; break;
case schema::Type::FLOAT32: case schema::Type::FLOAT32:
case schema::Type::FLOAT64: case schema::Type::FLOAT64:
if (value.isNull()) { switch (value.which()) {
setFn(kj::nan()); case JsonValue::NULL_:
} else if (value.isNumber()) { setFn(kj::nan());
setFn(value.getNumber()); break;
} else if (value.isString()) { case JsonValue::NUMBER:
setFn(parseFloat64(value.getString())); setFn(value.getNumber());
} else { break;
KJ_FAIL_REQUIRE("Expected numeric value"); case JsonValue::STRING:
setFn(parseFloat64(value.getString()));
break;
default:
KJ_FAIL_REQUIRE("Expected float value");
} }
break; break;
case schema::Type::TEXT: case schema::Type::TEXT:
if (value.isString()) { switch (value.which()) {
setFn(value.getString()); case JsonValue::STRING:
} else { setFn(value.getString());
KJ_FAIL_REQUIRE("Expected string value"); break;
default:
KJ_FAIL_REQUIRE("Expected text value");
} }
break; break;
case schema::Type::DATA: case schema::Type::DATA:
if (value.isArray()) { switch (value.which()) {
auto array = value.getArray(); case JsonValue::ARRAY: {
kj::Vector<byte> data(array.size()); auto array = value.getArray();
for (auto arrayObject : array) { kj::Vector<byte> data(array.size());
auto x = int(arrayObject.getNumber()); for (auto arrayObject : array) {
KJ_REQUIRE(x >= 0 && x <= 255, "Number in array of bytes out of range."); auto x = arrayObject.getNumber();
data.add(byte(x)); KJ_REQUIRE(byte(x) == x, "Number in array of bytes out of range.");
data.add(byte(x));
}
setFn(Data::Reader(data.asPtr()));
break;
} }
setFn(Data::Reader(data.asPtr())); default:
} else { KJ_FAIL_REQUIRE("Expected data value");
KJ_FAIL_REQUIRE("Expected string value");
} }
break; break;
case schema::Type::LIST: case schema::Type::LIST:
if (value.isNull()) { switch (value.which()) {
} else if (value.isArray()) { case JsonValue::NULL_:
decodeArrayFn(value.getArray()); // nothing to do
} else { break;
KJ_FAIL_REQUIRE("Expected array value"); case JsonValue::ARRAY:
decodeArrayFn(value.getArray());
break;
default:
KJ_FAIL_REQUIRE("Expected list value");
} }
break; break;
case schema::Type::ENUM: case schema::Type::ENUM:
if (value.isString()) { switch (value.which()) {
setFn(value.getString()); case JsonValue::STRING:
} else { setFn(value.getString());
KJ_FAIL_REQUIRE("Expected enum as string value"); break;
default:
KJ_FAIL_REQUIRE("Expected enum value");
} }
break; break;
case schema::Type::STRUCT: { case schema::Type::STRUCT:
if (value.isNull()) { switch (value.which()) {
} else if (value.isObject()) { case JsonValue::NULL_:
decodeObjectFn(value.getObject()); // nothing to do
} else { break;
KJ_FAIL_REQUIRE("Expected object value"); case JsonValue::OBJECT:
decodeObjectFn(value.getObject());
break;
default:
KJ_FAIL_REQUIRE("Expected object value");
} }
break; break;
}
} }
} }
} //namespace } // namespace
void JsonCodec::decodeArray(List<JsonValue>::Reader input, DynamicList::Builder output) const { void JsonCodec::decodeArray(List<JsonValue>::Reader input, DynamicList::Builder output) const {
KJ_ASSERT(input.size() == output.size(), "Builder was not initialized to input size"); KJ_ASSERT(input.size() == output.size(), "Builder was not initialized to input size");
...@@ -535,7 +561,7 @@ void JsonCodec::decodeObject(List<JsonValue::Field>::Reader input, DynamicStruct ...@@ -535,7 +561,7 @@ void JsonCodec::decodeObject(List<JsonValue::Field>::Reader input, DynamicStruct
decodeObject(object, output.init(*fieldSchema).as<DynamicStruct>()); decodeObject(object, output.init(*fieldSchema).as<DynamicStruct>());
}); });
} else { } else {
//Unknown json fields are ignored to allow schema evolution // Unknown json fields are ignored to allow schema evolution
} }
} }
} }
...@@ -553,7 +579,7 @@ void JsonCodec::decode(JsonValue::Reader input, DynamicStruct::Builder output) c ...@@ -553,7 +579,7 @@ void JsonCodec::decode(JsonValue::Reader input, DynamicStruct::Builder output) c
Orphan<DynamicValue> JsonCodec::decode( Orphan<DynamicValue> JsonCodec::decode(
JsonValue::Reader input, Type type, Orphanage orphanage) const { JsonValue::Reader input, Type type, Orphanage orphanage) const {
//TODO(soon) // TODO(soon)
KJ_FAIL_ASSERT("JSON decode into orphanage not implement yet. :("); KJ_FAIL_ASSERT("JSON decode into orphanage not implement yet. :(");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment