mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-29 02:07:32 +02:00
Add support for MsgPack extension
This commit is contained in:
@ -26,6 +26,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE("null" == variant.as<std::string>());
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(4.2)") {
|
||||
@ -38,6 +39,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<unsigned>() == 4U);
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(0.0)") {
|
||||
@ -47,6 +49,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<long>() == 0L);
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(false)") {
|
||||
@ -58,6 +61,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<std::string>() == "false");
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(true)") {
|
||||
@ -69,6 +73,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<std::string>() == "true");
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(42)") {
|
||||
@ -81,6 +86,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<std::string>() == "42");
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(42L)") {
|
||||
@ -205,6 +211,13 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
}
|
||||
|
||||
SECTION("set(serialized(\"hello\"))") {
|
||||
variant.set(serialized("hello"));
|
||||
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("to<JsonObject>()") {
|
||||
JsonObject obj = variant.to<JsonObject>();
|
||||
obj["key"] = "value";
|
||||
@ -262,10 +275,4 @@ TEST_CASE("JsonVariant::as()") {
|
||||
|
||||
REQUIRE(variant.as<MY_ENUM>() == ONE);
|
||||
}
|
||||
|
||||
SECTION("SerializedValue as MsgPackBinary") {
|
||||
variant.set(serialized("hello"));
|
||||
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ TEST_CASE("Unbound JsonVariant") {
|
||||
CHECK(variant.as<JsonString>().isNull());
|
||||
CHECK(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
CHECK(variant.as<MsgPackBinary>().size() == 0);
|
||||
CHECK(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
CHECK(variant.as<MsgPackExtension>().size() == 0);
|
||||
}
|
||||
|
||||
SECTION("is<T>()") {
|
||||
@ -49,6 +51,7 @@ TEST_CASE("Unbound JsonVariant") {
|
||||
CHECK_FALSE(variant.set(serialized(std::string("42"))));
|
||||
CHECK_FALSE(variant.set(true));
|
||||
CHECK_FALSE(variant.set(MsgPackBinary("hello", 5)));
|
||||
CHECK_FALSE(variant.set(MsgPackExtension(1, "hello", 5)));
|
||||
}
|
||||
|
||||
SECTION("add()") {
|
||||
|
@ -41,6 +41,24 @@ TEST_CASE("ARDUINOJSON_STRING_LENGTH_SIZE == 1") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("set(MsgPackExtension)") {
|
||||
SECTION("returns true if size <= 252") {
|
||||
auto str = std::string(252, '?');
|
||||
auto result = doc.set(MsgPackExtension(1, str.data(), str.size()));
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns false if size >= 253") {
|
||||
auto str = std::string(253, '?');
|
||||
auto result = doc.set(MsgPackExtension(1, str.data(), str.size()));
|
||||
|
||||
REQUIRE(result == false);
|
||||
REQUIRE(doc.overflowed() == true);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("deserializeJson()") {
|
||||
SECTION("returns Ok if string length <= 255") {
|
||||
auto input = "\"" + std::string(255, '?') + "\"";
|
||||
@ -91,5 +109,21 @@ TEST_CASE("ARDUINOJSON_STRING_LENGTH_SIZE == 1") {
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
|
||||
SECTION("returns Ok if extension size <= 252") {
|
||||
auto input = "\xc7\xfc\x01" + std::string(252, '?');
|
||||
|
||||
auto err = deserializeMsgPack(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("returns NoMemory if binary size >= 253") {
|
||||
auto input = "\xc7\xfd\x01" + std::string(253, '?');
|
||||
|
||||
auto err = deserializeMsgPack(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,24 @@ TEST_CASE("ARDUINOJSON_STRING_LENGTH_SIZE == 2") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("set(MsgPackExtension)") {
|
||||
SECTION("returns true if size <= 65531") {
|
||||
auto str = std::string(65531, '?');
|
||||
auto result = doc.set(MsgPackExtension(1, str.data(), str.size()));
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns false if size >= 65532") {
|
||||
auto str = std::string(65532, '?');
|
||||
auto result = doc.set(MsgPackExtension(1, str.data(), str.size()));
|
||||
|
||||
REQUIRE(result == false);
|
||||
REQUIRE(doc.overflowed() == true);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("deserializeJson()") {
|
||||
SECTION("returns Ok if string length <= 65535") {
|
||||
auto input = "\"" + std::string(65535, '?') + "\"";
|
||||
@ -92,5 +110,21 @@ TEST_CASE("ARDUINOJSON_STRING_LENGTH_SIZE == 2") {
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
|
||||
SECTION("returns Ok if extension size <= 65531") {
|
||||
auto input = "\xc8\xff\xfb\x01" + std::string(65531, '?');
|
||||
|
||||
auto err = deserializeMsgPack(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("returns NoMemory if binary size >= 65532") {
|
||||
auto input = "\xc8\xff\xfc\x01" + std::string(65532, '?');
|
||||
|
||||
auto err = deserializeMsgPack(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,16 @@ TEST_CASE("ARDUINOJSON_STRING_LENGTH_SIZE == 4") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("set(MsgPackExtension)") {
|
||||
SECTION("returns true if size >= 65532") {
|
||||
auto str = std::string(65532, '?');
|
||||
auto result = doc.set(MsgPackExtension(1, str.data(), str.size()));
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(doc.overflowed() == false);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("deserializeJson()") {
|
||||
SECTION("returns Ok if string length >= 65536") {
|
||||
auto input = "\"" + std::string(65536, '?') + "\"";
|
||||
@ -52,6 +62,14 @@ TEST_CASE("ARDUINOJSON_STRING_LENGTH_SIZE == 4") {
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("returns Ok if extension size >= 65532") {
|
||||
auto input = "\xc8\xff\xfb\x01" + std::string(65532, '?');
|
||||
|
||||
auto err = deserializeMsgPack(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("bin 32 deserialization") {
|
||||
@ -79,4 +97,31 @@ TEST_CASE("ARDUINOJSON_STRING_LENGTH_SIZE == 4") {
|
||||
REQUIRE(result == 5 + str.size());
|
||||
REQUIRE(output == std::string("\xc6\x00\x01\x00\x00", 5) + str);
|
||||
}
|
||||
|
||||
SECTION("ext 32 deserialization") {
|
||||
auto str = std::string(65536, '?');
|
||||
auto input = std::string("\xc9\x00\x01\x00\x00\x2a", 6) + str;
|
||||
|
||||
auto err = deserializeMsgPack(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto value = doc.as<MsgPackExtension>();
|
||||
REQUIRE(value.type() == 42);
|
||||
REQUIRE(value.size() == 65536);
|
||||
REQUIRE(value.data() != nullptr);
|
||||
REQUIRE(std::string(reinterpret_cast<const char*>(value.data()),
|
||||
value.size()) == str);
|
||||
}
|
||||
|
||||
SECTION("ext 32 serialization") {
|
||||
auto str = std::string(65536, '?');
|
||||
doc.set(MsgPackExtension(42, str.data(), str.size()));
|
||||
|
||||
std::string output;
|
||||
auto result = serializeMsgPack(doc, output);
|
||||
|
||||
REQUIRE(result == 6 + str.size());
|
||||
REQUIRE(output == std::string("\xc9\x00\x01\x00\x00\x2a", 6) + str);
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,6 @@ TEST_CASE("deserialize MsgPack value") {
|
||||
|
||||
SECTION("bin 16") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto str = std::string(256, '?');
|
||||
auto input = std::string("\xc5\x01\x00", 3) + str;
|
||||
|
||||
@ -169,6 +168,127 @@ TEST_CASE("deserialize MsgPack value") {
|
||||
REQUIRE(std::string(reinterpret_cast<const char*>(binary.data()),
|
||||
binary.size()) == str);
|
||||
}
|
||||
|
||||
SECTION("fixext 1") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto error = deserializeMsgPack(doc, "\xd4\x01\x02");
|
||||
|
||||
REQUIRE(error == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto ext = doc.as<MsgPackExtension>();
|
||||
REQUIRE(ext.type() == 1);
|
||||
REQUIRE(ext.size() == 1);
|
||||
auto data = reinterpret_cast<const uint8_t*>(ext.data());
|
||||
REQUIRE(data[0] == 2);
|
||||
}
|
||||
|
||||
SECTION("fixext 2") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto error = deserializeMsgPack(doc, "\xd5\x01\x02\x03");
|
||||
|
||||
REQUIRE(error == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto ext = doc.as<MsgPackExtension>();
|
||||
REQUIRE(ext.type() == 1);
|
||||
REQUIRE(ext.size() == 2);
|
||||
auto data = reinterpret_cast<const uint8_t*>(ext.data());
|
||||
REQUIRE(data[0] == 2);
|
||||
REQUIRE(data[1] == 3);
|
||||
}
|
||||
|
||||
SECTION("fixext 4") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto error = deserializeMsgPack(doc, "\xd6\x01\x02\x03\x04\x05");
|
||||
|
||||
REQUIRE(error == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto ext = doc.as<MsgPackExtension>();
|
||||
REQUIRE(ext.type() == 1);
|
||||
REQUIRE(ext.size() == 4);
|
||||
auto data = reinterpret_cast<const uint8_t*>(ext.data());
|
||||
REQUIRE(data[0] == 2);
|
||||
REQUIRE(data[1] == 3);
|
||||
REQUIRE(data[2] == 4);
|
||||
REQUIRE(data[3] == 5);
|
||||
}
|
||||
|
||||
SECTION("fixext 8") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto error = deserializeMsgPack(doc, "\xd7\x01????????");
|
||||
|
||||
REQUIRE(error == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto ext = doc.as<MsgPackExtension>();
|
||||
REQUIRE(ext.type() == 1);
|
||||
REQUIRE(ext.size() == 8);
|
||||
auto data = reinterpret_cast<const uint8_t*>(ext.data());
|
||||
REQUIRE(data[0] == '?');
|
||||
REQUIRE(data[7] == '?');
|
||||
}
|
||||
|
||||
SECTION("fixext 16") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto error = deserializeMsgPack(doc, "\xd8\x01?????????????????");
|
||||
|
||||
REQUIRE(error == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto ext = doc.as<MsgPackExtension>();
|
||||
REQUIRE(ext.type() == 1);
|
||||
REQUIRE(ext.size() == 16);
|
||||
auto data = reinterpret_cast<const uint8_t*>(ext.data());
|
||||
REQUIRE(data[0] == '?');
|
||||
REQUIRE(data[15] == '?');
|
||||
}
|
||||
|
||||
SECTION("ext 8") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto error = deserializeMsgPack(doc, "\xc7\x02\x01\x03\x04");
|
||||
|
||||
REQUIRE(error == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto ext = doc.as<MsgPackExtension>();
|
||||
REQUIRE(ext.type() == 1);
|
||||
REQUIRE(ext.size() == 2);
|
||||
auto data = reinterpret_cast<const uint8_t*>(ext.data());
|
||||
REQUIRE(data[0] == 3);
|
||||
REQUIRE(data[1] == 4);
|
||||
}
|
||||
|
||||
SECTION("ext 16") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto error = deserializeMsgPack(doc, "\xc8\x00\x02\x01\x03\x04");
|
||||
|
||||
REQUIRE(error == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto ext = doc.as<MsgPackExtension>();
|
||||
REQUIRE(ext.type() == 1);
|
||||
REQUIRE(ext.size() == 2);
|
||||
auto data = reinterpret_cast<const uint8_t*>(ext.data());
|
||||
REQUIRE(data[0] == 3);
|
||||
REQUIRE(data[1] == 4);
|
||||
}
|
||||
|
||||
SECTION("ext 32") {
|
||||
JsonDocument doc;
|
||||
|
||||
auto error = deserializeMsgPack(doc, "\xc9\x00\x00\x00\x02\x01\x03\x04");
|
||||
|
||||
REQUIRE(error == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<MsgPackExtension>());
|
||||
auto ext = doc.as<MsgPackExtension>();
|
||||
REQUIRE(ext.type() == 1);
|
||||
REQUIRE(ext.size() == 2);
|
||||
auto data = reinterpret_cast<const uint8_t*>(ext.data());
|
||||
REQUIRE(data[0] == 3);
|
||||
REQUIRE(data[1] == 4);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deserializeMsgPack() under memory constaints") {
|
||||
|
@ -184,53 +184,6 @@ TEST_CASE("deserializeMsgPack() returns IncompleteInput") {
|
||||
}
|
||||
}
|
||||
|
||||
static std::string msgPackToJson(const char* input, size_t inputSize) {
|
||||
JsonDocument doc;
|
||||
auto err = deserializeMsgPack(doc, input, inputSize);
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
return doc.as<std::string>();
|
||||
}
|
||||
|
||||
TEST_CASE("deserializeMsgPack() replaces ext types by null") {
|
||||
SECTION("ext 8") {
|
||||
REQUIRE(msgPackToJson("\x92\xc7\x01\x01\x01\x2A", 6) == "[null,42]");
|
||||
}
|
||||
|
||||
SECTION("ext 16") {
|
||||
REQUIRE(msgPackToJson("\x92\xc8\x00\x01\x01\x01\x2A", 7) == "[null,42]");
|
||||
}
|
||||
|
||||
SECTION("ext 32") {
|
||||
REQUIRE(msgPackToJson("\x92\xc9\x00\x00\x00\x01\x01\x01\x2A", 9) ==
|
||||
"[null,42]");
|
||||
}
|
||||
|
||||
SECTION("fixext 1") {
|
||||
REQUIRE(msgPackToJson("\x92\xd4\x01\x01\x2A", 5) == "[null,42]");
|
||||
}
|
||||
|
||||
SECTION("fixext 2") {
|
||||
REQUIRE(msgPackToJson("\x92\xd5\x01\x01\x02\x2A", 6) == "[null,42]");
|
||||
}
|
||||
|
||||
SECTION("fixext 4") {
|
||||
REQUIRE(msgPackToJson("\x92\xd6\x01\x01\x02\x03\x04\x2A", 8) ==
|
||||
"[null,42]");
|
||||
}
|
||||
|
||||
SECTION("fixext 8") {
|
||||
REQUIRE(msgPackToJson("\x92\xd7\x01\x01\x02\x03\x04\x05\x06\x07\x08\x2A",
|
||||
12) == "[null,42]");
|
||||
}
|
||||
|
||||
SECTION("fixext 16") {
|
||||
REQUIRE(msgPackToJson("\x92\xd8\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"
|
||||
"\x0B\x0C\x0D\x0E"
|
||||
"\x0F\x10\x2A",
|
||||
20) == "[null,42]");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"deserializeMsgPack() returns NoMemory when string allocation fails") {
|
||||
TimebombAllocator allocator(0);
|
||||
|
@ -147,16 +147,56 @@ TEST_CASE("serialize MsgPack value") {
|
||||
}
|
||||
|
||||
SECTION("bin 8") {
|
||||
auto str = std::string(1, 1);
|
||||
checkVariant(MsgPackBinary(str.data(), str.size()), "\xC4\x01\x01");
|
||||
checkVariant(MsgPackBinary("?", 1), "\xC4\x01?");
|
||||
}
|
||||
|
||||
SECTION("bin 16") {
|
||||
auto str = std::string(256, 1);
|
||||
auto str = std::string(256, '?');
|
||||
checkVariant(MsgPackBinary(str.data(), str.size()),
|
||||
std::string("\xC5\x01\x00", 3) + str);
|
||||
}
|
||||
|
||||
// bin 32 is tested in string_length_size_4.cpp
|
||||
|
||||
SECTION("fixext 1") {
|
||||
checkVariant(MsgPackExtension(1, "\x02", 1), "\xD4\x01\x02");
|
||||
}
|
||||
|
||||
SECTION("fixext 2") {
|
||||
checkVariant(MsgPackExtension(1, "\x03\x04", 2), "\xD5\x01\x03\x04");
|
||||
}
|
||||
|
||||
SECTION("fixext 4") {
|
||||
checkVariant(MsgPackExtension(1, "\x05\x06\x07\x08", 4),
|
||||
"\xD6\x01\x05\x06\x07\x08");
|
||||
}
|
||||
|
||||
SECTION("fixext 8") {
|
||||
checkVariant(MsgPackExtension(1, "????????", 8), "\xD7\x01????????");
|
||||
}
|
||||
|
||||
SECTION("fixext 16") {
|
||||
checkVariant(MsgPackExtension(1, "????????????????", 16),
|
||||
"\xD8\x01????????????????");
|
||||
}
|
||||
|
||||
SECTION("ext 8") {
|
||||
checkVariant(MsgPackExtension(2, "???", 3), "\xC7\x03\x02???");
|
||||
checkVariant(MsgPackExtension(2, "?????", 5), "\xC7\x05\x02?????");
|
||||
checkVariant(MsgPackExtension(2, "???????", 7), "\xC7\x07\x02???????");
|
||||
checkVariant(MsgPackExtension(2, "?????????", 9), "\xC7\x09\x02?????????");
|
||||
checkVariant(MsgPackExtension(2, "???????????????", 15),
|
||||
"\xC7\x0F\x02???????????????");
|
||||
checkVariant(MsgPackExtension(2, "?????????????????", 17),
|
||||
"\xC7\x11\x02?????????????????");
|
||||
}
|
||||
|
||||
SECTION("ext 16") {
|
||||
auto str = std::string(256, '?');
|
||||
checkVariant(MsgPackExtension(2, str.data(), str.size()),
|
||||
std::string("\xC8\x01\x00\x02", 4) + str);
|
||||
}
|
||||
|
||||
SECTION("serialize round double as integer") { // Issue #1718
|
||||
checkVariant(-32768.0, "\xD1\x80\x00");
|
||||
checkVariant(-129.0, "\xD1\xFF\x7F");
|
||||
|
Reference in New Issue
Block a user