Update libs

This commit is contained in:
iranl
2024-12-03 12:20:47 +01:00
parent 8a23eb3d03
commit a14074fd6d
62 changed files with 561 additions and 190 deletions

View File

@@ -1,6 +1,13 @@
ArduinoJson: change log ArduinoJson: change log
======================= =======================
v7.2.1 (2024-11-15)
------
* Forbid `deserializeJson(JsonArray|JsonObject, ...)` (issue #2135)
* Fix VLA support in `JsonDocument::set()`
* Fix `operator[](variant)` ignoring NUL characters
v7.2.0 (2024-09-18) v7.2.0 (2024-09-18)
------ ------

View File

@@ -10,7 +10,7 @@ if(ESP_PLATFORM)
return() return()
endif() endif()
project(ArduinoJson VERSION 7.2.0) project(ArduinoJson VERSION 7.2.1)
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest) include(CTest)

View File

@@ -1,4 +1,4 @@
version: 7.2.0.{build} version: 7.2.1.{build}
environment: environment:
matrix: matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022

View File

@@ -5,15 +5,18 @@
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(catch) link_libraries(ArduinoJson)
link_libraries(ArduinoJson catch) # Failing builds should only link with ArduinoJson, not catch
add_subdirectory(FailingBuilds)
add_subdirectory(catch)
link_libraries(catch)
include_directories(Helpers) include_directories(Helpers)
add_subdirectory(Cpp17) add_subdirectory(Cpp17)
add_subdirectory(Cpp20) add_subdirectory(Cpp20)
add_subdirectory(Deprecated) add_subdirectory(Deprecated)
add_subdirectory(FailingBuilds)
add_subdirectory(IntegrationTests) add_subdirectory(IntegrationTests)
add_subdirectory(JsonArray) add_subdirectory(JsonArray)
add_subdirectory(JsonArrayConst) add_subdirectory(JsonArrayConst)

View File

@@ -44,13 +44,25 @@ TEST_CASE("JsonDocument::containsKey()") {
REQUIRE(doc.containsKey("hello") == false); REQUIRE(doc.containsKey("hello") == false);
} }
SECTION("support JsonVariant") { SECTION("supports JsonVariant") {
doc["hello"] = "world"; doc["hello"] = "world";
doc["key"] = "hello"; doc["key"] = "hello";
REQUIRE(doc.containsKey(doc["key"]) == true); REQUIRE(doc.containsKey(doc["key"]) == true);
REQUIRE(doc.containsKey(doc["foo"]) == false); REQUIRE(doc.containsKey(doc["foo"]) == false);
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLAs") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
doc["hello"] = "world";
REQUIRE(doc.containsKey(vla) == true);
}
#endif
} }
TEST_CASE("MemberProxy::containsKey()") { TEST_CASE("MemberProxy::containsKey()") {
@@ -70,6 +82,18 @@ TEST_CASE("MemberProxy::containsKey()") {
REQUIRE(mp.containsKey("key"_s) == true); REQUIRE(mp.containsKey("key"_s) == true);
REQUIRE(mp.containsKey("key"_s) == true); REQUIRE(mp.containsKey("key"_s) == true);
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLAs") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
mp["hello"] = "world";
REQUIRE(mp.containsKey(vla) == true);
}
#endif
} }
TEST_CASE("JsonObject::containsKey()") { TEST_CASE("JsonObject::containsKey()") {
@@ -175,6 +199,18 @@ TEST_CASE("JsonVariant::containsKey()") {
REQUIRE(var.containsKey(doc["key"]) == true); REQUIRE(var.containsKey(doc["key"]) == true);
REQUIRE(var.containsKey(doc["foo"]) == false); REQUIRE(var.containsKey(doc["foo"]) == false);
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLAs") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
var["hello"] = "world";
REQUIRE(var.containsKey(vla) == true);
}
#endif
} }
TEST_CASE("JsonVariantConst::containsKey()") { TEST_CASE("JsonVariantConst::containsKey()") {

View File

@@ -2,7 +2,11 @@
# Copyright © 2014-2024, Benoit BLANCHON # Copyright © 2014-2024, Benoit BLANCHON
# MIT License # MIT License
macro(build_should_fail target) macro(add_failing_build source_file)
get_filename_component(target ${source_file} NAME_WE)
add_executable(${target} ${source_file})
set_target_properties(${target} set_target_properties(${target}
PROPERTIES PROPERTIES
EXCLUDE_FROM_ALL TRUE EXCLUDE_FROM_ALL TRUE
@@ -16,21 +20,13 @@ macro(build_should_fail target)
set_tests_properties(${target} set_tests_properties(${target}
PROPERTIES PROPERTIES
WILL_FAIL TRUE WILL_FAIL TRUE
LABELS "WillFail;Catch" LABELS "WillFail"
) )
endmacro() endmacro()
add_executable(Issue978 Issue978.cpp) add_failing_build(Issue978.cpp)
build_should_fail(Issue978) add_failing_build(read_long_long.cpp)
add_failing_build(write_long_long.cpp)
add_executable(read_long_long read_long_long.cpp) add_failing_build(variant_as_char.cpp)
build_should_fail(read_long_long) add_failing_build(assign_char.cpp)
add_failing_build(deserialize_object.cpp)
add_executable(write_long_long write_long_long.cpp)
build_should_fail(write_long_long)
add_executable(variant_as_char variant_as_char.cpp)
build_should_fail(variant_as_char)
add_executable(assign_char assign_char.cpp)
build_should_fail(assign_char)

View File

@@ -0,0 +1,12 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
// See issue #2135
int main() {
JsonObject obj;
deserializeJson(obj, "");
}

View File

@@ -16,6 +16,7 @@ add_executable(JsonDocumentTests
nesting.cpp nesting.cpp
overflowed.cpp overflowed.cpp
remove.cpp remove.cpp
set.cpp
shrinkToFit.cpp shrinkToFit.cpp
size.cpp size.cpp
subscript.cpp subscript.cpp

View File

@@ -7,7 +7,7 @@
#include "Literals.hpp" #include "Literals.hpp"
typedef ArduinoJson::detail::ElementProxy<JsonDocument&> ElementProxy; using ElementProxy = ArduinoJson::detail::ElementProxy<JsonDocument&>;
TEST_CASE("ElementProxy::add()") { TEST_CASE("ElementProxy::add()") {
JsonDocument doc; JsonDocument doc;
@@ -26,13 +26,25 @@ TEST_CASE("ElementProxy::add()") {
REQUIRE(doc.as<std::string>() == "[[\"world\"]]"); REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
} }
SECTION("set(char[])") { SECTION("add(char[])") {
char s[] = "world"; char s[] = "world";
ep.add(s); ep.add(s);
strcpy(s, "!!!!!"); strcpy(s, "!!!!!");
REQUIRE(doc.as<std::string>() == "[[\"world\"]]"); REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("set(vla)") {
size_t i = 8;
char vla[i];
strcpy(vla, "world");
ep.add(vla);
REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
}
#endif
} }
TEST_CASE("ElementProxy::clear()") { TEST_CASE("ElementProxy::clear()") {
@@ -166,6 +178,18 @@ TEST_CASE("ElementProxy::set()") {
REQUIRE(doc.as<std::string>() == "[\"world\"]"); REQUIRE(doc.as<std::string>() == "[\"world\"]");
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("set(VLA)") {
size_t i = 8;
char vla[i];
strcpy(vla, "world");
ep.set(vla);
REQUIRE(doc.as<std::string>() == "[\"world\"]");
}
#endif
} }
TEST_CASE("ElementProxy::size()") { TEST_CASE("ElementProxy::size()") {
@@ -205,6 +229,18 @@ TEST_CASE("ElementProxy::operator[]") {
REQUIRE(doc.as<std::string>() == "[null,[null,null,42]]"); REQUIRE(doc.as<std::string>() == "[null,[null,null,42]]");
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("set VLA") {
size_t i = 8;
char vla[i];
strcpy(vla, "world");
ep[0] = vla;
REQUIRE(doc.as<std::string>() == "[null,[\"world\"]]");
}
#endif
} }
TEST_CASE("ElementProxy cast to JsonVariantConst") { TEST_CASE("ElementProxy cast to JsonVariantConst") {

View File

@@ -14,8 +14,8 @@
using ArduinoJson::detail::sizeofArray; using ArduinoJson::detail::sizeofArray;
using ArduinoJson::detail::sizeofObject; using ArduinoJson::detail::sizeofObject;
typedef ArduinoJson::detail::MemberProxy<JsonDocument&, const char*> using MemberProxy =
MemberProxy; ArduinoJson::detail::MemberProxy<JsonDocument&, const char*>;
TEST_CASE("MemberProxy::add()") { TEST_CASE("MemberProxy::add()") {
JsonDocument doc; JsonDocument doc;
@@ -32,6 +32,18 @@ TEST_CASE("MemberProxy::add()") {
REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}"); REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}");
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("add(vla)") {
size_t i = 16;
char vla[i];
strcpy(vla, "world");
mp.add(vla);
REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}");
}
#endif
} }
TEST_CASE("MemberProxy::clear()") { TEST_CASE("MemberProxy::clear()") {
@@ -195,6 +207,18 @@ TEST_CASE("MemberProxy::set()") {
REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\"}"); REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\"}");
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("set(vla)") {
size_t i = 8;
char vla[i];
strcpy(vla, "world");
mp.set(vla);
REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\"}");
}
#endif
} }
TEST_CASE("MemberProxy::size()") { TEST_CASE("MemberProxy::size()") {

View File

@@ -79,6 +79,24 @@ TEST_CASE("JsonDocument::add(T)") {
Allocate(sizeofString("example")), Allocate(sizeofString("example")),
}); });
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "example");
doc.add(vla);
doc.add(vla);
CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
REQUIRE("example"_s == doc[0]);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("example")),
});
}
#endif
} }
TEST_CASE("JsonDocument::add<T>()") { TEST_CASE("JsonDocument::add<T>()") {

View File

@@ -0,0 +1,79 @@
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#define ARDUINOJSON_ENABLE_PROGMEM 1
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Allocators.hpp"
#include "Literals.hpp"
TEST_CASE("JsonDocument::set()") {
SpyingAllocator spy;
JsonDocument doc(&spy);
SECTION("integer") {
doc.set(42);
REQUIRE(doc.as<std::string>() == "42");
REQUIRE(spy.log() == AllocatorLog{});
}
SECTION("const char*") {
doc.set("example");
REQUIRE(doc.as<const char*>() == "example"_s);
REQUIRE(spy.log() == AllocatorLog{});
}
SECTION("std::string") {
doc.set("example"_s);
REQUIRE(doc.as<const char*>() == "example"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofString("example")),
});
}
SECTION("char*") {
char value[] = "example";
doc.set(value);
REQUIRE(doc.as<const char*>() == "example"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofString("example")),
});
}
SECTION("Arduino String") {
doc.set(String("example"));
REQUIRE(doc.as<const char*>() == "example"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofString("example")),
});
}
SECTION("Flash string") {
doc.set(F("example"));
REQUIRE(doc.as<const char*>() == "example"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofString("example")),
});
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "example");
doc.set(vla);
REQUIRE(doc.as<const char*>() == "example"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofString("example")),
});
}
#endif
}

View File

@@ -12,28 +12,55 @@ TEST_CASE("JsonDocument::operator[]") {
const JsonDocument& cdoc = doc; const JsonDocument& cdoc = doc;
SECTION("object") { SECTION("object") {
deserializeJson(doc, "{\"hello\":\"world\"}"); doc["abc"_s] = "ABC";
doc["abc\0d"_s] = "ABCD";
SECTION("const char*") { SECTION("const char*") {
REQUIRE(doc["hello"] == "world"); REQUIRE(doc["abc"] == "ABC");
REQUIRE(cdoc["hello"] == "world"); REQUIRE(cdoc["abc"] == "ABC");
} }
SECTION("std::string") { SECTION("std::string") {
REQUIRE(doc["hello"_s] == "world"); REQUIRE(doc["abc"_s] == "ABC");
REQUIRE(cdoc["hello"_s] == "world"); REQUIRE(cdoc["abc"_s] == "ABC");
REQUIRE(doc["abc\0d"_s] == "ABCD");
REQUIRE(cdoc["abc\0d"_s] == "ABCD");
} }
SECTION("JsonVariant") { SECTION("JsonVariant") {
doc["key"] = "hello"; doc["key1"] = "abc";
REQUIRE(doc[doc["key"]] == "world"); doc["key2"] = "abc\0d"_s;
REQUIRE(cdoc[cdoc["key"]] == "world"); doc["key3"] = "foo";
CHECK(doc[doc["key1"]] == "ABC");
CHECK(doc[doc["key2"]] == "ABCD");
CHECK(doc[doc["key3"]] == nullptr);
CHECK(doc[doc["key4"]] == nullptr);
CHECK(cdoc[cdoc["key1"]] == "ABC");
CHECK(cdoc[cdoc["key2"]] == "ABCD");
CHECK(cdoc[cdoc["key3"]] == nullptr);
CHECK(cdoc[cdoc["key4"]] == nullptr);
} }
SECTION("supports operator|") { SECTION("supports operator|") {
REQUIRE((doc["hello"] | "nope") == "world"_s); REQUIRE((doc["abc"] | "nope") == "ABC"_s);
REQUIRE((doc["world"] | "nope") == "nope"_s); REQUIRE((doc["def"] | "nope") == "nope"_s);
} }
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
!defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
SECTION("supports VLAs") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
doc[vla] = "world";
REQUIRE(doc[vla] == "world");
REQUIRE(cdoc[vla] == "world");
}
#endif
} }
SECTION("array") { SECTION("array") {

View File

@@ -253,9 +253,15 @@ TEST_CASE("JsonObject::operator[]") {
SECTION("JsonVariant") { SECTION("JsonVariant") {
obj["hello"] = "world"; obj["hello"] = "world";
doc["key"] = "hello"; obj["a\0b"_s] = "ABC";
REQUIRE(obj[obj["key"]] == "world"); doc["key1"] = "hello";
REQUIRE(obj[obj["foo"]] == nullptr); doc["key2"] = "a\0b"_s;
doc["key3"] = "foo";
REQUIRE(obj[obj["key1"]] == "world");
REQUIRE(obj[obj["key2"]] == "ABC");
REQUIRE(obj[obj["key3"]] == nullptr);
REQUIRE(obj[obj["key4"]] == nullptr);
} }
} }

View File

@@ -11,6 +11,7 @@
TEST_CASE("JsonObjectConst::operator[]") { TEST_CASE("JsonObjectConst::operator[]") {
JsonDocument doc; JsonDocument doc;
doc["hello"] = "world"; doc["hello"] = "world";
doc["a\0b"_s] = "ABC";
JsonObjectConst obj = doc.as<JsonObjectConst>(); JsonObjectConst obj = doc.as<JsonObjectConst>();
SECTION("supports const char*") { SECTION("supports const char*") {
@@ -19,6 +20,7 @@ TEST_CASE("JsonObjectConst::operator[]") {
SECTION("supports std::string") { SECTION("supports std::string") {
REQUIRE(obj["hello"_s] == "world"); // issue #2019 REQUIRE(obj["hello"_s] == "world"); // issue #2019
REQUIRE(obj["a\0b"_s] == "ABC");
} }
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \ #if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
@@ -28,13 +30,17 @@ TEST_CASE("JsonObjectConst::operator[]") {
char vla[i]; char vla[i];
strcpy(vla, "hello"); strcpy(vla, "hello");
REQUIRE("world"_s == obj[vla]); REQUIRE(obj[vla] == "world"_s);
} }
#endif #endif
SECTION("supports JsonVariant") { SECTION("supports JsonVariant") {
doc["key"] = "hello"; doc["key1"] = "hello";
REQUIRE(obj[obj["key"]] == "world"); doc["key2"] = "a\0b"_s;
REQUIRE(obj[obj["foo"]] == nullptr); doc["key3"] = "foo";
REQUIRE(obj[obj["key1"]] == "world");
REQUIRE(obj[obj["key2"]] == "ABC");
REQUIRE(obj[obj["key3"]] == nullptr);
REQUIRE(obj[obj["key4"]] == nullptr);
} }
} }

View File

@@ -46,6 +46,18 @@ TEST_CASE("JsonVariant::add(T)") {
REQUIRE(var.as<std::string>() == "{\"val\":123}"); REQUIRE(var.as<std::string>() == "{\"val\":123}");
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLAs") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
var.add(vla);
REQUIRE(var.as<std::string>() == "[\"hello\"]");
}
#endif
} }
TEST_CASE("JsonVariant::add<T>()") { TEST_CASE("JsonVariant::add<T>()") {

View File

@@ -83,6 +83,23 @@ TEST_CASE("JsonVariant::remove(std::string)") {
REQUIRE(var.as<std::string>() == "{\"a\":1}"); REQUIRE(var.as<std::string>() == "{\"a\":1}");
} }
#ifdef HAS_VARIABLE_LENGTH_ARRAY
TEST_CASE("JsonVariant::remove(VLA)") {
JsonDocument doc;
JsonVariant var = doc.to<JsonVariant>();
var["a"] = 1;
var["b"] = 2;
size_t i = 16;
char vla[i];
strcpy(vla, "b");
var.remove("b"_s);
REQUIRE(var.as<std::string>() == "{\"a\":1}");
}
#endif
TEST_CASE("JsonVariant::remove(JsonVariant) from object") { TEST_CASE("JsonVariant::remove(JsonVariant) from object") {
JsonDocument doc; JsonDocument doc;
JsonVariant var = doc.to<JsonVariant>(); JsonVariant var = doc.to<JsonVariant>();

View File

@@ -99,7 +99,7 @@ TEST_CASE("vector<int>") {
} }
TEST_CASE("array<int, 2>") { TEST_CASE("array<int, 2>") {
typedef std::array<int, 2> array_type; using array_type = std::array<int, 2>;
SECTION("toJson") { SECTION("toJson") {
array_type v; array_type v;

View File

@@ -116,12 +116,19 @@ TEST_CASE("JsonVariant::operator[]") {
} }
SECTION("use JsonVariant as key") { SECTION("use JsonVariant as key") {
object["a"] = "a"; object["a"] = "A";
object["b"] = "b"; object["ab"] = "AB";
object["c"] = "b"; object["ab\0c"_s] = "ABC";
object["key1"] = "a";
object["key2"] = "ab";
object["key3"] = "ab\0c"_s;
object["key4"] = "foo";
REQUIRE(var[var["c"]] == "b"); REQUIRE(var[var["key1"]] == "A");
REQUIRE(var[var["d"]].isNull()); REQUIRE(var[var["key2"]] == "AB");
REQUIRE(var[var["key3"]] == "ABC");
REQUIRE(var[var["key4"]].isNull());
REQUIRE(var[var["key5"]].isNull());
} }
} }

View File

@@ -50,20 +50,22 @@ TEST_CASE("JsonVariantConst::operator[]") {
SECTION("object") { SECTION("object") {
JsonObject object = doc.to<JsonObject>(); JsonObject object = doc.to<JsonObject>();
object["a"] = "A"; object["ab"_s] = "AB";
object["b"] = "B"; object["abc"_s] = "ABC";
object["abc\0d"_s] = "ABCD";
SECTION("supports const char*") { SECTION("supports const char*") {
REQUIRE("A"_s == var["a"]); REQUIRE(var["ab"] == "AB"_s);
REQUIRE("B"_s == var["b"]); REQUIRE(var["abc"] == "ABC"_s);
REQUIRE(var["c"].isNull()); REQUIRE(var["def"].isNull());
REQUIRE(var[0].isNull()); REQUIRE(var[0].isNull());
} }
SECTION("supports std::string") { SECTION("supports std::string") {
REQUIRE("A"_s == var["a"_s]); REQUIRE(var["ab"_s] == "AB"_s);
REQUIRE("B"_s == var["b"_s]); REQUIRE(var["abc"_s] == "ABC"_s);
REQUIRE(var["c"_s].isNull()); REQUIRE(var["abc\0d"_s] == "ABCD"_s);
REQUIRE(var["def"_s].isNull());
} }
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \ #if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
@@ -71,16 +73,23 @@ TEST_CASE("JsonVariantConst::operator[]") {
SECTION("supports VLA") { SECTION("supports VLA") {
size_t i = 16; size_t i = 16;
char vla[i]; char vla[i];
strcpy(vla, "a"); strcpy(vla, "abc");
REQUIRE("A"_s == var[vla]); REQUIRE(var[vla] == "ABC"_s);
} }
#endif #endif
SECTION("supports JsonVariant") { SECTION("supports JsonVariant") {
object["c"] = "b"; object["key1"] = "ab";
REQUIRE(var[var["c"]] == "B"); object["key2"] = "abc";
REQUIRE(var[var["d"]].isNull()); object["key3"] = "abc\0d"_s;
object["key4"] = "foo";
REQUIRE(var[var["key1"]] == "AB"_s);
REQUIRE(var[var["key2"]] == "ABC"_s);
REQUIRE(var[var["key3"]] == "ABCD"_s);
REQUIRE(var[var["key4"]].isNull());
REQUIRE(var[var["key5"]].isNull());
} }
} }
} }

View File

@@ -6,6 +6,7 @@ add_executable(MiscTests
arithmeticCompare.cpp arithmeticCompare.cpp
conflicts.cpp conflicts.cpp
issue1967.cpp issue1967.cpp
issue2129.cpp
JsonString.cpp JsonString.cpp
NoArduinoHeader.cpp NoArduinoHeader.cpp
printable.cpp printable.cpp

View File

@@ -12,77 +12,101 @@
#include "custom_string.hpp" #include "custom_string.hpp"
#include "weird_strcmp.hpp" #include "weird_strcmp.hpp"
using ArduinoJson::JsonString;
using namespace ArduinoJson::detail; using namespace ArduinoJson::detail;
TEST_CASE("ZeroTerminatedRamString") { TEST_CASE("adaptString()") {
SECTION("null") { SECTION("null const char*") {
ZeroTerminatedRamString s = adaptString(static_cast<const char*>(0)); auto s = adaptString(static_cast<const char*>(0));
CHECK(s.isNull() == true); CHECK(s.isNull() == true);
CHECK(s.size() == 0); CHECK(s.size() == 0);
CHECK(s.isLinked() == true);
} }
SECTION("non-null") { SECTION("non-null const char*") {
ZeroTerminatedRamString s = adaptString("bravo"); auto s = adaptString("bravo");
CHECK(s.isNull() == false); CHECK(s.isNull() == false);
CHECK(s.size() == 5); CHECK(s.size() == 5);
CHECK(s.isLinked() == true);
} }
}
TEST_CASE("SizedRamString") { SECTION("null const char* + size") {
SECTION("null") { auto s = adaptString(static_cast<const char*>(0), 10);
SizedRamString s = adaptString(static_cast<const char*>(0), 10);
CHECK(s.isNull() == true); CHECK(s.isNull() == true);
CHECK(s.isLinked() == false);
} }
SECTION("non-null") { SECTION("non-null const char* + size") {
SizedRamString s = adaptString("bravo", 5); auto s = adaptString("bravo", 5);
CHECK(s.isNull() == false); CHECK(s.isNull() == false);
CHECK(s.size() == 5); CHECK(s.size() == 5);
CHECK(s.isLinked() == false);
} }
}
TEST_CASE("FlashString") { SECTION("null Flash string") {
SECTION("null") { auto s = adaptString(static_cast<const __FlashStringHelper*>(0));
FlashString s = adaptString(static_cast<const __FlashStringHelper*>(0));
CHECK(s.isNull() == true); CHECK(s.isNull() == true);
CHECK(s.size() == 0); CHECK(s.size() == 0);
CHECK(s.isLinked() == false);
} }
SECTION("non-null") { SECTION("non-null Flash string") {
FlashString s = adaptString(F("bravo")); auto s = adaptString(F("bravo"));
CHECK(s.isNull() == false); CHECK(s.isNull() == false);
CHECK(s.size() == 5); CHECK(s.size() == 5);
CHECK(s.isLinked() == false);
} }
}
TEST_CASE("std::string") { SECTION("std::string") {
std::string orig("bravo"); std::string orig("bravo");
SizedRamString s = adaptString(orig); auto s = adaptString(orig);
CHECK(s.isNull() == false); CHECK(s.isNull() == false);
CHECK(s.size() == 5); CHECK(s.size() == 5);
} CHECK(s.isLinked() == false);
}
TEST_CASE("Arduino String") { SECTION("Arduino String") {
::String orig("bravo"); ::String orig("bravo");
SizedRamString s = adaptString(orig); auto s = adaptString(orig);
CHECK(s.isNull() == false); CHECK(s.isNull() == false);
CHECK(s.size() == 5); CHECK(s.size() == 5);
} CHECK(s.isLinked() == false);
}
TEST_CASE("custom_string") { SECTION("custom_string") {
custom_string orig("bravo"); custom_string orig("bravo");
SizedRamString s = adaptString(orig); auto s = adaptString(orig);
CHECK(s.isNull() == false); CHECK(s.isNull() == false);
CHECK(s.size() == 5); CHECK(s.size() == 5);
CHECK(s.isLinked() == false);
}
SECTION("JsonString linked") {
JsonString orig("hello", JsonString::Ownership::Linked);
auto s = adaptString(orig);
CHECK(s.isNull() == false);
CHECK(s.size() == 5);
CHECK(s.isLinked() == true);
}
SECTION("JsonString copied") {
JsonString orig("hello", JsonString::Ownership::Copied);
auto s = adaptString(orig);
CHECK(s.isNull() == false);
CHECK(s.size() == 5);
CHECK(s.isLinked() == false);
}
} }
struct EmptyStruct {}; struct EmptyStruct {};
@@ -97,6 +121,7 @@ TEST_CASE("IsString<T>") {
CHECK(IsString<::String>::value == true); CHECK(IsString<::String>::value == true);
CHECK(IsString<::StringSumHelper>::value == true); CHECK(IsString<::StringSumHelper>::value == true);
CHECK(IsString<const EmptyStruct*>::value == false); CHECK(IsString<const EmptyStruct*>::value == false);
CHECK(IsString<JsonString>::value == true);
} }
TEST_CASE("stringCompare") { TEST_CASE("stringCompare") {

View File

@@ -8,4 +8,4 @@
struct custom_char_traits : std::char_traits<char> {}; struct custom_char_traits : std::char_traits<char> {};
typedef std::basic_string<char, custom_char_traits> custom_string; using custom_string = std::basic_string<char, custom_char_traits>;

View File

@@ -0,0 +1,55 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
template <typename T>
class Nullable {
public:
Nullable() : value_{} {}
Nullable(T value) : value_{value} {}
operator T() const {
return value_;
}
operator T&() {
return value_;
}
bool is_valid() const {
return value_ != invalid_value_;
}
T value() const {
return value_;
}
private:
T value_;
static T invalid_value_;
};
template <>
float Nullable<float>::invalid_value_ = std::numeric_limits<float>::lowest();
template <typename T>
void convertToJson(const Nullable<T>& src, JsonVariant dst) {
if (src.is_valid()) {
dst.set(src.value());
} else {
dst.clear();
}
}
TEST_CASE("Issue #2129") {
Nullable<float> nullable_value = Nullable<float>{123.4f};
JsonDocument doc;
doc["value"] = nullable_value;
REQUIRE(doc["value"].as<float>() == Approx(123.4f));
}

View File

@@ -1,7 +1,7 @@
version: "7.2.0" version: "7.2.1"
description: >- description: >-
A simple and efficient JSON library for embedded C++. A simple and efficient JSON library for embedded C++.
6690 stars on GitHub! 6739 stars on GitHub!
Supports serialization, deserialization, MessagePack, streams, filtering, and more. Supports serialization, deserialization, MessagePack, streams, filtering, and more.
Fully tested and documented. Fully tested and documented.
url: https://arduinojson.org/ url: https://arduinojson.org/

View File

@@ -1,13 +1,13 @@
{ {
"name": "ArduinoJson", "name": "ArduinoJson",
"keywords": "json, rest, http, web", "keywords": "json, rest, http, web",
"description": "A simple and efficient JSON library for embedded C++. ⭐ 6690 stars on GitHub! Supports serialization, deserialization, MessagePack, streams, filtering, and more. Fully tested and documented.", "description": "A simple and efficient JSON library for embedded C++. ⭐ 6739 stars on GitHub! Supports serialization, deserialization, MessagePack, streams, filtering, and more. Fully tested and documented.",
"homepage": "https://arduinojson.org/?utm_source=meta&utm_medium=library.json", "homepage": "https://arduinojson.org/?utm_source=meta&utm_medium=library.json",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git" "url": "https://github.com/bblanchon/ArduinoJson.git"
}, },
"version": "7.2.0", "version": "7.2.1",
"authors": { "authors": {
"name": "Benoit Blanchon", "name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr" "url": "https://blog.benoitblanchon.fr"

View File

@@ -1,9 +1,9 @@
name=ArduinoJson name=ArduinoJson
version=7.2.0 version=7.2.1
author=Benoit Blanchon <blog.benoitblanchon.fr> author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr> maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=A simple and efficient JSON library for embedded C++. sentence=A simple and efficient JSON library for embedded C++.
paragraph=⭐ 6690 stars on GitHub! Supports serialization, deserialization, MessagePack, streams, filtering, and more. Fully tested and documented. paragraph=⭐ 6739 stars on GitHub! Supports serialization, deserialization, MessagePack, streams, filtering, and more. Fully tested and documented.
category=Data Processing category=Data Processing
url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties
architectures=* architectures=*

View File

@@ -17,7 +17,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
friend class detail::VariantAttorney; friend class detail::VariantAttorney;
public: public:
typedef JsonArrayIterator iterator; using iterator = JsonArrayIterator;
// Constructs an unbound reference. // Constructs an unbound reference.
JsonArray() : data_(0), resources_(0) {} JsonArray() : data_(0), resources_(0) {}

View File

@@ -19,7 +19,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
friend class detail::VariantAttorney; friend class detail::VariantAttorney;
public: public:
typedef JsonArrayConstIterator iterator; using iterator = JsonArrayConstIterator;
// Returns an iterator to the first element of the array. // Returns an iterator to the first element of the array.
// https://arduinojson.org/v7/api/jsonarrayconst/begin/ // https://arduinojson.org/v7/api/jsonarrayconst/begin/

View File

@@ -24,14 +24,10 @@ struct first_or_void<T, Rest...> {
// A meta-function that returns true if T is a valid destination type for // A meta-function that returns true if T is a valid destination type for
// deserialize() // deserialize()
template <class T, class = void>
struct is_deserialize_destination : false_type {};
template <class T> template <class T>
struct is_deserialize_destination< using is_deserialize_destination =
T, enable_if_t<is_same<decltype(VariantAttorney::getResourceManager( bool_constant<is_base_of<JsonDocument, remove_cv_t<T>>::value ||
detail::declval<T&>())), IsVariant<T>::value>;
ResourceManager*>::value>> : true_type {};
template <typename TDestination> template <typename TDestination>
inline void shrinkJsonDocument(TDestination&) { inline void shrinkJsonDocument(TDestination&) {

View File

@@ -142,6 +142,13 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
return to<JsonVariant>().set(src); return to<JsonVariant>().set(src);
} }
// Replaces the root with the specified value.
// https://arduinojson.org/v7/api/jsondocument/set/
template <typename TChar>
bool set(TChar* src) {
return to<JsonVariant>().set(src);
}
// Clears the document and converts it to the specified type. // Clears the document and converts it to the specified type.
// https://arduinojson.org/v7/api/jsondocument/to/ // https://arduinojson.org/v7/api/jsondocument/to/
template <typename T> template <typename T>
@@ -232,8 +239,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename TVariant> template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst> detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<JsonString>())
return operator[](key.template as<const char*>()); return operator[](key.template as<JsonString>());
if (key.template is<size_t>()) if (key.template is<size_t>())
return operator[](key.template as<size_t>()); return operator[](key.template as<size_t>());
return {}; return {};

View File

@@ -13,7 +13,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TWriter> template <typename TWriter>
class PrettyJsonSerializer : public JsonSerializer<TWriter> { class PrettyJsonSerializer : public JsonSerializer<TWriter> {
typedef JsonSerializer<TWriter> base; using base = JsonSerializer<TWriter>;
public: public:
PrettyJsonSerializer(TWriter writer, const ResourceManager* resources) PrettyJsonSerializer(TWriter writer, const ResourceManager* resources)

View File

@@ -105,7 +105,7 @@ class TextFormatter {
template <typename T> template <typename T>
enable_if_t<is_signed<T>::value> writeInteger(T value) { enable_if_t<is_signed<T>::value> writeInteger(T value) {
typedef make_unsigned_t<T> unsigned_type; using unsigned_type = make_unsigned_t<T>;
unsigned_type unsigned_value; unsigned_type unsigned_value;
if (value < 0) { if (value < 0) {
writeRaw('-'); writeRaw('-');

View File

@@ -20,7 +20,7 @@ struct FloatParts {
template <typename TFloat> template <typename TFloat>
inline int16_t normalize(TFloat& value) { inline int16_t normalize(TFloat& value) {
typedef FloatTraits<TFloat> traits; using traits = FloatTraits<TFloat>;
int16_t powersOf10 = 0; int16_t powersOf10 = 0;
int8_t index = sizeof(TFloat) == 8 ? 8 : 5; int8_t index = sizeof(TFloat) == 8 ? 8 : 5;

View File

@@ -21,12 +21,12 @@ struct FloatTraits {};
template <typename T> template <typename T>
struct FloatTraits<T, 8 /*64bits*/> { struct FloatTraits<T, 8 /*64bits*/> {
typedef uint64_t mantissa_type; using mantissa_type = uint64_t;
static const short mantissa_bits = 52; static const short mantissa_bits = 52;
static const mantissa_type mantissa_max = static const mantissa_type mantissa_max =
(mantissa_type(1) << mantissa_bits) - 1; (mantissa_type(1) << mantissa_bits) - 1;
typedef int16_t exponent_type; using exponent_type = int16_t;
static const exponent_type exponent_max = 308; static const exponent_type exponent_max = 308;
static pgm_ptr<T> positiveBinaryPowersOfTen() { static pgm_ptr<T> positiveBinaryPowersOfTen() {
@@ -105,12 +105,12 @@ struct FloatTraits<T, 8 /*64bits*/> {
template <typename T> template <typename T>
struct FloatTraits<T, 4 /*32bits*/> { struct FloatTraits<T, 4 /*32bits*/> {
typedef uint32_t mantissa_type; using mantissa_type = uint32_t;
static const short mantissa_bits = 23; static const short mantissa_bits = 23;
static const mantissa_type mantissa_max = static const mantissa_type mantissa_max =
(mantissa_type(1) << mantissa_bits) - 1; (mantissa_type(1) << mantissa_bits) - 1;
typedef int8_t exponent_type; using exponent_type = int8_t;
static const exponent_type exponent_max = 38; static const exponent_type exponent_max = 38;
static pgm_ptr<T> positiveBinaryPowersOfTen() { static pgm_ptr<T> positiveBinaryPowersOfTen() {

View File

@@ -10,9 +10,9 @@
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
#if ARDUINOJSON_USE_DOUBLE #if ARDUINOJSON_USE_DOUBLE
typedef double JsonFloat; using JsonFloat = double;
#else #else
typedef float JsonFloat; using JsonFloat = float;
#endif #endif
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

View File

@@ -12,11 +12,11 @@
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
#if ARDUINOJSON_USE_LONG_LONG #if ARDUINOJSON_USE_LONG_LONG
typedef int64_t JsonInteger; using JsonInteger = int64_t;
typedef uint64_t JsonUInt; using JsonUInt = uint64_t;
#else #else
typedef long JsonInteger; using JsonInteger = long;
typedef unsigned long JsonUInt; using JsonUInt = unsigned long;
#endif #endif
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

View File

@@ -103,9 +103,9 @@ class Number {
}; };
inline Number parseNumber(const char* s) { inline Number parseNumber(const char* s) {
typedef FloatTraits<JsonFloat> traits; using traits = FloatTraits<JsonFloat>;
typedef largest_type<traits::mantissa_type, JsonUInt> mantissa_t; using mantissa_t = largest_type<traits::mantissa_type, JsonUInt>;
typedef traits::exponent_type exponent_t; using exponent_t = traits::exponent_type;
ARDUINOJSON_ASSERT(s != 0); ARDUINOJSON_ASSERT(s != 0);

View File

@@ -17,7 +17,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
friend class detail::VariantAttorney; friend class detail::VariantAttorney;
public: public:
typedef JsonObjectIterator iterator; using iterator = JsonObjectIterator;
// Creates an unbound reference. // Creates an unbound reference.
JsonObject() : data_(0), resources_(0) {} JsonObject() : data_(0), resources_(0) {}
@@ -121,10 +121,10 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// https://arduinojson.org/v7/api/jsonobject/subscript/ // https://arduinojson.org/v7/api/jsonobject/subscript/
template <typename TVariant> template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value, detail::enable_if_t<detail::IsVariant<TVariant>::value,
detail::MemberProxy<JsonObject, const char*>> detail::MemberProxy<JsonObject, JsonString>>
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<JsonString>())
return {*this, key.template as<const char*>()}; return {*this, key.template as<JsonString>()};
else else
return {*this, nullptr}; return {*this, nullptr};
} }

View File

@@ -16,7 +16,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
friend class detail::VariantAttorney; friend class detail::VariantAttorney;
public: public:
typedef JsonObjectConstIterator iterator; using iterator = JsonObjectConstIterator;
// Creates an unbound reference. // Creates an unbound reference.
JsonObjectConst() : data_(0), resources_(0) {} JsonObjectConst() : data_(0), resources_(0) {}
@@ -121,8 +121,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
template <typename TVariant> template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst> detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<JsonString>())
return operator[](key.template as<const char*>()); return operator[](key.template as<JsonString>());
else else
return JsonVariantConst(); return JsonVariantConst();
} }

View File

@@ -15,17 +15,17 @@ struct uint_;
template <> template <>
struct uint_<8> { struct uint_<8> {
typedef uint8_t type; using type = uint8_t;
}; };
template <> template <>
struct uint_<16> { struct uint_<16> {
typedef uint16_t type; using type = uint16_t;
}; };
template <> template <>
struct uint_<32> { struct uint_<32> {
typedef uint32_t type; using type = uint32_t;
}; };
template <int Bits> template <int Bits>

View File

@@ -10,12 +10,12 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <bool Condition, class TrueType, class FalseType> template <bool Condition, class TrueType, class FalseType>
struct conditional { struct conditional {
typedef TrueType type; using type = TrueType;
}; };
template <class TrueType, class FalseType> template <class TrueType, class FalseType>
struct conditional<false, TrueType, FalseType> { struct conditional<false, TrueType, FalseType> {
typedef FalseType type; using type = FalseType;
}; };
template <bool Condition, class TrueType, class FalseType> template <bool Condition, class TrueType, class FalseType>

View File

@@ -14,7 +14,7 @@ struct enable_if {};
template <typename T> template <typename T>
struct enable_if<true, T> { struct enable_if<true, T> {
typedef T type; using type = T;
}; };
template <bool Condition, typename T = void> template <bool Condition, typename T = void>

View File

@@ -13,7 +13,10 @@ struct integral_constant {
static const T value = v; static const T value = v;
}; };
typedef integral_constant<bool, true> true_type; template <bool B>
typedef integral_constant<bool, false> false_type; using bool_constant = integral_constant<bool, B>;
using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -27,7 +27,7 @@ struct is_convertible {
static int probe(To); static int probe(To);
static char probe(...); static char probe(...);
static From& from_; static const From& from_;
public: public:
static const bool value = sizeof(probe(from_)) == sizeof(int); static const bool value = sizeof(probe(from_)) == sizeof(int);

View File

@@ -11,11 +11,11 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// A meta-function that return the type T without the const modifier // A meta-function that return the type T without the const modifier
template <typename T> template <typename T>
struct remove_const { struct remove_const {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_const<const T> { struct remove_const<const T> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>

View File

@@ -10,19 +10,19 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename T> template <typename T>
struct remove_cv { struct remove_cv {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_cv<const T> { struct remove_cv<const T> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_cv<volatile T> { struct remove_cv<volatile T> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_cv<const volatile T> { struct remove_cv<const volatile T> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>

View File

@@ -11,11 +11,11 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// A meta-function that return the type T without the reference modifier. // A meta-function that return the type T without the reference modifier.
template <typename T> template <typename T>
struct remove_reference { struct remove_reference {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_reference<T&> { struct remove_reference<T&> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>

View File

@@ -10,7 +10,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename T> template <typename T>
struct type_identity { struct type_identity {
typedef T type; using type = T;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -74,7 +74,7 @@ class FlashString {
template <> template <>
struct StringAdapter<const __FlashStringHelper*, void> { struct StringAdapter<const __FlashStringHelper*, void> {
typedef FlashString AdaptedString; using AdaptedString = FlashString;
static AdaptedString adapt(const __FlashStringHelper* s) { static AdaptedString adapt(const __FlashStringHelper* s) {
return AdaptedString(s, s ? strlen_P(reinterpret_cast<const char*>(s)) : 0); return AdaptedString(s, s ? strlen_P(reinterpret_cast<const char*>(s)) : 0);
@@ -83,7 +83,7 @@ struct StringAdapter<const __FlashStringHelper*, void> {
template <> template <>
struct SizedStringAdapter<const __FlashStringHelper*, void> { struct SizedStringAdapter<const __FlashStringHelper*, void> {
typedef FlashString AdaptedString; using AdaptedString = FlashString;
static AdaptedString adapt(const __FlashStringHelper* s, size_t n) { static AdaptedString adapt(const __FlashStringHelper* s, size_t n) {
return AdaptedString(s, n); return AdaptedString(s, n);

View File

@@ -25,7 +25,7 @@ class JsonStringAdapter : public SizedRamString {
template <> template <>
struct StringAdapter<JsonString> { struct StringAdapter<JsonString> {
typedef JsonStringAdapter AdaptedString; using AdaptedString = JsonStringAdapter;
static AdaptedString adapt(const JsonString& s) { static AdaptedString adapt(const JsonString& s) {
return AdaptedString(s); return AdaptedString(s);

View File

@@ -41,18 +41,6 @@ class ZeroTerminatedRamString {
return str_; return str_;
} }
friend int stringCompare(ZeroTerminatedRamString a,
ZeroTerminatedRamString b) {
ARDUINOJSON_ASSERT(!a.isNull());
ARDUINOJSON_ASSERT(!b.isNull());
return ::strcmp(a.str_, b.str_);
}
friend bool stringEquals(ZeroTerminatedRamString a,
ZeroTerminatedRamString b) {
return stringCompare(a, b) == 0;
}
bool isLinked() const { bool isLinked() const {
return false; return false;
} }
@@ -63,7 +51,7 @@ class ZeroTerminatedRamString {
template <typename TChar> template <typename TChar>
struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> { struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
typedef ZeroTerminatedRamString AdaptedString; using AdaptedString = ZeroTerminatedRamString;
static AdaptedString adapt(const TChar* p) { static AdaptedString adapt(const TChar* p) {
return AdaptedString(reinterpret_cast<const char*>(p)); return AdaptedString(reinterpret_cast<const char*>(p));
@@ -72,7 +60,7 @@ struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
template <typename TChar, size_t N> template <typename TChar, size_t N>
struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> { struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> {
typedef ZeroTerminatedRamString AdaptedString; using AdaptedString = ZeroTerminatedRamString;
static AdaptedString adapt(const TChar* p) { static AdaptedString adapt(const TChar* p) {
return AdaptedString(reinterpret_cast<const char*>(p)); return AdaptedString(reinterpret_cast<const char*>(p));
@@ -90,7 +78,7 @@ class StaticStringAdapter : public ZeroTerminatedRamString {
template <> template <>
struct StringAdapter<const char*, void> { struct StringAdapter<const char*, void> {
typedef StaticStringAdapter AdaptedString; using AdaptedString = StaticStringAdapter;
static AdaptedString adapt(const char* p) { static AdaptedString adapt(const char* p) {
return AdaptedString(p); return AdaptedString(p);
@@ -132,7 +120,7 @@ class SizedRamString {
template <typename TChar> template <typename TChar>
struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> { struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
typedef SizedRamString AdaptedString; using AdaptedString = SizedRamString;
static AdaptedString adapt(const TChar* p, size_t n) { static AdaptedString adapt(const TChar* p, size_t n) {
return AdaptedString(reinterpret_cast<const char*>(p), n); return AdaptedString(reinterpret_cast<const char*>(p), n);

View File

@@ -15,7 +15,7 @@ struct StringAdapter<
T, T,
enable_if_t<(string_traits<T>::has_cstr || string_traits<T>::has_data) && enable_if_t<(string_traits<T>::has_cstr || string_traits<T>::has_data) &&
(string_traits<T>::has_length || string_traits<T>::has_size)>> { (string_traits<T>::has_length || string_traits<T>::has_size)>> {
typedef SizedRamString AdaptedString; using AdaptedString = SizedRamString;
static AdaptedString adapt(const T& s) { static AdaptedString adapt(const T& s) {
return AdaptedString(get_data(s), get_size(s)); return AdaptedString(get_data(s), get_size(s));

View File

@@ -136,7 +136,7 @@ class JsonVariantConst : public detail::VariantTag,
if (key.template is<size_t>()) if (key.template is<size_t>())
return operator[](key.template as<size_t>()); return operator[](key.template as<size_t>());
else else
return operator[](key.template as<const char*>()); return operator[](key.template as<JsonString>());
} }
// DEPRECATED: use obj[key].is<T>() instead // DEPRECATED: use obj[key].is<T>() instead

View File

@@ -11,7 +11,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class JsonVariantCopier { class JsonVariantCopier {
public: public:
typedef bool result_type; using result_type = bool;
JsonVariantCopier(JsonVariant dst) : dst_(dst) {} JsonVariantCopier(JsonVariant dst) : dst_(dst) {}

View File

@@ -13,7 +13,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TResult> template <typename TResult>
struct JsonVariantVisitor { struct JsonVariantVisitor {
typedef TResult result_type; using result_type = TResult;
template <typename T> template <typename T>
TResult visit(const T&) { TResult visit(const T&) {

View File

@@ -13,7 +13,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TResult> template <typename TResult>
struct VariantDataVisitor { struct VariantDataVisitor {
typedef TResult result_type; using result_type = TResult;
template <typename T> template <typename T>
TResult visit(const T&) { TResult visit(const T&) {

View File

@@ -207,7 +207,7 @@ class VariantRefBase : public VariantTag {
if (key.template is<size_t>()) if (key.template is<size_t>())
return operator[](key.template as<size_t>()); return operator[](key.template as<size_t>());
else else
return operator[](key.template as<const char*>()); return operator[](key.template as<JsonString>());
} }
// DEPRECATED: use add<JsonVariant>() instead // DEPRECATED: use add<JsonVariant>() instead

View File

@@ -20,15 +20,15 @@ struct VariantTo {};
template <> template <>
struct VariantTo<JsonArray> { struct VariantTo<JsonArray> {
typedef JsonArray type; using type = JsonArray;
}; };
template <> template <>
struct VariantTo<JsonObject> { struct VariantTo<JsonObject> {
typedef JsonObject type; using type = JsonObject;
}; };
template <> template <>
struct VariantTo<JsonVariant> { struct VariantTo<JsonVariant> {
typedef JsonVariant type; using type = JsonVariant;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -4,8 +4,8 @@
#pragma once #pragma once
#define ARDUINOJSON_VERSION "7.2.0" #define ARDUINOJSON_VERSION "7.2.1"
#define ARDUINOJSON_VERSION_MAJOR 7 #define ARDUINOJSON_VERSION_MAJOR 7
#define ARDUINOJSON_VERSION_MINOR 2 #define ARDUINOJSON_VERSION_MINOR 2
#define ARDUINOJSON_VERSION_REVISION 0 #define ARDUINOJSON_VERSION_REVISION 1
#define ARDUINOJSON_VERSION_MACRO V720 #define ARDUINOJSON_VERSION_MACRO V721

View File

@@ -4,7 +4,7 @@
#define NUKI_HUB_VERSION "9.03" #define NUKI_HUB_VERSION "9.03"
#define NUKI_HUB_BUILD "unknownbuildnr" #define NUKI_HUB_BUILD "unknownbuildnr"
#define NUKI_HUB_DATE "2024-12-01" #define NUKI_HUB_DATE "2024-12-03"
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest" #define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json" #define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"

View File

@@ -4,9 +4,9 @@ dependencies:
esp-nimble-cpp: esp-nimble-cpp:
git: https://github.com/h2zero/esp-nimble-cpp.git git: https://github.com/h2zero/esp-nimble-cpp.git
version: 020c61700dce2174769f855d45ab0ea70a2aaac4 version: 6c85cfa6c3d5ec9c46b87c761925b1bcb5c3827c
espressif/libsodium: "^1.0.20~1" espressif/libsodium: "^1.0.20~2"
# # Defining a dependency from the registry: # # Defining a dependency from the registry:
# # https://components.espressif.com/component/example/cmp # # https://components.espressif.com/component/example/cmp