From be9fa9eda2bc60e6b96f9cc095589438b0a8ef55 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Wed, 21 Feb 2024 18:40:49 +0100 Subject: [PATCH] Several fixes: - moved "StaticJsonDocument" to JsonDocument as StaticJsonDocument is marked depriciated. - Fixed display_plus show()-method - Fixed string length for drumset sounds - Newer version of third-party libraries --- MicroDexed.ino | 2 +- config.h | 2 +- dexed_sd.cpp | 26 +- disp_plus.h | 53 +- third-party/ArduinoJson/ArduinoJson.h | 2 +- third-party/ArduinoJson/CHANGELOG.md | 904 ++--------- third-party/ArduinoJson/CMakeLists.txt | 4 +- third-party/ArduinoJson/LICENSE.txt | 2 +- third-party/ArduinoJson/README.md | 76 +- third-party/ArduinoJson/appveyor.yml | 2 +- .../JsonConfigFile/JsonConfigFile.ino | 30 +- .../JsonFilterExample/JsonFilterExample.ino | 11 +- .../JsonGeneratorExample.ino | 30 +- .../JsonHttpClient/JsonHttpClient.ino | 13 +- .../JsonParserExample/JsonParserExample.ino | 33 +- .../examples/JsonServer/JsonServer.ino | 19 +- .../examples/JsonUdpBeacon/JsonUdpBeacon.ino | 16 +- .../examples/MsgPackParser/MsgPackParser.ino | 34 +- .../ProgmemExample/ProgmemExample.ino | 6 +- .../examples/StringExample/StringExample.ino | 7 +- .../ArduinoJson/extras/CompileOptions.cmake | 17 +- .../extras/ci/espidf/CMakeLists.txt | 2 +- .../extras/ci/espidf/main/CMakeLists.txt | 2 +- .../extras/ci/espidf/main/main.cpp | 4 +- .../ArduinoJson/extras/conf_test/avr.cpp | 3 +- .../ArduinoJson/extras/conf_test/esp8266.cpp | 3 +- .../ArduinoJson/extras/conf_test/x64.cpp | 5 +- .../ArduinoJson/extras/conf_test/x86.cpp | 3 +- .../ArduinoJson/extras/fuzzing/CMakeLists.txt | 2 +- .../extras/fuzzing/json_fuzzer.cpp | 2 +- .../extras/fuzzing/msgpack_fuzzer.cpp | 2 +- .../ArduinoJson/extras/fuzzing/reproducer.cpp | 2 +- .../extras/scripts/get-release-page.sh | 2 +- .../scripts/publish-particle-library.sh | 4 +- .../ArduinoJson/extras/scripts/publish.sh | 19 +- .../scripts/wandbox/JsonGeneratorExample.cpp | 28 +- .../scripts/wandbox/JsonParserExample.cpp | 30 +- .../scripts/wandbox/MsgPackParserExample.cpp | 31 +- .../ArduinoJson/extras/tests/CMakeLists.txt | 8 +- .../extras/tests/Cpp17/CMakeLists.txt | 2 +- .../extras/tests/Cpp17/string_view.cpp | 32 +- .../extras/tests/Cpp20/CMakeLists.txt | 2 +- .../extras/tests/Cpp20/smoke_test.cpp | 2 +- .../tests/Deprecated/BasicJsonDocument.cpp | 69 + .../extras/tests/Deprecated/CMakeLists.txt | 34 + .../tests/Deprecated/DynamicJsonDocument.cpp | 37 + .../tests/Deprecated/StaticJsonDocument.cpp | 32 + .../extras/tests/Deprecated/add.cpp | 38 + .../tests/Deprecated/createNestedArray.cpp | 111 ++ .../tests/Deprecated/createNestedObject.cpp | 111 ++ .../extras/tests/Deprecated/macros.cpp | 18 + .../extras/tests/Deprecated/memoryUsage.cpp | 51 + .../extras/tests/Deprecated/shallowCopy.cpp | 14 + .../extras/tests/FailingBuilds/CMakeLists.txt | 8 +- .../extras/tests/FailingBuilds/Issue978.cpp | 4 +- .../tests/FailingBuilds/assign_char.cpp | 4 +- .../tests/FailingBuilds/read_long_long.cpp | 4 +- .../tests/FailingBuilds/variant_as_char.cpp | 4 +- .../tests/FailingBuilds/write_long_long.cpp | 4 +- .../extras/tests/Helpers/Allocators.hpp | 283 ++++ .../extras/tests/Helpers/Arduino.h | 2 +- .../extras/tests/Helpers/CustomReader.hpp | 2 +- .../extras/tests/Helpers/api/Print.h | 2 +- .../extras/tests/Helpers/api/Stream.h | 2 +- .../extras/tests/Helpers/api/String.h | 36 +- .../extras/tests/Helpers/avr/pgmspace.h | 2 +- .../tests/IntegrationTests/CMakeLists.txt | 2 +- .../tests/IntegrationTests/gbathree.cpp | 4 +- .../tests/IntegrationTests/issue772.cpp | 6 +- .../tests/IntegrationTests/openweathermap.cpp | 6 +- .../tests/IntegrationTests/round_trip.cpp | 4 +- .../extras/tests/JsonArray/CMakeLists.txt | 4 +- .../extras/tests/JsonArray/add.cpp | 87 +- .../extras/tests/JsonArray/clear.cpp | 25 +- .../extras/tests/JsonArray/compare.cpp | 110 +- .../extras/tests/JsonArray/copyArray.cpp | 66 +- .../extras/tests/JsonArray/equals.cpp | 12 +- .../extras/tests/JsonArray/isNull.cpp | 32 +- .../extras/tests/JsonArray/iterator.cpp | 54 +- .../extras/tests/JsonArray/nesting.cpp | 8 +- .../extras/tests/JsonArray/remove.cpp | 26 +- .../extras/tests/JsonArray/size.cpp | 4 +- .../extras/tests/JsonArray/std_string.cpp | 4 +- .../extras/tests/JsonArray/subscript.cpp | 47 +- .../extras/tests/JsonArray/unbound.cpp | 10 +- .../tests/JsonArrayConst/CMakeLists.txt | 19 + .../extras/tests/JsonArrayConst/equals.cpp | 63 + .../extras/tests/JsonArrayConst/isNull.cpp | 32 + .../extras/tests/JsonArrayConst/iterator.cpp | 34 + .../extras/tests/JsonArrayConst/nesting.cpp | 35 + .../extras/tests/JsonArrayConst/size.cpp | 27 + .../extras/tests/JsonArrayConst/subscript.cpp | 20 + .../tests/JsonDeserializer/CMakeLists.txt | 8 +- .../JsonDeserializer/DeserializationError.cpp | 2 +- .../extras/tests/JsonDeserializer/array.cpp | 74 +- .../JsonDeserializer/destination_types.cpp | 108 ++ .../extras/tests/JsonDeserializer/errors.cpp | 120 ++ .../extras/tests/JsonDeserializer/filter.cpp | 1400 +++++++++-------- .../tests/JsonDeserializer/input_types.cpp | 57 +- .../extras/tests/JsonDeserializer/misc.cpp | 118 +- .../tests/JsonDeserializer/nestingLimit.cpp | 4 +- .../extras/tests/JsonDeserializer/number.cpp | 4 +- .../extras/tests/JsonDeserializer/object.cpp | 82 +- .../extras/tests/JsonDeserializer/string.cpp | 116 +- .../extras/tests/JsonDocument/CMakeLists.txt | 9 +- .../tests/JsonDocument/ElementProxy.cpp | 51 +- .../extras/tests/JsonDocument/MemberProxy.cpp | 145 +- .../extras/tests/JsonDocument/add.cpp | 88 +- .../extras/tests/JsonDocument/assignment.cpp | 134 ++ .../extras/tests/JsonDocument/cast.cpp | 4 +- .../extras/tests/JsonDocument/clear.cpp | 47 + .../extras/tests/JsonDocument/compare.cpp | 82 +- .../extras/tests/JsonDocument/constructor.cpp | 120 ++ .../extras/tests/JsonDocument/containsKey.cpp | 4 +- .../extras/tests/JsonDocument/isNull.cpp | 4 +- .../extras/tests/JsonDocument/issue1120.cpp | 2 +- .../extras/tests/JsonDocument/nesting.cpp | 4 +- .../extras/tests/JsonDocument/overflowed.cpp | 48 +- .../extras/tests/JsonDocument/remove.cpp | 4 +- .../extras/tests/JsonDocument/shrinkToFit.cpp | 187 ++- .../extras/tests/JsonDocument/size.cpp | 4 +- .../extras/tests/JsonDocument/subscript.cpp | 8 +- .../extras/tests/JsonDocument/swap.cpp | 10 +- .../extras/tests/JsonObject/CMakeLists.txt | 7 +- .../extras/tests/JsonObject/clear.cpp | 4 +- .../extras/tests/JsonObject/compare.cpp | 62 +- .../extras/tests/JsonObject/containsKey.cpp | 10 +- .../extras/tests/JsonObject/copy.cpp | 60 +- .../extras/tests/JsonObject/equals.cpp | 14 +- .../extras/tests/JsonObject/isNull.cpp | 32 +- .../extras/tests/JsonObject/iterator.cpp | 41 +- .../extras/tests/JsonObject/nesting.cpp | 8 +- .../extras/tests/JsonObject/remove.cpp | 7 +- .../extras/tests/JsonObject/size.cpp | 4 +- .../extras/tests/JsonObject/std_string.cpp | 48 +- .../extras/tests/JsonObject/subscript.cpp | 69 +- .../extras/tests/JsonObject/unbound.cpp | 27 + .../tests/JsonObjectConst/CMakeLists.txt | 20 + .../tests/JsonObjectConst/containsKey.cpp | 32 + .../extras/tests/JsonObjectConst/equals.cpp | 65 + .../extras/tests/JsonObjectConst/isNull.cpp | 32 + .../extras/tests/JsonObjectConst/iterator.cpp | 39 + .../extras/tests/JsonObjectConst/nesting.cpp | 35 + .../extras/tests/JsonObjectConst/size.cpp | 22 + .../tests/JsonObjectConst/subscript.cpp | 33 + .../tests/JsonSerializer/CMakeLists.txt | 2 +- .../tests/JsonSerializer/CustomWriter.cpp | 4 +- .../extras/tests/JsonSerializer/JsonArray.cpp | 32 +- .../tests/JsonSerializer/JsonArrayPretty.cpp | 12 +- .../tests/JsonSerializer/JsonObject.cpp | 16 +- .../tests/JsonSerializer/JsonObjectPretty.cpp | 12 +- .../tests/JsonSerializer/JsonVariant.cpp | 4 +- .../extras/tests/JsonSerializer/misc.cpp | 6 +- .../tests/JsonSerializer/std_stream.cpp | 4 +- .../tests/JsonSerializer/std_string.cpp | 19 +- .../extras/tests/JsonVariant/CMakeLists.txt | 5 +- .../extras/tests/JsonVariant/add.cpp | 30 +- .../extras/tests/JsonVariant/as.cpp | 15 +- .../extras/tests/JsonVariant/clear.cpp | 17 +- .../extras/tests/JsonVariant/compare.cpp | 12 +- .../extras/tests/JsonVariant/containsKey.cpp | 20 +- .../extras/tests/JsonVariant/converters.cpp | 19 +- .../extras/tests/JsonVariant/copy.cpp | 83 +- .../extras/tests/JsonVariant/is.cpp | 159 +- .../extras/tests/JsonVariant/isnull.cpp | 29 +- .../extras/tests/JsonVariant/misc.cpp | 11 +- .../extras/tests/JsonVariant/nesting.cpp | 4 +- .../extras/tests/JsonVariant/nullptr.cpp | 2 +- .../extras/tests/JsonVariant/or.cpp | 4 +- .../extras/tests/JsonVariant/overflow.cpp | 6 +- .../extras/tests/JsonVariant/remove.cpp | 83 +- .../extras/tests/JsonVariant/set.cpp | 61 +- .../extras/tests/JsonVariant/size.cpp | 4 +- .../tests/JsonVariant/stl_containers.cpp | 14 +- .../extras/tests/JsonVariant/subscript.cpp | 78 +- .../extras/tests/JsonVariant/types.cpp | 17 +- .../extras/tests/JsonVariant/unbound.cpp | 12 +- .../tests/JsonVariantConst/CMakeLists.txt | 20 + .../extras/tests/JsonVariantConst/as.cpp | 19 + .../tests/JsonVariantConst/containsKey.cpp | 33 + .../extras/tests/JsonVariantConst/is.cpp | 162 ++ .../extras/tests/JsonVariantConst/isnull.cpp | 21 + .../extras/tests/JsonVariantConst/nesting.cpp | 31 + .../extras/tests/JsonVariantConst/size.cpp | 36 + .../tests/JsonVariantConst/subscript.cpp | 68 + .../extras/tests/Misc/CMakeLists.txt | 3 +- .../extras/tests/Misc/FloatParts.cpp | 2 +- .../extras/tests/Misc/JsonString.cpp | 2 +- .../extras/tests/Misc/NoArduinoHeader.cpp | 2 +- .../ArduinoJson/extras/tests/Misc/Readers.cpp | 2 +- .../extras/tests/Misc/StringAdapters.cpp | 2 +- .../extras/tests/Misc/StringWriter.cpp | 6 +- .../extras/tests/Misc/TypeTraits.cpp | 11 +- .../ArduinoJson/extras/tests/Misc/Utf16.cpp | 2 +- .../ArduinoJson/extras/tests/Misc/Utf8.cpp | 7 +- .../extras/tests/Misc/arithmeticCompare.cpp | 2 +- .../extras/tests/Misc/conflicts.cpp | 4 +- .../extras/tests/Misc/custom_string.hpp | 2 +- .../extras/tests/Misc/issue1967.cpp | 13 + .../extras/tests/Misc/printable.cpp | 100 +- .../extras/tests/Misc/unsigned_char.cpp | 54 +- .../ArduinoJson/extras/tests/Misc/version.cpp | 2 +- .../extras/tests/Misc/weird_strcmp.hpp | 2 +- .../tests/MixedConfiguration/CMakeLists.txt | 4 +- .../MixedConfiguration/decode_unicode_0.cpp | 2 +- .../MixedConfiguration/decode_unicode_1.cpp | 2 +- .../MixedConfiguration/enable_comments_0.cpp | 4 +- .../MixedConfiguration/enable_comments_1.cpp | 8 +- .../MixedConfiguration/enable_infinity_0.cpp | 4 +- .../MixedConfiguration/enable_infinity_1.cpp | 2 +- .../tests/MixedConfiguration/enable_nan_0.cpp | 2 +- .../tests/MixedConfiguration/enable_nan_1.cpp | 2 +- .../MixedConfiguration/enable_progmem_1.cpp | 4 +- .../tests/MixedConfiguration/issue1707.cpp | 4 +- .../tests/MixedConfiguration/use_double_0.cpp | 2 +- .../tests/MixedConfiguration/use_double_1.cpp | 2 +- .../MixedConfiguration/use_long_long_0.cpp | 2 +- .../MixedConfiguration/use_long_long_1.cpp | 2 +- .../tests/MsgPackDeserializer/CMakeLists.txt | 8 +- .../MsgPackDeserializer/deserializeArray.cpp | 4 +- .../MsgPackDeserializer/deserializeObject.cpp | 4 +- .../deserializeVariant.cpp | 228 ++- .../MsgPackDeserializer/destination_types.cpp | 108 ++ .../MsgPackDeserializer/doubleToFloat.cpp | 2 +- .../tests/MsgPackDeserializer/errors.cpp | 265 ++++ .../tests/MsgPackDeserializer/filter.cpp | 817 ++++++++-- .../tests/MsgPackDeserializer/input_types.cpp | 12 +- .../MsgPackDeserializer/nestingLimit.cpp | 4 +- .../tests/MsgPackSerializer/CMakeLists.txt | 2 +- .../MsgPackSerializer/destination_types.cpp | 4 +- .../tests/MsgPackSerializer/measure.cpp | 4 +- .../extras/tests/MsgPackSerializer/misc.cpp | 8 +- .../MsgPackSerializer/serializeArray.cpp | 7 +- .../MsgPackSerializer/serializeObject.cpp | 4 +- .../MsgPackSerializer/serializeVariant.cpp | 4 +- .../extras/tests/Numbers/CMakeLists.txt | 2 +- .../extras/tests/Numbers/convertNumber.cpp | 2 +- .../extras/tests/Numbers/parseDouble.cpp | 2 +- .../extras/tests/Numbers/parseFloat.cpp | 2 +- .../extras/tests/Numbers/parseInteger.cpp | 2 +- .../extras/tests/Numbers/parseNumber.cpp | 2 +- .../tests/ResourceManager/CMakeLists.txt | 25 + .../tests/ResourceManager/StringBuilder.cpp | 143 ++ .../tests/ResourceManager/allocVariant.cpp | 94 ++ .../extras/tests/ResourceManager/clear.cpp | 30 + .../tests/ResourceManager/saveString.cpp | 70 + .../tests/ResourceManager/shrinkToFit.cpp | 57 + .../extras/tests/ResourceManager/size.cpp | 31 + .../extras/tests/ResourceManager/swap.cpp | 96 ++ .../extras/tests/TextFormatter/CMakeLists.txt | 2 +- .../extras/tests/TextFormatter/writeFloat.cpp | 2 +- .../tests/TextFormatter/writeInteger.cpp | 2 +- .../tests/TextFormatter/writeString.cpp | 2 +- third-party/ArduinoJson/idf_component.yml | 8 +- third-party/ArduinoJson/keywords.txt | 10 +- third-party/ArduinoJson/library.json | 12 +- third-party/ArduinoJson/library.properties | 4 +- third-party/ArduinoJson/src/ArduinoJson.h | 2 +- third-party/ArduinoJson/src/ArduinoJson.hpp | 13 +- .../src/ArduinoJson/Array/ArrayData.hpp | 57 + .../src/ArduinoJson/Array/ArrayImpl.hpp | 50 + .../src/ArduinoJson/Array/ElementProxy.hpp | 27 +- .../src/ArduinoJson/Array/JsonArray.hpp | 199 ++- .../src/ArduinoJson/Array/JsonArrayConst.hpp | 122 +- .../ArduinoJson/Array/JsonArrayIterator.hpp | 93 +- .../src/ArduinoJson/Array/Utilities.hpp | 18 +- .../ArduinoJson/Collection/CollectionData.hpp | 122 +- .../ArduinoJson/Collection/CollectionImpl.hpp | 234 +-- .../src/ArduinoJson/Configuration.hpp | 80 +- .../Deserialization/DeserializationError.hpp | 2 +- .../DeserializationOptions.hpp | 2 +- .../ArduinoJson/Deserialization/Filter.hpp | 13 +- .../Deserialization/NestingLimit.hpp | 2 +- .../ArduinoJson/Deserialization/Reader.hpp | 4 +- .../Readers/ArduinoStreamReader.hpp | 4 +- .../Readers/ArduinoStringReader.hpp | 2 +- .../Deserialization/Readers/FlashReader.hpp | 2 +- .../Readers/IteratorReader.hpp | 2 +- .../Deserialization/Readers/RamReader.hpp | 2 +- .../Readers/StdStreamReader.hpp | 2 +- .../Deserialization/Readers/VariantReader.hpp | 2 +- .../Deserialization/deserialize.hpp | 79 +- .../src/ArduinoJson/Document/JsonDocument.hpp | 332 ++-- .../src/ArduinoJson/Json/EscapeSequence.hpp | 2 +- .../src/ArduinoJson/Json/JsonDeserializer.hpp | 96 +- .../src/ArduinoJson/Json/JsonSerializer.hpp | 68 +- .../src/ArduinoJson/Json/Latch.hpp | 2 +- .../ArduinoJson/Json/PrettyJsonSerializer.hpp | 43 +- .../src/ArduinoJson/Json/TextFormatter.hpp | 2 +- .../src/ArduinoJson/Json/Utf16.hpp | 2 +- .../ArduinoJson/src/ArduinoJson/Json/Utf8.hpp | 2 +- .../src/ArduinoJson/Memory/Alignment.hpp | 2 +- .../src/ArduinoJson/Memory/Allocator.hpp | 49 + .../ArduinoJson/Memory/ResourceManager.hpp | 127 ++ .../src/ArduinoJson/Memory/StringBuilder.hpp | 80 + .../src/ArduinoJson/Memory/StringNode.hpp | 73 + .../src/ArduinoJson/Memory/StringPool.hpp | 105 ++ .../src/ArduinoJson/Memory/VariantPool.hpp | 63 + .../ArduinoJson/Memory/VariantPoolImpl.hpp | 81 + .../ArduinoJson/Memory/VariantPoolList.hpp | 189 +++ .../src/ArduinoJson/Misc/SerializedValue.hpp | 4 +- .../MsgPack/MsgPackDeserializer.hpp | 75 +- .../ArduinoJson/MsgPack/MsgPackSerializer.hpp | 73 +- .../src/ArduinoJson/MsgPack/endianess.hpp | 2 +- .../src/ArduinoJson/MsgPack/ieee754.hpp | 2 +- .../ArduinoJson/src/ArduinoJson/Namespace.hpp | 22 +- .../src/ArduinoJson/Numbers/FloatParts.hpp | 2 +- .../src/ArduinoJson/Numbers/FloatTraits.hpp | 2 +- .../src/ArduinoJson/Numbers/JsonFloat.hpp | 2 +- .../src/ArduinoJson/Numbers/JsonInteger.hpp | 4 +- .../ArduinoJson/Numbers/arithmeticCompare.hpp | 2 +- .../src/ArduinoJson/Numbers/convertNumber.hpp | 2 +- .../src/ArduinoJson/Numbers/parseNumber.hpp | 4 +- .../src/ArduinoJson/Object/JsonObject.hpp | 222 ++- .../ArduinoJson/Object/JsonObjectConst.hpp | 137 +- .../ArduinoJson/Object/JsonObjectIterator.hpp | 92 +- .../src/ArduinoJson/Object/JsonPair.hpp | 54 +- .../src/ArduinoJson/Object/MemberProxy.hpp | 33 +- .../src/ArduinoJson/Object/ObjectData.hpp | 73 + .../src/ArduinoJson/Object/ObjectImpl.hpp | 45 + .../src/ArduinoJson/Polyfills/alias_cast.hpp | 2 +- .../src/ArduinoJson/Polyfills/assert.hpp | 2 +- .../src/ArduinoJson/Polyfills/attributes.hpp | 21 +- .../src/ArduinoJson/Polyfills/ctype.hpp | 2 +- .../src/ArduinoJson/Polyfills/integer.hpp | 16 +- .../src/ArduinoJson/Polyfills/limits.hpp | 10 +- .../src/ArduinoJson/Polyfills/math.hpp | 2 +- .../src/ArduinoJson/Polyfills/mpl/max.hpp | 2 +- .../src/ArduinoJson/Polyfills/pgmspace.hpp | 2 +- .../Polyfills/pgmspace_generic.hpp | 2 +- .../ArduinoJson/Polyfills/preprocessor.hpp | 2 +- .../src/ArduinoJson/Polyfills/type_traits.hpp | 2 +- .../Polyfills/type_traits/conditional.hpp | 2 +- .../Polyfills/type_traits/declval.hpp | 2 +- .../Polyfills/type_traits/enable_if.hpp | 2 +- .../type_traits/integral_constant.hpp | 2 +- .../Polyfills/type_traits/is_array.hpp | 2 +- .../Polyfills/type_traits/is_base_of.hpp | 2 +- .../Polyfills/type_traits/is_class.hpp | 2 +- .../Polyfills/type_traits/is_const.hpp | 2 +- .../Polyfills/type_traits/is_convertible.hpp | 2 +- .../Polyfills/type_traits/is_enum.hpp | 2 +- .../type_traits/is_floating_point.hpp | 2 +- .../Polyfills/type_traits/is_integral.hpp | 2 +- .../Polyfills/type_traits/is_pointer.hpp | 2 +- .../Polyfills/type_traits/is_same.hpp | 2 +- .../Polyfills/type_traits/is_signed.hpp | 2 +- .../Polyfills/type_traits/is_unsigned.hpp | 2 +- .../Polyfills/type_traits/make_unsigned.hpp | 2 +- .../Polyfills/type_traits/make_void.hpp | 2 +- .../Polyfills/type_traits/remove_const.hpp | 2 +- .../Polyfills/type_traits/remove_cv.hpp | 2 +- .../type_traits/remove_reference.hpp | 2 +- .../Polyfills/type_traits/type_identity.hpp | 2 +- .../src/ArduinoJson/Polyfills/utility.hpp | 19 +- .../Serialization/CountingDecorator.hpp | 2 +- .../src/ArduinoJson/Serialization/Writer.hpp | 2 +- .../Writers/ArduinoStringWriter.hpp | 8 +- .../Serialization/Writers/DummyWriter.hpp | 2 +- .../Serialization/Writers/PrintWriter.hpp | 2 +- .../Writers/StaticStringWriter.hpp | 2 +- .../Serialization/Writers/StdStreamWriter.hpp | 2 +- .../Serialization/Writers/StdStringWriter.hpp | 12 +- .../src/ArduinoJson/Serialization/measure.hpp | 8 +- .../ArduinoJson/Serialization/serialize.hpp | 8 +- .../Strings/Adapters/FlashString.hpp | 10 +- .../Strings/Adapters/JsonString.hpp | 7 +- .../Strings/Adapters/RamString.hpp | 18 +- .../Strings/Adapters/StringObject.hpp | 2 +- .../src/ArduinoJson/Strings/IsString.hpp | 2 +- .../src/ArduinoJson/Strings/JsonString.hpp | 4 +- .../src/ArduinoJson/Strings/StringAdapter.hpp | 2 +- .../ArduinoJson/Strings/StringAdapters.hpp | 2 +- .../src/ArduinoJson/Strings/StringTraits.hpp | 2 +- .../src/ArduinoJson/Variant/Converter.hpp | 4 +- .../src/ArduinoJson/Variant/ConverterImpl.hpp | 223 ++- .../src/ArduinoJson/Variant/JsonVariant.hpp | 32 +- .../ArduinoJson/Variant/JsonVariantConst.hpp | 116 +- .../ArduinoJson/Variant/JsonVariantCopier.hpp | 34 + .../Variant/JsonVariantVisitor.hpp | 61 + .../ArduinoJson/Variant/VariantAttorney.hpp | 27 +- .../ArduinoJson/Variant/VariantCompare.hpp | 123 +- .../ArduinoJson/Variant/VariantContent.hpp | 23 +- .../src/ArduinoJson/Variant/VariantData.hpp | 478 ++++-- .../Variant/VariantDataVisitor.hpp | 24 + .../ArduinoJson/Variant/VariantOperators.hpp | 2 +- .../ArduinoJson/Variant/VariantRefBase.hpp | 252 ++- .../Variant/VariantRefBaseImpl.hpp | 177 +++ .../src/ArduinoJson/Variant/VariantSlot.hpp | 98 +- .../src/ArduinoJson/Variant/VariantTag.hpp | 2 +- .../src/ArduinoJson/Variant/VariantTo.hpp | 2 +- .../src/ArduinoJson/compatibility.hpp | 123 +- .../ArduinoJson/src/ArduinoJson/version.hpp | 10 +- third-party/ArduinoJson/src/CMakeLists.txt | 2 +- third-party/Synth_Dexed/src/compressor.h | 18 +- .../examples/AudioDelay8M/AudioDelay8M.ino | 53 +- 396 files changed, 10267 insertions(+), 5493 deletions(-) create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/BasicJsonDocument.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/CMakeLists.txt create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/DynamicJsonDocument.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/StaticJsonDocument.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/add.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/createNestedArray.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/createNestedObject.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/macros.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/memoryUsage.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Deprecated/shallowCopy.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Helpers/Allocators.hpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonArrayConst/CMakeLists.txt create mode 100644 third-party/ArduinoJson/extras/tests/JsonArrayConst/equals.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonArrayConst/isNull.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonArrayConst/iterator.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonArrayConst/nesting.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonArrayConst/size.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonArrayConst/subscript.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonDeserializer/destination_types.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonDeserializer/errors.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonDocument/assignment.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonDocument/clear.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonDocument/constructor.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonObject/unbound.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonObjectConst/CMakeLists.txt create mode 100644 third-party/ArduinoJson/extras/tests/JsonObjectConst/containsKey.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonObjectConst/equals.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonObjectConst/isNull.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonObjectConst/iterator.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonObjectConst/nesting.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonObjectConst/size.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonObjectConst/subscript.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonVariantConst/CMakeLists.txt create mode 100644 third-party/ArduinoJson/extras/tests/JsonVariantConst/as.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonVariantConst/containsKey.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonVariantConst/is.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonVariantConst/isnull.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonVariantConst/nesting.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonVariantConst/size.cpp create mode 100644 third-party/ArduinoJson/extras/tests/JsonVariantConst/subscript.cpp create mode 100644 third-party/ArduinoJson/extras/tests/Misc/issue1967.cpp create mode 100644 third-party/ArduinoJson/extras/tests/MsgPackDeserializer/destination_types.cpp create mode 100644 third-party/ArduinoJson/extras/tests/MsgPackDeserializer/errors.cpp create mode 100644 third-party/ArduinoJson/extras/tests/ResourceManager/CMakeLists.txt create mode 100644 third-party/ArduinoJson/extras/tests/ResourceManager/StringBuilder.cpp create mode 100644 third-party/ArduinoJson/extras/tests/ResourceManager/allocVariant.cpp create mode 100644 third-party/ArduinoJson/extras/tests/ResourceManager/clear.cpp create mode 100644 third-party/ArduinoJson/extras/tests/ResourceManager/saveString.cpp create mode 100644 third-party/ArduinoJson/extras/tests/ResourceManager/shrinkToFit.cpp create mode 100644 third-party/ArduinoJson/extras/tests/ResourceManager/size.cpp create mode 100644 third-party/ArduinoJson/extras/tests/ResourceManager/swap.cpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Array/ArrayData.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Memory/Allocator.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Memory/ResourceManager.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Memory/StringBuilder.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Memory/StringNode.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Memory/StringPool.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Memory/VariantPool.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Memory/VariantPoolImpl.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Memory/VariantPoolList.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Object/ObjectData.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Object/ObjectImpl.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Variant/JsonVariantCopier.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Variant/JsonVariantVisitor.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Variant/VariantDataVisitor.hpp create mode 100644 third-party/ArduinoJson/src/ArduinoJson/Variant/VariantRefBaseImpl.hpp diff --git a/MicroDexed.ino b/MicroDexed.ino index 6e0b7e0..4c58252 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -67,7 +67,7 @@ AudioEffectModulatedDelay* modchorus[NUM_DEXED]; AudioMixer<2>* chorus_mixer[NUM_DEXED]; AudioMixer<2>* delay_fb_mixer[NUM_DEXED]; #if defined(USE_DELAY_8M) -AudioEffectDelayExternal8* delay_fx[NUM_DEXED]; +AudioEffectDelayExternal8* delay_fx[NUM_DEXED]; // APS6404L-3SQR QSPI PSRAM (1 MB) #else AudioEffectDelay* delay_fx[NUM_DEXED]; #endif diff --git a/config.h b/config.h index 39449e0..338ef2f 100644 --- a/config.h +++ b/config.h @@ -263,7 +263,7 @@ #define VOICE_NAME_LEN 12 // 11 (plus '\0') #define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN #define CONFIG_FILENAME_LEN 50 -#define DRUM_NAME_LEN 10 +#define DRUM_NAME_LEN 16 #define PERFORMANCE_NAME_LEN 11 #define FAV_CONFIG_PATH "FAVCFG" diff --git a/dexed_sd.cpp b/dexed_sd.cpp index 6c423bb..9c0438b 100644 --- a/dexed_sd.cpp +++ b/dexed_sd.cpp @@ -408,7 +408,7 @@ bool load_sd_drumsettings_json(uint8_t number) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, DRUMS_CONFIG_NAME); @@ -470,7 +470,7 @@ bool save_sd_drumsettings_json(uint8_t number) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; if (check_performance_directory(number)) { snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, DRUMS_CONFIG_NAME); @@ -558,7 +558,7 @@ bool load_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s%d.json"), PERFORMANCE_CONFIG_PATH, vc, VOICE_CONFIG_NAME, instance_id + 1); @@ -646,7 +646,7 @@ bool save_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s%d.json"), PERFORMANCE_CONFIG_PATH, vc, VOICE_CONFIG_NAME, instance_id + 1); #ifdef DEBUG @@ -730,7 +730,7 @@ bool load_sd_fx_json(uint8_t number) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, FX_CONFIG_NAME); @@ -818,7 +818,7 @@ bool save_sd_fx_json(uint8_t number) { save_sd_drumsettings_json(number); if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, FX_CONFIG_NAME); #ifdef DEBUG @@ -896,7 +896,7 @@ bool load_sd_epiano_json(uint8_t number) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, EPIANO_CONFIG_NAME); @@ -970,7 +970,7 @@ bool save_sd_epiano_json(uint8_t number) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, EPIANO_CONFIG_NAME); #ifdef DEBUG @@ -1033,7 +1033,7 @@ bool save_sd_epiano_json(uint8_t number) { bool load_sd_sys_json(void) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; snprintf_P(filename, sizeof(filename), PSTR("/%s.json"), SYS_CONFIG_NAME); @@ -1092,7 +1092,7 @@ bool save_sd_sys_json(void) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s.json"), SYS_CONFIG_NAME); #ifdef DEBUG @@ -1170,7 +1170,7 @@ bool save_sd_performance_json(uint8_t number) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, PERFORMANCE_CONFIG_NAME); #ifdef DEBUG Serial.print(F("Saving performance config ")); @@ -1242,7 +1242,7 @@ void get_sd_performance_name_json(uint8_t number, char* name, uint8_t len) { number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, PERFORMANCE_CONFIG_NAME); @@ -1289,7 +1289,7 @@ bool load_sd_performance_json(uint8_t number) { if (sd_card > 0) { File json; - StaticJsonDocument data_json; + JsonDocument data_json; for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { #ifdef DEBUG diff --git a/disp_plus.h b/disp_plus.h index 3b714de..328adfc 100644 --- a/disp_plus.h +++ b/disp_plus.h @@ -37,49 +37,26 @@ public: using T::T; void show(uint8_t y, uint8_t x, uint8_t fs, const char *str) { - _show(y, x, fs, str, false, false); + char tmp[STRING_BUFFER_SIZE]; + char format_str[16]; + + snprintf_P(format_str, sizeof(format_str), PSTR("%%-%ds"), fs); + snprintf(tmp, sizeof(tmp), format_str, str); + + this->setCursor(x, y); + this->print(tmp); } void show(uint8_t y, uint8_t x, uint8_t fs, long num) { - char _buf10[STRING_BUFFER_SIZE]; + char tmp[STRING_BUFFER_SIZE]; + char format_str[16]; - _show(y, x, fs, itoa(num, _buf10, 10), true, true); + snprintf_P(format_str, sizeof(format_str), PSTR("%%0%dd"), fs); + snprintf(tmp, sizeof(tmp), format_str, num); + + this->setCursor(x, y); + this->print(tmp); } private: - void _show(uint8_t pos_y, uint8_t pos_x, uint8_t field_size, const char *str, bool justify_right, bool fill_zero) { - { - char tmp[STRING_BUFFER_SIZE]; - char *s = tmp; - uint8_t l = strlen(str); - - memset(tmp, 0, sizeof(tmp)); - if (fill_zero == true) - memset(tmp, '0', field_size); - else - memset(tmp, 0x20, field_size); // blank - - if (l > field_size) - l = field_size; - - if (justify_right == true) - s += field_size - l; - - strncpy(s, str, l); - //s[l] = '\0'; - - //setCursor(pos_x * getMaxCharWidth(), pos_y * getMaxCharHeight()); - this->setCursor(pos_x, pos_y); - this->print(tmp); - -#ifdef DEBUG - Serial.print(pos_y, DEC); - Serial.print(F("/")); - Serial.print(pos_x, DEC); - Serial.print(F(": [")); - Serial.print(tmp); - Serial.println(F("]")); -#endif - } - } }; diff --git a/third-party/ArduinoJson/ArduinoJson.h b/third-party/ArduinoJson/ArduinoJson.h index 15c218f..9939599 100644 --- a/third-party/ArduinoJson/ArduinoJson.h +++ b/third-party/ArduinoJson/ArduinoJson.h @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include "src/ArduinoJson.h" diff --git a/third-party/ArduinoJson/CHANGELOG.md b/third-party/ArduinoJson/CHANGELOG.md index 28c506a..fa4cfe6 100644 --- a/third-party/ArduinoJson/CHANGELOG.md +++ b/third-party/ArduinoJson/CHANGELOG.md @@ -1,854 +1,130 @@ ArduinoJson: change log ======================= -v6.21.3 (2023-07-23) -------- - -* Fix compatibility with the Blynk libary (issue #1914) -* Fix double lookup in `to()` -* Fix double call to `size()` in `serializeMsgPack()` -* Include `ARDUINOJSON_SLOT_OFFSET_SIZE` in the namespace name -* Show a link to the documentation when user passes an unsupported input type - -v6.21.2 (2023-04-12) -------- - -* Fix compatibility with the Zephyr Project (issue #1905) -* Allow using PROGMEM outside of Arduino (issue #1903) -* Set default for `ARDUINOJSON_ENABLE_PROGMEM` to `1` on AVR - -v6.21.1 (2023-03-27) -------- - -* Double speed of `DynamicJsonDocument::garbageCollect()` -* Fix compatibility with GCC 5.2 (issue #1897) - -v6.21.0 (2023-03-14) -------- - -* Drop support for C++98/C++03. Minimum required is C++11. -* Remove `ARDUINOJSON_NAMESPACE`; use `ArduinoJson` instead. -* Make string support generic (issue #1807) - -v6.20.1 (2023-02-08) -------- - -* Remove explicit exclusion of `as()` and `as()` (issue #1860) - If you try to call them, you'll now get the same error message as any unsupported type. - You could also add a custom converter for `char*` and `char`. - -v6.20.0 (2022-12-26) -------- - -* Add `JsonVariant::shallowCopy()` (issue #1343) -* Fix `9.22337e+18 is outside the range of representable values of type 'long'` -* Fix comparison operators for `JsonArray`, `JsonArrayConst`, `JsonObject`, and `JsonObjectConst` -* Fix lax parsing of `true`, `false`, and `null` (issue #1781) -* Remove undocumented `accept()` functions -* Rename `addElement()` to `add()` -* Remove `getElement()`, `getOrAddElement()`, `getMember()`, and `getOrAddMember()` -* Remove undocumented `JsonDocument::data()` and `JsonDocument::memoryPool()` -* Remove undocumented `JsonArrayIterator::internal()` and `JsonObjectIterator::internal()` -* Rename things in `ARDUINOJSON_NAMESPACE` to match the public names -* Add documentation to most public symbols -* Remove support for naked `char` (was deprecated since 6.18.0) - -> ### BREAKING CHANGES -> -> This release hides `JsonVariant`'s functions that were only intended for internal use. -> If you were using them in your programs, you must replace with `operator[]` and `to()`, like so: -> -> ```c++ -> // before -> JsonVariant a = variant.getElement(idx); -> JsonVariant b = variant.getOrAddElement(idx); -> JsonVariant c = variant.getMember(key); -> JsonVariant d = variant.getOrAddMember(key); -> -> // after -> JsonVariant a = variant[idx]; -> JsonVariant b = idx < variant.size() ? variant[idx] : variant[idx].to(); -> JsonVariant c = variant[key]; -> JsonVariant d = variant.containsKey(key) ? variant[key] : variant[key].to(); -> ``` - -v6.19.4 (2022-04-05) -------- - -* Add `ElementProxy::memoryUsage()` -* Add `MemberProxy::memoryUsage()` (issue #1730) -* Add implicit conversion from `JsonDocument` to `JsonVariant` -* Fix comparisons operators with `const JsonDocument&` - -v6.19.3 (2022-03-08) -------- - -* Fix `call of overloaded 'String(const char*, int)' is ambiguous` -* Fix `JsonString` operator `==` and `!=` for non-zero-terminated string -* Fix `-Wsign-conversion` on GCC 8 (issue #1715) -* MessagePack: serialize round floats as integers (issue #1718) - -v6.19.2 (2022-02-14) -------- - -* Fix `cannot convert 'pgm_p' to 'const void*'` (issue #1707) - -v6.19.1 (2022-01-14) -------- - -* Fix crash when adding an object member in a too small `JsonDocument` -* Fix filter not working in zero-copy mode (issue #1697) - -v6.19.0 (2022-01-08) -------- - -* Remove `ARDUINOJSON_EMBEDDED_MODE` and assume we run on an embedded platform. - Dependent settings (like `ARDUINOJSON_DEFAULT_NESTING_LIMIT`) must be set individually. -* Change the default of `ARDUINOJSON_USE_DOUBLE` to `1` -* Change the default of `ARDUINOJSON_USE_LONG_LONG` to `1` on 32-bit platforms -* Add `as()` and `is()` -* Add safe bool idiom in `JsonString` -* Add support for NUL in string values (issue #1646) -* Add support for arbitrary array rank in `copyArray()` -* Add support for `char[][]` in `copyArray()` -* Remove `DeserializationError == bool` and `DeserializationError != bool` -* Renamed undocumented function `isUndefined()` to `isUnbound()` -* Fix `JsonVariant::memoryUsage()` for raw strings -* Fix `call of overloaded 'swap(BasicJsonDocument&, BasicJsonDocument&)' is ambiguous` (issue #1678) -* Fix inconsistent pool capacity between `BasicJsonDocument`'s copy and move constructors -* Fix inconsistent pool capacity between `BasicJsonDocument`'s copy and move assignments -* Fix return type of `StaticJsonDocument::operator=` -* Avoid pool reallocation in `BasicJsonDocument`'s copy assignment if capacity is the same -* Avoid including `Arduino.h` when all its features are disabled (issue #1692, PR #1693 by @paulocsanz) -* Assume `PROGMEM` is available as soon as `ARDUINO` is defined (consequence of #1693) - -v6.18.5 (2021-09-28) -------- - -* Set `ARDUINOJSON_EMBEDDED_MODE` to `1` on Nios II (issue #1657) - -v6.18.4 (2021-09-06) -------- - -* Fixed error `'dummy' may be used uninitialized` on GCC 11 -* Fixed error `expected unqualified-id before 'const'` on GCC 11 (issue #1622) -* Filter: exact match takes precedence over wildcard (issue #1628) -* Fixed deserialization of `\u0000` (issue #1646) - -v6.18.3 (2021-07-27) -------- - -* Changed return type of `convertToJson()` and `Converter::toJson()` to `void` -* Added `as()` and `is()` - -v6.18.2 (2021-07-19) -------- - -* Removed a symlink because the Arduino Library Specification forbids it - -v6.18.1 (2021-07-03) -------- - -* Fixed support for `volatile float` and `volatile double` (issue #1557) -* Fixed error `[Pe070]: incomplete type is not allowed` on IAR (issue #1560) -* Fixed `serializeJson(doc, String)` when allocation fails (issue #1572) -* Fixed clang-tidy warnings (issue #1574, PR #1577 by @armandas) -* Added fake class `InvalidConversion` to easily identify invalid conversions (issue #1585) -* Added support for `std::string_view` (issue #1578, PR #1554 by @0xFEEDC0DE64) -* Fixed warning `definition of implicit copy constructor for 'MsgPackDeserializer' is deprecated because it has a user-declared copy assignment operator` -* Added `JsonArray::clear()` (issue #1597) -* Fixed `JsonVariant::as()` (issue #1601) -* Added support for ESP-IDF component build (PR #1562 by @qt1, PR #1599 by @andreaskuster) - -v6.18.0 (2021-05-05) -------- - -* Added support for custom converters (issue #687) -* Added support for `Printable` (issue #1444) -* Removed support for `char` values, see below (issue #1498) -* `deserializeJson()` leaves `\uXXXX` unchanged instead of returning `NotSupported` -* `deserializeMsgPack()` inserts `null` instead of returning `NotSupported` -* Removed `DeserializationError::NotSupported` -* Added `JsonVariant::is()` (issue #1412) -* Added `JsonVariant::is()` (issue #1412) -* Changed `JsonVariantConst::is()` to return `false` (issue #1412) -* Simplified `JsonVariant::as()` to always return `T` (see below) -* Updated folders list in `.mbedignore` (PR #1515 by @AGlass0fMilk) -* Fixed member-call-on-null-pointer in `getMember()` when array is empty -* `serializeMsgPack(doc, buffer, size)` doesn't add null-terminator anymore (issue #1545) -* `serializeJson(doc, buffer, size)` adds null-terminator only if there is enough room -* PlatformIO: set `build.libArchive` to `false` (PR #1550 by @askreet) - -> ### BREAKING CHANGES -> -> #### Support for `char` removed -> -> We cannot cast a `JsonVariant` to a `char` anymore, so the following will break: -> ```c++ -> char age = doc["age"]; // error: no matching function for call to 'variantAs(VariantData*&)' -> ``` -> Instead, you must use another integral type, such as `int8_t`: -> ```c++ -> int8_t age = doc["age"]; // OK -> ``` -> -> Similarly, we cannot assign from a `char` anymore, so the following will break: -> ```c++ -> char age; -> doc["age"] = age; // error: no matching function for call to 'VariantRef::set(const char&)' -> ``` -> Instead, you must use another integral type, such as `int8_t`: -> ```c++ -> int8_t age; -> doc["age"] = age; // OK -> ``` -> A deprecation warning with the message "Support for `char` is deprecated, use `int8_t` or `uint8_t` instead" was added to allow a smooth transition. -> -> #### `as()` always returns `T` -> -> Previously, `JsonVariant::as()` could return a type different from `T`. -> The most common example is `as()` that returned a `const char*`. -> While this feature simplified a few use cases, it was confusing and complicated the -> implementation of custom converters. -> -> Starting from this version, `as` doesn't try to auto-correct the return type and always return `T`, -> which means that you cannot write this anymore: -> -> ```c++ -> Serial.println(doc["sensor"].as()); // error: invalid conversion from 'const char*' to 'char*' [-fpermissive] -> ``` -> -> Instead, you must write: -> -> ```c++ -> Serial.println(doc["sensor"].as()); // OK -> ``` -> -> A deprecation warning with the message "Replace `as()` with `as()`" was added to allow a smooth transition. -> -> #### `DeserializationError::NotSupported` removed -> -> On a different topic, `DeserializationError::NotSupported` has been removed. -> Instead of returning this error: -> -> * `deserializeJson()` leaves `\uXXXX` unchanged (only when `ARDUINOJSON_DECODE_UNICODE` is `0`) -> * `deserializeMsgPack()` replaces unsupported values with `null`s -> -> #### Const-aware `is()` -> -> Lastly, a very minor change concerns `JsonVariantConst::is()`. -> It used to return `true` for `JsonArray` and `JsonOject`, but now it returns `false`. -> Instead, you must use `JsonArrayConst` and `JsonObjectConst`. - -v6.17.3 (2021-02-15) -------- - -* Made `JsonDocument`'s destructor protected (issue #1480) -* Added missing calls to `client.stop()` in `JsonHttpClient.ino` (issue #1485) -* Fixed error `expected ')' before 'char'` when `isdigit()` is a macro (issue #1487) -* Fixed error `definition of implicit copy constructor is deprecated` on Clang 10 -* PlatformIO: set framework compatibility to `*` (PR #1490 by @maxgerhardt) - -v6.17.2 (2020-11-14) -------- - -* Fixed invalid conversion error in `operator|(JsonVariant, char*)` (issue #1432) -* Changed the default value of `ARDUINOJSON_ENABLE_PROGMEM` (issue #1433). - It now checks that the `pgm_read_XXX` macros are defined before enabling `PROGMEM`. - -v6.17.1 (2020-11-07) -------- - -* Fixed error `ambiguous overload for 'operator|'` (issue #1411) -* Fixed `operator|(MemberProxy, JsonObject)` (issue #1415) -* Allowed more than 32767 values in non-embedded mode (issue #1414) - -v6.17.0 (2020-10-19) -------- - -* Added a build failure when nullptr is defined as a macro (issue #1355) -* Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358) -* Added `DeserializationError::EmptyInput` which tells if the input was empty -* Added `DeserializationError::f_str()` which returns a `const __FlashStringHelper*` (issue #846) -* Added `operator|(JsonVariantConst, JsonVariantConst)` -* Added filtering for MessagePack (issue #1298, PR #1394 by Luca Passarella) -* Moved float convertion tables to PROGMEM -* Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368) -* Fixed error `No such file or directory #include ` (issue #1381) - -v6.16.1 (2020-08-04) -------- - -* Fixed `deserializeJson()` that stopped reading after `{}` (issue #1335) - -v6.16.0 (2020-08-01) -------- +v7.0.3 (2024-02-05) +------ -* Added comparisons (`>`, `>=`, `==`, `!=`, `<`, and `<=`) between `JsonVariant`s -* Added string deduplication (issue #1303) -* Added `JsonString::operator!=` -* Added wildcard key (`*`) for filters (issue #1309) -* Set `ARDUINOJSON_DECODE_UNICODE` to `1` by default -* Fixed `copyArray()` not working with `String`, `ElementProxy`, and `MemberProxy` -* Fixed error `getOrAddElement is not a member of ElementProxy` (issue #1311) -* Fixed excessive stack usage when compiled with `-Og` (issues #1210 and #1314) -* Fixed `Warning[Pa093]: implicit conversion from floating point to integer` on IAR compiler (PR #1328 by @stawiski) +* Improve error messages when using `char` or `char*` (issue #2043) +* Reduce stack consumption (issue #2046) +* Fix compatibility with GCC 4.8 (issue #2045) -v6.15.2 (2020-05-15) -------- +v7.0.2 (2024-01-19) +------ -* CMake: don't build tests when imported in another project -* CMake: made project arch-independent -* Visual Studio: fixed error C2766 with flag `/Zc:__cplusplus` (issue #1250) -* Added support for `JsonDocument` to `copyArray()` (issue #1255) -* Added support for `enum`s in `as()` and `is()` (issue #1256) -* Added `JsonVariant` as an input type for `deserializeXxx()` - For example, you can do: `deserializeJson(doc2, doc1["payload"])` -* Break the build if using 64-bit integers with ARDUINOJSON_USE_LONG_LONG==0 +* Fix assertion `poolIndex < count_` after `JsonDocument::clear()` (issue #2034) -v6.15.1 (2020-04-08) -------- +v7.0.1 (2024-01-10) +------ -* Fixed "maybe-uninitialized" warning (issue #1217) -* Fixed "statement is unreachable" warning on IAR (issue #1233) -* Fixed "pointless integer comparison" warning on IAR (issue #1233) -* Added CMake "install" target (issue #1209) -* Disabled alignment on AVR (issue #1231) +* Fix "no matching function" with `JsonObjectConst::operator[]` (issue #2019) +* Remove unused files in the PlatformIO package +* Fix `volatile bool` serialized as `1` or `0` instead of `true` or `false` (issue #2029) -v6.15.0 (2020-03-22) -------- +v7.0.0 (2024-01-03) +------ -* Added `DeserializationOption::Filter` (issue #959) -* Added example `JsonFilterExample.ino` -* Changed the array subscript operator to automatically add missing elements -* Fixed "deprecated-copy" warning on GCC 9 (fixes #1184) -* Fixed `MemberProxy::set(char[])` not duplicating the string (issue #1191) -* Fixed enums serialized as booleans (issue #1197) -* Fixed incorrect string comparison on some platforms (issue #1198) -* Added move-constructor and move-assignment to `BasicJsonDocument` -* Added `BasicJsonDocument::garbageCollect()` (issue #1195) -* Added `StaticJsonDocument::garbageCollect()` -* Changed copy-constructor of `BasicJsonDocument` to preserve the capacity of the source. -* Removed copy-constructor of `JsonDocument` (issue #1189) +* Remove `BasicJsonDocument` +* Remove `StaticJsonDocument` +* Add abstract `Allocator` class +* Merge `DynamicJsonDocument` with `JsonDocument` +* Remove `JSON_ARRAY_SIZE()`, `JSON_OBJECT_SIZE()`, and `JSON_STRING_SIZE()` +* Remove `ARDUINOJSON_ENABLE_STRING_DEDUPLICATION` (string deduplication cannot be disabled anymore) +* Remove `JsonDocument::capacity()` +* Store the strings in the heap +* Reference-count shared strings +* Always store `serialized("string")` by copy (#1915) +* Remove the zero-copy mode of `deserializeJson()` and `deserializeMsgPack()` +* Fix double lookup in `to()` +* Fix double call to `size()` in `serializeMsgPack()` +* Include `ARDUINOJSON_SLOT_OFFSET_SIZE` in the namespace name +* Remove `JsonVariant::shallowCopy()` +* `JsonDocument`'s capacity grows as needed, no need to pass it to the constructor anymore +* `JsonDocument`'s allocator is not monotonic anymore, removed values get recycled +* Show a link to the documentation when user passes an unsupported input type +* Remove `JsonDocument::memoryUsage()` +* Remove `JsonDocument::garbageCollect()` +* Add `deserializeJson(JsonVariant, ...)` and `deserializeMsgPack(JsonVariant, ...)` (#1226) +* Call `shrinkToFit()` in `deserializeJson()` and `deserializeMsgPack()` +* `serializeJson()` and `serializeMsgPack()` replace the content of `std::string` and `String` instead of appending to it +* Replace `add()` with `add()` (`add(T)` is still supported) +* Remove `createNestedArray()` and `createNestedObject()` (use `to()` and `to()` instead) > ### BREAKING CHANGES -> -> #### Copy-constructor of `BasicJsonDocument` -> -> In previous versions, the copy constructor of `BasicJsonDocument` looked at the source's `memoryUsage()` to choose its capacity. -> Now, the copy constructor of `BasicJsonDocument` uses the same capacity as the source. > -> Example: -> -> ```c++ -> DynamicJsonDocument doc1(64); -> doc1.set(String("example")); +> As every major release, ArduinoJson 7 introduces several breaking changes. +> I added some stubs so that most existing programs should compile, but I highty recommend you upgrade your code. > -> DynamicJsonDocument doc2 = doc1; -> Serial.print(doc2.capacity()); // 8 with ArduinoJson 6.14 -> // 64 with ArduinoJson 6.15 -> ``` -> -> I made this change to get consistent results between copy-constructor and move-constructor, and whether RVO applies or not. -> -> If you use the copy-constructor to optimize your documents, you can use `garbageCollect()` or `shrinkToFit()` instead. -> -> #### Copy-constructor of `JsonDocument` -> -> In previous versions, it was possible to create a function that take a `JsonDocument` by value. -> -> ```c++ -> void myFunction(JsonDocument doc) {} -> ``` -> -> This function gives the wrong clues because it doesn't receive a copy of the `JsonDocument`, only a sliced version. -> It worked because the copy constructor copied the internal pointers, but it was an accident. -> -> From now, if you need to pass a `JsonDocument` to a function, you must use a reference: -> -> ```c++ -> void myFunction(JsonDocument& doc) {} -> ``` - -v6.14.1 (2020-01-27) -------- - -* Fixed regression in UTF16 decoding (issue #1173) -* Fixed `containsKey()` on `JsonVariantConst` -* Added `getElement()` and `getMember()` to `JsonVariantConst` - -v6.14.0 (2020-01-16) -------- - -* Added `BasicJsonDocument::shrinkToFit()` -* Added support of `uint8_t` for `serializeJson()`, `serializeJsonPretty()`, and `serializeMsgPack()` (issue #1142) -* Added `ARDUINOJSON_ENABLE_COMMENTS` to enable support for comments (defaults to 0) -* Auto enable support for `std::string` and `std::stream` on modern compilers (issue #1156) - (No need to define `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_STD_STREAM` anymore) -* Improved decoding of UTF-16 surrogate pairs (PR #1157 by @kaysievers) - (ArduinoJson now produces standard UTF-8 instead of CESU-8) -* Added `measureJson`, `measureJsonPretty`, and `measureMsgPack` to `keywords.txt` - (This file is used for syntax highlighting in the Arduino IDE) -* Fixed `variant.is()` -* Fixed value returned by `serializeJson()`, `serializeJsonPretty()`, and `serializeMsgPack()` when writing to a `String` -* Improved speed of `serializeJson()`, `serializeJsonPretty()`, and `serializeMsgPack()` when writing to a `String` - -> ### BREAKING CHANGES -> -> #### Comments +> #### `JsonDocument` > -> Support for comments in input is now optional and disabled by default. +> In ArduinoJson 6, you could allocate the memory pool on the stack (with `StaticJsonDocument`) or in the heap (with `DynamicJsonDocument`). +> In ArduinoJson 7, the memory pool is always allocated in the heap, so `StaticJsonDocument` and `DynamicJsonDocument` have been merged into `JsonDocument`. > -> If you need support for comments, you must defined `ARDUINOJSON_ENABLE_COMMENTS` to `1`; otherwise, you'll receive `InvalidInput` errors. -> -> ```c++ -> #define ARDUINOJSON_ENABLE_COMMENTS 1 -> #include -> ``` - -v6.13.0 (2019-11-01) -------- - -* Added support for custom writer/reader classes (issue #1088) -* Added conversion from `JsonArray` and `JsonObject` to `bool`, to be consistent with `JsonVariant` -* Fixed `deserializeJson()` when input contains duplicate keys (issue #1095) -* Improved `deserializeMsgPack()` speed by reading several bytes at once -* Added detection of Atmel AVR8/GNU C Compiler (issue #1112) -* Fixed deserializer that stopped reading at the first `0xFF` (PR #1118 by @mikee47) -* Fixed dangling reference in copies of `MemberProxy` and `ElementProxy` (issue #1120) - -v6.12.0 (2019-09-05) -------- - -* Use absolute instead of relative includes (issue #1072) -* Changed `JsonVariant::as()` to return `true` for any non-null value (issue #1005) -* Moved ancillary files to `extras/` (issue #1011) - -v6.11.5 (2019-08-23) -------- - -* Added fallback implementations of `strlen_P()`, `strncmp_P()`, `strcmp_P()`, and `memcpy_P()` (issue #1073) - -v6.11.4 (2019-08-12) -------- - -* Added `measureJson()` to the `ArduinoJson` namespace (PR #1069 by @nomis) -* Added support for `basic_string` (issue #1045) -* Fixed example `JsonConfigFile.ino` for ESP8266 -* Include `Arduino.h` if `ARDUINO` is defined (PR #1071 by @nomis) - -v6.11.3 (2019-07-22) -------- - -* Added operators `==` and `!=` for `JsonDocument`, `ElementProxy`, and `MemberProxy` -* Fixed comparison of `JsonVariant` when one contains a linked string and the other contains an owned string (issue #1051) - -v6.11.2 (2019-07-08) -------- - -* Fixed assignment of `JsonDocument` to `JsonVariant` (issue #1023) -* Fix invalid conversion error on Particle Argon (issue #1035) - -v6.11.1 (2019-06-21) -------- - -* Fixed `serialized()` not working with Flash strings (issue #1030) - -v6.11.0 (2019-05-26) -------- - -* Fixed `deserializeJson()` silently accepting a `Stream*` (issue #978) -* Fixed invalid result from `operator|` (issue #981) -* Made `deserializeJson()` more picky about trailing characters (issue #980) -* Added `ARDUINOJSON_ENABLE_NAN` (default=0) to enable NaN in JSON (issue #973) -* Added `ARDUINOJSON_ENABLE_INFINITY` (default=0) to enable Infinity in JSON -* Removed implicit conversion in comparison operators (issue #998) -* Added lexicographical comparison for `JsonVariant` -* Added support for `nullptr` (issue #998) - -> ### BREAKING CHANGES -> -> #### NaN and Infinity -> -> The JSON specification allows neither NaN not Infinity, but previous -> versions of ArduinoJson supported it. Now, ArduinoJson behaves like most -> other libraries: a NaN or and Infinity in the `JsonDocument`, becomes -> a `null` in the output JSON. Also, `deserializeJson()` returns -> `InvalidInput` if the JSON document contains NaN or Infinity. -> -> This version still supports NaN and Infinity in JSON documents, but -> it's disabled by default to be compatible with other JSON parsers. -> If you need the old behavior back, define `ARDUINOJSON_ENABLE_NAN` and -> `ARDUINOJSON_ENABLE_INFINITY` to `1`;: -> -> ```c++ -> #define ARDUINOJSON_ENABLE_NAN 1 -> #define ARDUINOJSON_ENABLE_INFINITY 1 -> #include -> ``` -> -> #### The "or" operator -> -> This version slightly changes the behavior of the | operator when the -> variant contains a float and the user requests an integer. +> In ArduinoJson 6, `JsonDocument` had a fixed capacity; in ArduinoJson 7, it has an elastic capacity that grows as needed. +> Therefore, you don't need to specify the capacity anymore, so the macros `JSON_ARRAY_SIZE()`, `JSON_OBJECT_SIZE()`, and `JSON_STRING_SIZE()` have been removed. > -> Older versions returned the floating point value truncated. -> Now, it returns the default value. -> > ```c++ -> // suppose variant contains 1.2 -> int value = variant | 3; -> -> // old behavior: -> value == 1 -> -> // new behavior -> value == 3 -> ``` -> -> If you need the old behavior, you must add `if (variant.is())`. - -v6.10.1 (2019-04-23) -------- - -* Fixed error "attributes are not allowed on a function-definition" -* Fixed `deserializeJson()` not being picky enough (issue #969) -* Fixed error "no matching function for call to write(uint8_t)" (issue #972) - -v6.10.0 (2019-03-22) -------- - -* Fixed an integer overflow in the JSON deserializer -* Added overflow handling in `JsonVariant::as()` and `JsonVariant::is()`. - - `as()` returns `0` if the integer `T` overflows - - `is()` returns `false` if the integer `T` overflows -* Added `BasicJsonDocument` to support custom allocator (issue #876) -* Added `JsonDocument::containsKey()` (issue #938) -* Added `JsonVariant::containsKey()` - -v6.9.1 (2019-03-01) ------- - -* Fixed warning "unused variable" with GCC 4.4 (issue #912) -* Fixed warning "cast increases required alignment" (issue #914) -* Fixed warning "conversion may alter value" (issue #914) -* Fixed naming conflict with "CAPACITY" (issue #839) -* Muted warning "will change in GCC 7.1" (issue #914) -* Added a clear error message for `StaticJsonBuffer` and `DynamicJsonBuffer` -* Marked ArduinoJson.h as a "system header" - -v6.9.0 (2019-02-26) ------- - -* Decode escaped Unicode characters like \u00DE (issue #304, PR #791) - Many thanks to Daniel Schulte (aka @trilader) who implemented this feature. -* Added option ARDUINOJSON_DECODE_UNICODE to enable it -* Converted `JsonArray::copyFrom()/copyTo()` to free functions `copyArray()` -* Renamed `JsonArray::copyFrom()` and `JsonObject::copyFrom()` to `set()` -* Renamed `JsonArray::get()` to `getElement()` -* Renamed `JsonArray::add()` (without arg) to `addElement()` -* Renamed `JsonObject::get()` to `getMember()` -* Renamed `JsonObject::getOrCreate()` to `getOrAddMember()` -* Fixed `JsonVariant::isNull()` not returning `true` after `set((char*)0)` -* Fixed segfault after `variant.set(serialized((char*)0))` -* Detect `IncompleteInput` in `false`, `true`, and `null` -* Added `JsonDocument::size()` -* Added `JsonDocument::remove()` -* Added `JsonVariant::clear()` -* Added `JsonVariant::remove()` - -v6.8.0-beta (2019-01-30) ------------ - -* Import functions in the ArduinoJson namespace to get clearer errors -* Improved syntax highlighting in Arduino IDE -* Removed default capacity of `DynamicJsonDocument` -* `JsonArray::copyFrom()` accepts `JsonArrayConst` -* `JsonVariant::set()` accepts `JsonArrayConst` and `JsonObjectConst` -* `JsonDocument` was missing in the ArduinoJson namespace -* Added `memoryUsage()` to `JsonArray`, `JsonObject`, and `JsonVariant` -* Added `nesting()` to `JsonArray`, `JsonDocument`, `JsonObject`, and `JsonVariant` -* Replaced `JsonDocument::nestingLimit` with an additional parameter - to `deserializeJson()` and `deserializeMsgPack()` -* Fixed uninitialized variant in `JsonDocument` -* Fixed `StaticJsonDocument` copy constructor and copy assignment -* The copy constructor of `DynamicJsonDocument` chooses the capacity according to the memory usage of the source, not from the capacity of the source. -* Added the ability to create/assign a `StaticJsonDocument`/`DynamicJsonDocument` from a `JsonArray`/`JsonObject`/`JsonVariant` -* Added `JsonDocument::isNull()` -* Added `JsonDocument::operator[]` -* Added `ARDUINOJSON_TAB` to configure the indentation character -* Reduced the size of the pretty JSON serializer -* Added `add()`, `createNestedArray()` and `createNestedObject()` to `JsonVariant` -* `JsonVariant` automatically promotes to `JsonObject` or `JsonArray` on write. - Calling `JsonVariant::to()` is not required anymore. -* `JsonDocument` now support the same operations as `JsonVariant`. - Calling `JsonDocument::as()` is not required anymore. -* Fixed example `JsonHttpClient.ino` -* User can now use a `JsonString` as a key or a value - -> ### BREAKING CHANGES -> -> #### `DynamicJsonDocument`'s constructor +> // ArduinoJson 6 +> StaticJsonDocument<256> doc; +> // or +> DynamicJsonDocument doc(256); > -> The parameter to the constructor of `DynamicJsonDocument` is now mandatory -> -> Old code: -> -> ```c++ -> DynamicJsonDocument doc; +> // ArduinoJson 7 +> JsonDocument doc; > ``` > -> New code: +> In ArduinoJson 7, `JsonDocument` reuses released memory, so `garbageCollect()` has been removed. +> `shrinkToFit()` is still available and releases the over-allocated memory. > -> ```c++ -> DynamicJsonDocument doc(1024); -> ``` -> -> #### Nesting limit -> -> `JsonDocument::nestingLimit` was replaced with a new parameter to `deserializeJson()` and `deserializeMsgPack()`. -> -> Old code: -> -> ```c++ -> doc.nestingLimit = 15; -> deserializeJson(doc, input); -> ``` -> -> New code: +> Due to a change in the implementation, it's not possible to store a pointer to a variant from another `JsonDocument`, so `shallowCopy()` has been removed. > -> ```c++ -> deserializeJson(doc, input, DeserializationOption::NestingLimit(15)); -> ``` - -v6.7.0-beta (2018-12-07) ------------ - -* Removed the automatic expansion of `DynamicJsonDocument`, it now has a fixed capacity. -* Restored the monotonic allocator because the code was getting too big -* Reduced the memory usage -* Reduced the code size -* Renamed `JsonKey` to `JsonString` -* Removed spurious files in the Particle library - -v6.6.0-beta (2018-11-13) ------------ - -* Removed `JsonArray::is(i)` and `JsonArray::set(i,v)` -* Removed `JsonObject::is(k)` and `JsonObject::set(k,v)` -* Replaced `T JsonArray::get(i)` with `JsonVariant JsonArray::get(i)` -* Replaced `T JsonObject::get(k)` with `JsonVariant JsonObject::get(k)` -* Added `JSON_STRING_SIZE()` -* ~~Replacing or removing a value now releases the memory~~ -* Added `DeserializationError::code()` to be used in switch statements (issue #846) - -v6.5.0-beta (2018-10-13) ------------ - -* Added implicit conversion from `JsonArray` and `JsonObject` to `JsonVariant` -* Allow mixed configuration in compilation units (issue #809) -* Fixed object keys not being duplicated -* `JsonPair::key()` now returns a `JsonKey` -* Increased the default capacity of `DynamicJsonDocument` -* Fixed `JsonVariant::is()` (closes #763) -* Added `JsonArrayConst`, `JsonObjectConst`, and `JsonVariantConst` -* Added copy-constructor and copy-assignment-operator for `JsonDocument` (issue #827) - -v6.4.0-beta (2018-09-11) ------------ - -* Copy `JsonArray` and `JsonObject`, instead of storing pointers (issue #780) -* Added `JsonVariant::to()` and `JsonVariant::to()` - -v6.3.0-beta (2018-08-31) ------------ - -* Implemented reference semantics for `JsonVariant` -* Replaced `JsonPair`'s `key` and `value` with `key()` and `value()` -* Fixed `serializeJson(obj[key], dst)` (issue #794) - -> ### BREAKING CHANGES +> In ArduinoJson 6, the meaning of `memoryUsage()` was clear: it returned the number of bytes used in the memory pool. +> In ArduinoJson 7, the meaning of `memoryUsage()` would be ambiguous, so it has been removed. > -> #### JsonVariant -> -> `JsonVariant` now has a semantic similar to `JsonObject` and `JsonArray`. -> It's a reference to a value stored in the `JsonDocument`. -> As a consequence, a `JsonVariant` cannot be used as a standalone variable anymore. +> #### Custom allocators > -> Old code: +> In ArduinoJson 6, you could specify a custom allocator class as a template parameter of `BasicJsonDocument`. +> In ArduinoJson 7, you must inherit from `ArduinoJson::Allocator` and pass a pointer to an instance of your class to the constructor of `JsonDocument`. > > ```c++ -> JsonVariant myValue = 42; -> ``` +> // ArduinoJson 6 +> class MyAllocator { +> // ... +> }; +> BasicJsonDocument doc(256); > -> New code: -> -> ```c++ -> DynamicJsonDocument doc; -> JsonVariant myValue = doc.to(); -> myValue.set(42); +> // ArduinoJson 7 +> class MyAllocator : public ArduinoJson::Allocator { +> // ... +> }; +> MyAllocator myAllocator; +> JsonDocument doc(&myAllocator); > ``` > -> #### JsonPair +> #### `createNestedArray()` and `createNestedObject()` > -> Old code: +> In ArduinoJson 6, you could create a nested array or object with `createNestedArray()` and `createNestedObject()`. +> In ArduinoJson 7, you must use `add()` or `to()` instead. > -> ```c++ -> for(JsonPair p : myObject) { -> Serial.println(p.key); -> Serial.println(p.value.as()); -> } -> ``` -> -> New code: +> For example, to create `[[],{}]`, you would write: > > ```c++ -> for(JsonPair p : myObject) { -> Serial.println(p.key()); -> Serial.println(p.value().as()); -> } -> ``` -> -> CAUTION: the key is now read only! - -v6.2.3-beta (2018-07-19) ------------ - -* Fixed exception when using Flash strings as object keys (issue #784) - -v6.2.2-beta (2018-07-18) ------------ - -* Fixed `invalid application of 'sizeof' to incomplete type '__FlashStringHelper'` (issue #783) -* Fixed `char[]` not duplicated when passed to `JsonVariant::operator[]` - -v6.2.1-beta (2018-07-17) ------------ - -* Fixed `JsonObject` not inserting keys of type `String` (issue #782) - -v6.2.0-beta (2018-07-12) ------------ - -* Disabled lazy number deserialization (issue #772) -* Fixed `JsonVariant::is()` that returned true for empty strings -* Improved float serialization when `-fsingle-precision-constant` is used -* Renamed function `RawJson()` to `serialized()` -* `serializeMsgPack()` now supports values marked with `serialized()` - -> ### BREAKING CHANGES -> -> #### Non quoted strings +> // ArduinoJson 6 +> arr.createNestedArray(); +> arr.createNestedObject(); > -> Non quoted strings are now forbidden in values, but they are still allowed in keys. -> For example, `{key:"value"}` is accepted, but `{key:value}` is not. -> -> #### Preformatted values +> // ArduinoJson 7 +> arr.add(); +> arr.add(); +> ``` > -> Old code: +> And to create `{"array":[],"object":{}}`, you would write: > > ```c++ -> object["values"] = RawJson("[1,2,3,4]"); -> ``` -> -> New code: -> -> ```c++ -> object["values"] = serialized("[1,2,3,4]"); -> ``` - -v6.1.0-beta (2018-07-02) ------------ - -* Return `JsonArray` and `JsonObject` by value instead of reference (issue #309) -* Replaced `success()` with `isNull()` - -> ### BREAKING CHANGES -> -> Old code: +> // ArduinoJson 6 +> obj.createNestedArray("array"); +> obj.createNestedObject("object"); > -> ```c++ -> JsonObject& obj = doc.to(); -> JsonArray& arr = obj.createNestedArray("key"); -> if (!arr.success()) { -> Serial.println("Not enough memory"); -> return; -> } -> ``` -> -> New code: -> -> ```c++ -> JsonObject obj = doc.to(); -> JsonArray arr = obj.createNestedArray("key"); -> if (arr.isNull()) { -> Serial.println("Not enough memory"); -> return; -> } -> ``` - -v6.0.1-beta (2018-06-11) ------------ - -* Fixed conflicts with `isnan()` and `isinf()` macros (issue #752) - -v6.0.0-beta (2018-06-07) ------------ - -* Added `DynamicJsonDocument` and `StaticJsonDocument` -* Added `deserializeJson()` -* Added `serializeJson()` and `serializeJsonPretty()` -* Added `measureJson()` and `measureJsonPretty()` -* Added `serializeMsgPack()`, `deserializeMsgPack()` and `measureMsgPack()` (issue #358) -* Added example `MsgPackParser.ino` (issue #358) -* Added support for non zero-terminated strings (issue #704) -* Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` -* Removed `JsonBuffer::createArray()` and `createObject()` -* Removed `printTo()` and `prettyPrintTo()` -* Removed `measureLength()` and `measurePrettyLength()` -* Removed all deprecated features - -> ### BREAKING CHANGES -> -> #### Deserialization -> -> Old code: -> -> ```c++ -> DynamicJsonBuffer jb; -> JsonObject& obj = jb.parseObject(json); -> if (obj.success()) { -> -> } -> ``` -> -> New code: -> -> ```c++ -> DynamicJsonDocument doc; -> DeserializationError error = deserializeJson(doc, json); -> if (error) { -> -> } -> JsonObject& obj = doc.as(); -> ``` -> -> #### Serialization -> -> Old code: -> -> ```c++ -> DynamicJsonBuffer jb; -> JsonObject& obj = jb.createObject(); -> obj["key"] = "value"; -> obj.printTo(Serial); -> ``` -> -> New code: -> -> ```c++ -> DynamicJsonDocument obj; -> JsonObject& obj = doc.to(); -> obj["key"] = "value"; -> serializeJson(doc, Serial); +> // ArduinoJson 7 +> obj["array"].to(); +> obj["object"].to(); > ``` diff --git a/third-party/ArduinoJson/CMakeLists.txt b/third-party/ArduinoJson/CMakeLists.txt index a79bc66..169cff1 100644 --- a/third-party/ArduinoJson/CMakeLists.txt +++ b/third-party/ArduinoJson/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License cmake_minimum_required(VERSION 3.15) @@ -10,7 +10,7 @@ if(ESP_PLATFORM) return() endif() -project(ArduinoJson VERSION 6.21.3) +project(ArduinoJson VERSION 7.0.3) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) include(CTest) diff --git a/third-party/ArduinoJson/LICENSE.txt b/third-party/ArduinoJson/LICENSE.txt index 15f1b9f..56bb92b 100644 --- a/third-party/ArduinoJson/LICENSE.txt +++ b/third-party/ArduinoJson/LICENSE.txt @@ -1,7 +1,7 @@ The MIT License (MIT) --------------------- -Copyright © 2014-2023, Benoit BLANCHON +Copyright © 2014-2024, Benoit BLANCHON Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/third-party/ArduinoJson/README.md b/third-party/ArduinoJson/README.md index 16d93a3..2900240 100644 --- a/third-party/ArduinoJson/README.md +++ b/third-party/ArduinoJson/README.md @@ -4,13 +4,10 @@ --- -[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bblanchon/ArduinoJson/ci.yml?branch=6.x&logo=github)](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x) -[![Continuous Integration](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x) +[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bblanchon/ArduinoJson/ci.yml?branch=7.x&logo=github)](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A7.x) +[![Continuous Integration](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/7.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/7.x) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/arduinojson.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson) -[![Coveralls branch](https://img.shields.io/coveralls/github/bblanchon/ArduinoJson/6.x?logo=coveralls)](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x) -[![Arduino Library Manager](https://img.shields.io/static/v1?label=Arduino&message=v6.21.3&logo=arduino&logoColor=white&color=blue)](https://www.ardu-badge.com/ArduinoJson/6.21.3) -[![PlatformIO Registry](https://badges.registry.platformio.org/packages/bblanchon/library/ArduinoJson.svg?version=6.21.3)](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.21.3) -[![ESP IDF](https://img.shields.io/static/v1?label=ESP+IDF&message=v6.21.3&logo=cpu&logoColor=white&color=blue)](https://components.espressif.com/components/bblanchon/arduinojson) +[![Coveralls branch](https://img.shields.io/coveralls/github/bblanchon/ArduinoJson/7.x?logo=coveralls)](https://coveralls.io/github/bblanchon/ArduinoJson?branch=7.x) [![GitHub stars](https://img.shields.io/github/stars/bblanchon/ArduinoJson?style=flat&logo=github&color=orange)](https://github.com/bblanchon/ArduinoJson/stargazers) [![GitHub Sponsors](https://img.shields.io/github/sponsors/bblanchon?logo=github&color=orange)](https://github.com/sponsors/bblanchon) @@ -18,31 +15,28 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things). ## Features -* [JSON deserialization](https://arduinojson.org/v6/api/json/deserializejson/) - * [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v6/api/config/decode_unicode/) - * [Optionally stores links to the input buffer (zero-copy)](https://arduinojson.org/v6/api/json/deserializejson/) - * [Optionally supports comments in the input](https://arduinojson.org/v6/api/config/enable_comments/) - * [Optionally filters the input to keep only desired values](https://arduinojson.org/v6/api/json/deserializejson/#filtering) +* [JSON deserialization](https://arduinojson.org/v7/api/json/deserializejson/) + * [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v7/api/config/decode_unicode/) + * [Optionally supports comments in the input](https://arduinojson.org/v7/api/config/enable_comments/) + * [Optionally filters the input to keep only desired values](https://arduinojson.org/v7/api/json/deserializejson/#filtering) * Supports single quotes as a string delimiter * Compatible with [NDJSON](http://ndjson.org/) and [JSON Lines](https://jsonlines.org/) -* [JSON serialization](https://arduinojson.org/v6/api/json/serializejson/) - * [Can write to a buffer or a stream](https://arduinojson.org/v6/api/json/serializejson/) - * [Optionally indents the document (prettified JSON)](https://arduinojson.org/v6/api/json/serializejsonpretty/) -* [MessagePack serialization](https://arduinojson.org/v6/api/msgpack/serializemsgpack/) -* [MessagePack deserialization](https://arduinojson.org/v6/api/msgpack/deserializemsgpack/) +* [JSON serialization](https://arduinojson.org/v7/api/json/serializejson/) + * [Can write to a buffer or a stream](https://arduinojson.org/v7/api/json/serializejson/) + * [Optionally indents the document (prettified JSON)](https://arduinojson.org/v7/api/json/serializejsonpretty/) +* [MessagePack serialization](https://arduinojson.org/v7/api/msgpack/serializemsgpack/) +* [MessagePack deserialization](https://arduinojson.org/v7/api/msgpack/deserializemsgpack/) * Efficient * [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/) * [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/) * [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/) - * [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/) - * [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/) * [Deduplicates strings](https://arduinojson.org/news/2020/08/01/version-6-16-0/) * Versatile - * Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/) - * Supports [`String`](https://arduinojson.org/v6/api/config/enable_arduino_string/), [`std::string`](https://arduinojson.org/v6/api/config/enable_std_string/), and [`std::string_view`](https://arduinojson.org/v6/api/config/enable_string_view/) - * Supports [`Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/) and [`std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/) - * Supports [Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/) - * Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/#custom-writer) + * Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v7/how-to/use-external-ram-on-esp32/) + * Supports [`String`](https://arduinojson.org/v7/api/config/enable_arduino_string/), [`std::string`](https://arduinojson.org/v7/api/config/enable_std_string/), and [`std::string_view`](https://arduinojson.org/v7/api/config/enable_string_view/) + * Supports [`Stream`](https://arduinojson.org/v7/api/config/enable_arduino_stream/) and [`std::istream`/`std::ostream`](https://arduinojson.org/v7/api/config/enable_std_stream/) + * Supports [Flash strings](https://arduinojson.org/v7/api/config/enable_progmem/) + * Supports [custom readers](https://arduinojson.org/v7/api/json/deserializejson/#custom-reader) and [custom writers](https://arduinojson.org/v7/api/json/serializejson/#custom-writer) * Supports [custom converters](https://arduinojson.org/news/2021/05/04/version-6-18-0/) * Portable * Usable on any C++ project (not limited to Arduino) @@ -72,29 +66,29 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things). * [Visual Micro](http://www.visualmicro.com/) * [Visual Studio](https://www.visualstudio.com/) * [Even works with online compilers like wandbox.org](https://wandbox.org/permlink/RlZSKy17DjJ6HcdN) - * [CMake friendly](https://arduinojson.org/v6/how-to/use-arduinojson-with-cmake/) + * [CMake friendly](https://arduinojson.org/v7/how-to/use-arduinojson-with-cmake/) * Well designed - * [Elegant API](http://arduinojson.org/v6/example/) + * [Elegant API](http://arduinojson.org/v7/example/) * [Thread-safe](https://en.wikipedia.org/wiki/Thread_safety) * Self-contained (no external dependency) * `const` friendly - * [`for` friendly](https://arduinojson.org/v6/api/jsonobject/begin_end/) + * [`for` friendly](https://arduinojson.org/v7/api/jsonobject/begin_end/) * [TMP friendly](https://en.wikipedia.org/wiki/Template_metaprogramming) - * Handles [integer overflows](https://arduinojson.org/v6/api/jsonvariant/as/#integer-overflows) + * Handles [integer overflows](https://arduinojson.org/v7/api/jsonvariant/as/#integer-overflows) * Well tested - * [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x) + * [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=7.x) * Continuously tested on - * [Visual Studio 2017, 2019, 2022](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x) - * [GCC 5, 6, 7, 8, 9, 10, 11](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22) - * [Clang 3.8, 3.9, 4.0, 5.0, 6.0, 7, 8, 9, 10](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22) + * [Visual Studio 2017, 2019, 2022](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/7.x) + * [GCC 4.8, 5, 6, 7, 8, 9, 10, 11, 12](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22) + * [Clang 3.9, 4.0, 5.0, 6.0, 7, 8, 9, 10, 11, 12, 13, 14, 15](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22) * [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson) * Passes all default checks of [clang-tidy](https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clang-tidy/) * Well documented - * [Tutorials](https://arduinojson.org/v6/doc/deserialization/) - * [Examples](https://arduinojson.org/v6/example/) - * [How-tos](https://arduinojson.org/v6/example/) - * [FAQ](https://arduinojson.org/v6/faq/) - * [Troubleshooter](https://arduinojson.org/v6/troubleshooter/) + * [Tutorials](https://arduinojson.org/v7/doc/deserialization/) + * [Examples](https://arduinojson.org/v7/example/) + * [How-tos](https://arduinojson.org/v7/example/) + * [FAQ](https://arduinojson.org/v7/faq/) + * [Troubleshooter](https://arduinojson.org/v7/troubleshooter/) * [Book](https://arduinojson.org/book/) * [Changelog](CHANGELOG.md) * Vibrant user community @@ -109,9 +103,9 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things). Here is a program that parses a JSON document with ArduinoJson. ```c++ -char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; +const char* json = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; -DynamicJsonDocument doc(1024); +JsonDocument doc; deserializeJson(doc, json); const char* sensor = doc["sensor"]; @@ -120,14 +114,14 @@ double latitude = doc["data"][0]; double longitude = doc["data"][1]; ``` -See the [tutorial on arduinojson.org](https://arduinojson.org/v6/doc/deserialization/) +See the [tutorial on arduinojson.org](https://arduinojson.org/v7/doc/deserialization/) ### Serialization Here is a program that generates a JSON document with ArduinoJson: ```c++ -DynamicJsonDocument doc(1024); +JsonDocument doc; doc["sensor"] = "gps"; doc["time"] = 1351824120; @@ -139,7 +133,7 @@ serializeJson(doc, Serial); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} ``` -See the [tutorial on arduinojson.org](https://arduinojson.org/v6/doc/serialization/) +See the [tutorial on arduinojson.org](https://arduinojson.org/v7/doc/serialization/) ## Sponsors diff --git a/third-party/ArduinoJson/appveyor.yml b/third-party/ArduinoJson/appveyor.yml index 4a9789b..d8ff69d 100644 --- a/third-party/ArduinoJson/appveyor.yml +++ b/third-party/ArduinoJson/appveyor.yml @@ -1,4 +1,4 @@ -version: 6.21.3.{build} +version: 7.0.3.{build} environment: matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 diff --git a/third-party/ArduinoJson/examples/JsonConfigFile/JsonConfigFile.ino b/third-party/ArduinoJson/examples/JsonConfigFile/JsonConfigFile.ino index b2819d5..cd94064 100644 --- a/third-party/ArduinoJson/examples/JsonConfigFile/JsonConfigFile.ino +++ b/third-party/ArduinoJson/examples/JsonConfigFile/JsonConfigFile.ino @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to store your project configuration in a file. @@ -17,35 +17,28 @@ // * CLK <-> pin 13 // * CS <-> pin 4 // -// https://arduinojson.org/v6/example/config/ +// https://arduinojson.org/v7/example/config/ #include #include #include // Our configuration structure. -// -// Never use a JsonDocument to store the configuration! -// A JsonDocument is *not* a permanent storage; it's only a temporary storage -// used during the serialization phase. See: -// https://arduinojson.org/v6/faq/why-must-i-create-a-separate-config-object/ struct Config { char hostname[64]; int port; }; -const char *filename = "/config.txt"; // <- SD library uses 8.3 filenames +const char* filename = "/config.txt"; // <- SD library uses 8.3 filenames Config config; // <- global configuration object // Loads the configuration from a file -void loadConfiguration(const char *filename, Config &config) { +void loadConfiguration(const char* filename, Config& config) { // Open file for reading File file = SD.open(filename); // Allocate a temporary JsonDocument - // Don't forget to change the capacity to match your requirements. - // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<512> doc; + JsonDocument doc; // Deserialize the JSON document DeserializationError error = deserializeJson(doc, file); @@ -63,7 +56,7 @@ void loadConfiguration(const char *filename, Config &config) { } // Saves the configuration to a file -void saveConfiguration(const char *filename, const Config &config) { +void saveConfiguration(const char* filename, const Config& config) { // Delete existing file, otherwise the configuration is appended to the file SD.remove(filename); @@ -75,9 +68,7 @@ void saveConfiguration(const char *filename, const Config &config) { } // Allocate a temporary JsonDocument - // Don't forget to change the capacity to match your requirements. - // Use https://arduinojson.org/assistant to compute the capacity. - StaticJsonDocument<256> doc; + JsonDocument doc; // Set the values in the document doc["hostname"] = config.hostname; @@ -93,7 +84,7 @@ void saveConfiguration(const char *filename, const Config &config) { } // Prints the content of a file to the Serial -void printFile(const char *filename) { +void printFile(const char* filename) { // Open file for reading File file = SD.open(filename); if (!file) { @@ -114,7 +105,8 @@ void printFile(const char *filename) { void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Initialize SD library const int chipSelect = 4; @@ -144,7 +136,7 @@ void loop() { // ------------------ // // File is an unbuffered stream, which is not optimal for ArduinoJson. -// See: https://arduinojson.org/v6/how-to/improve-speed/ +// See: https://arduinojson.org/v7/how-to/improve-speed/ // See also // -------- diff --git a/third-party/ArduinoJson/examples/JsonFilterExample/JsonFilterExample.ino b/third-party/ArduinoJson/examples/JsonFilterExample/JsonFilterExample.ino index 6937a00..1c20fe9 100644 --- a/third-party/ArduinoJson/examples/JsonFilterExample/JsonFilterExample.ino +++ b/third-party/ArduinoJson/examples/JsonFilterExample/JsonFilterExample.ino @@ -1,17 +1,18 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to use DeserializationOption::Filter // -// https://arduinojson.org/v6/example/filter/ +// https://arduinojson.org/v7/example/filter/ #include void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // The huge input: an extract from OpenWeatherMap response auto input_json = F( @@ -33,12 +34,12 @@ void setup() { "1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}"); // The filter: it contains "true" for each value we want to keep - StaticJsonDocument<200> filter; + JsonDocument filter; filter["list"][0]["dt"] = true; filter["list"][0]["main"]["temp"] = true; // Deserialize the document - StaticJsonDocument<400> doc; + JsonDocument doc; deserializeJson(doc, input_json, DeserializationOption::Filter(filter)); // Print the result diff --git a/third-party/ArduinoJson/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/third-party/ArduinoJson/examples/JsonGeneratorExample/JsonGeneratorExample.ino index cf4ab0d..d67b885 100644 --- a/third-party/ArduinoJson/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/third-party/ArduinoJson/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -1,43 +1,32 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to generate a JSON document with ArduinoJson. // -// https://arduinojson.org/v6/example/generator/ +// https://arduinojson.org/v7/example/generator/ #include void setup() { // Initialize Serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Allocate the JSON document - // - // Inside the brackets, 200 is the RAM allocated to this document. - // Don't forget to change this value to match your requirement. - // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<200> doc; - - // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonDocument which allocates in the heap. - // - // DynamicJsonDocument doc(200); + JsonDocument doc; // Add values in the document - // doc["sensor"] = "gps"; doc["time"] = 1351824120; - // Add an array. - // - JsonArray data = doc.createNestedArray("data"); + // Add an array + JsonArray data = doc["data"].to(); data.add(48.756080); data.add(2.302038); - // Generate the minified JSON and send it to the Serial port. - // + // Generate the minified JSON and send it to the Serial port serializeJson(doc, Serial); // The above line prints: // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} @@ -45,8 +34,7 @@ void setup() { // Start a new line Serial.println(); - // Generate the prettified JSON and send it to the Serial port. - // + // Generate the prettified JSON and send it to the Serial port serializeJsonPretty(doc, Serial); // The above line prints: // { diff --git a/third-party/ArduinoJson/examples/JsonHttpClient/JsonHttpClient.ino b/third-party/ArduinoJson/examples/JsonHttpClient/JsonHttpClient.ino index 72f311f..9315118 100644 --- a/third-party/ArduinoJson/examples/JsonHttpClient/JsonHttpClient.ino +++ b/third-party/ArduinoJson/examples/JsonHttpClient/JsonHttpClient.ino @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to parse a JSON document in an HTTP response. @@ -16,7 +16,7 @@ // ] // } // -// https://arduinojson.org/v6/example/http-client/ +// https://arduinojson.org/v7/example/http-client/ #include #include @@ -25,7 +25,8 @@ void setup() { // Initialize Serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Initialize Ethernet library byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; @@ -77,9 +78,7 @@ void setup() { } // Allocate the JSON document - // Use https://arduinojson.org/v6/assistant to compute the capacity. - const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; - DynamicJsonDocument doc(capacity); + JsonDocument doc; // Parse JSON object DeserializationError error = deserializeJson(doc, client); @@ -109,7 +108,7 @@ void loop() { // ------------------ // // EthernetClient is an unbuffered stream, which is not optimal for ArduinoJson. -// See: https://arduinojson.org/v6/how-to/improve-speed/ +// See: https://arduinojson.org/v7/how-to/improve-speed/ // See also // -------- diff --git a/third-party/ArduinoJson/examples/JsonParserExample/JsonParserExample.ino b/third-party/ArduinoJson/examples/JsonParserExample/JsonParserExample.ino index a9d8b6d..7220dcf 100644 --- a/third-party/ArduinoJson/examples/JsonParserExample/JsonParserExample.ino +++ b/third-party/ArduinoJson/examples/JsonParserExample/JsonParserExample.ino @@ -1,52 +1,37 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to deserialize a JSON document with ArduinoJson. // -// https://arduinojson.org/v6/example/parser/ +// https://arduinojson.org/v7/example/parser/ #include void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Allocate the JSON document - // - // Inside the brackets, 200 is the capacity of the memory pool in bytes. - // Don't forget to change this value to match your JSON document. - // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<200> doc; - - // StaticJsonDocument allocates memory on the stack, it can be - // replaced by DynamicJsonDocument which allocates in the heap. - // - // DynamicJsonDocument doc(200); + JsonDocument doc; // JSON input string. - // - // Using a char[], as shown here, enables the "zero-copy" mode. This mode uses - // the minimal amount of memory because the JsonDocument stores pointers to - // the input buffer. - // If you use another type of input, ArduinoJson must copy the strings from - // the input to the JsonDocument, so you need to increase the capacity of the - // JsonDocument. - char json[] = + const char* json = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; // Deserialize the JSON document DeserializationError error = deserializeJson(doc, json); - // Test if parsing succeeds. + // Test if parsing succeeds if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; } - // Fetch values. + // Fetch the values // // Most of the time, you can rely on the implicit casts. // In other case, you can do doc["time"].as(); @@ -55,7 +40,7 @@ void setup() { double latitude = doc["data"][0]; double longitude = doc["data"][1]; - // Print values. + // Print the values Serial.println(sensor); Serial.println(time); Serial.println(latitude, 6); diff --git a/third-party/ArduinoJson/examples/JsonServer/JsonServer.ino b/third-party/ArduinoJson/examples/JsonServer/JsonServer.ino index a897fce..d8b65c8 100644 --- a/third-party/ArduinoJson/examples/JsonServer/JsonServer.ino +++ b/third-party/ArduinoJson/examples/JsonServer/JsonServer.ino @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to implement an HTTP server that sends a JSON document @@ -13,7 +13,7 @@ // "digital": [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0] // } // -// https://arduinojson.org/v6/example/http-server/ +// https://arduinojson.org/v7/example/http-server/ #include #include @@ -25,7 +25,8 @@ EthernetServer server(80); void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Initialize Ethernet libary if (!Ethernet.begin(mac)) { @@ -52,14 +53,14 @@ void loop() { Serial.println(F("New client")); // Read the request (we ignore the content in this example) - while (client.available()) client.read(); + while (client.available()) + client.read(); // Allocate a temporary JsonDocument - // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<500> doc; + JsonDocument doc; // Create the "analog" array - JsonArray analogValues = doc.createNestedArray("analog"); + JsonArray analogValues = doc["analog"].to(); for (int pin = 0; pin < 6; pin++) { // Read the analog input int value = analogRead(pin); @@ -69,7 +70,7 @@ void loop() { } // Create the "digital" array - JsonArray digitalValues = doc.createNestedArray("digital"); + JsonArray digitalValues = doc["digital"].to(); for (int pin = 0; pin < 14; pin++) { // Read the digital input int value = digitalRead(pin); @@ -101,7 +102,7 @@ void loop() { // ------------------ // // EthernetClient is an unbuffered stream, which is not optimal for ArduinoJson. -// See: https://arduinojson.org/v6/how-to/improve-speed/ +// See: https://arduinojson.org/v7/how-to/improve-speed/ // See also // -------- diff --git a/third-party/ArduinoJson/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/third-party/ArduinoJson/examples/JsonUdpBeacon/JsonUdpBeacon.ino index 6c369fa..6a4e08f 100644 --- a/third-party/ArduinoJson/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/third-party/ArduinoJson/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to send a JSON document to a UDP socket. @@ -17,7 +17,7 @@ // $ ncat -ulp 8888 // See https://nmap.org/ncat/ // -// https://arduinojson.org/v6/example/udp-beacon/ +// https://arduinojson.org/v7/example/udp-beacon/ #include #include @@ -32,7 +32,8 @@ EthernetUDP udp; void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Initialize Ethernet libary if (!Ethernet.begin(mac)) { @@ -46,11 +47,10 @@ void setup() { void loop() { // Allocate a temporary JsonDocument - // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<500> doc; + JsonDocument doc; // Create the "analog" array - JsonArray analogValues = doc.createNestedArray("analog"); + JsonArray analogValues = doc["analog"].to(); for (int pin = 0; pin < 6; pin++) { // Read the analog input int value = analogRead(pin); @@ -60,7 +60,7 @@ void loop() { } // Create the "digital" array - JsonArray digitalValues = doc.createNestedArray("digital"); + JsonArray digitalValues = doc["digital"].to(); for (int pin = 0; pin < 14; pin++) { // Read the digital input int value = digitalRead(pin); @@ -90,7 +90,7 @@ void loop() { // ------------------ // // EthernetUDP is an unbuffered stream, which is not optimal for ArduinoJson. -// See: https://arduinojson.org/v6/how-to/improve-speed/ +// See: https://arduinojson.org/v7/how-to/improve-speed/ // See also // -------- diff --git a/third-party/ArduinoJson/examples/MsgPackParser/MsgPackParser.ino b/third-party/ArduinoJson/examples/MsgPackParser/MsgPackParser.ino index 1a54c3b..dd7d7b6 100644 --- a/third-party/ArduinoJson/examples/MsgPackParser/MsgPackParser.ino +++ b/third-party/ArduinoJson/examples/MsgPackParser/MsgPackParser.ino @@ -1,39 +1,24 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to deserialize a MessagePack document with // ArduinoJson. // -// https://arduinojson.org/v6/example/msgpack-parser/ +// https://arduinojson.org/v7/example/msgpack-parser/ #include void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Allocate the JSON document - // - // Inside the brackets, 200 is the capacity of the memory pool in bytes. - // Don't forget to change this value to match your JSON document. - // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<200> doc; - - // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonObject which allocates in the heap. - // - // DynamicJsonObject doc(200); + JsonDocument doc; - // MessagePack input string. - // - // Using a char[], as shown here, enables the "zero-copy" mode. This mode uses - // the minimal amount of memory because the JsonDocument stores pointers to - // the input buffer. - // If you use another type of input, ArduinoJson must copy the strings from - // the input to the JsonDocument, so you need to increase the capacity of the - // JsonDocument. + // The MessagePack input string uint8_t input[] = {131, 166, 115, 101, 110, 115, 111, 114, 163, 103, 112, 115, 164, 116, 105, 109, 101, 206, 80, 147, 50, 248, 164, 100, 97, 116, 97, 146, 203, 64, 72, 96, 199, 58, 188, 148, @@ -45,16 +30,17 @@ void setup() { // "data": [48.75608, 2.302038] // } + // Parse the input DeserializationError error = deserializeMsgPack(doc, input); - // Test if parsing succeeded. + // Test if parsing succeeded if (error) { Serial.print("deserializeMsgPack() failed: "); Serial.println(error.f_str()); return; } - // Fetch values. + // Fetch the values // // Most of the time, you can rely on the implicit casts. // In other case, you can do doc["time"].as(); @@ -63,7 +49,7 @@ void setup() { double latitude = doc["data"][0]; double longitude = doc["data"][1]; - // Print values. + // Print the values Serial.println(sensor); Serial.println(time); Serial.println(latitude, 6); diff --git a/third-party/ArduinoJson/examples/ProgmemExample/ProgmemExample.ino b/third-party/ArduinoJson/examples/ProgmemExample/ProgmemExample.ino index 68b8ec5..ffeb79e 100644 --- a/third-party/ArduinoJson/examples/ProgmemExample/ProgmemExample.ino +++ b/third-party/ArduinoJson/examples/ProgmemExample/ProgmemExample.ino @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows the different ways you can use Flash strings with @@ -9,12 +9,12 @@ // JsonDocument. Prefer plain old char*, as they are more efficient in term of // code size, speed, and memory usage. // -// https://arduinojson.org/v6/example/progmem/ +// https://arduinojson.org/v7/example/progmem/ #include void setup() { - DynamicJsonDocument doc(1024); + JsonDocument doc; // You can use a Flash String as your JSON input. // WARNING: the strings in the input will be duplicated in the JsonDocument. diff --git a/third-party/ArduinoJson/examples/StringExample/StringExample.ino b/third-party/ArduinoJson/examples/StringExample/StringExample.ino index 3e51b91..fb5f243 100644 --- a/third-party/ArduinoJson/examples/StringExample/StringExample.ino +++ b/third-party/ArduinoJson/examples/StringExample/StringExample.ino @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows the different ways you can use String with ArduinoJson. @@ -8,12 +8,12 @@ // JsonDocument. Prefer plain old char[], as they are more efficient in term of // code size, speed, and memory usage. // -// https://arduinojson.org/v6/example/string/ +// https://arduinojson.org/v7/example/string/ #include void setup() { - DynamicJsonDocument doc(1024); + JsonDocument doc; // You can use a String as your JSON input. // WARNING: the string in the input will be duplicated in the JsonDocument. @@ -55,7 +55,6 @@ void setup() { } // Lastly, you can print the resulting JSON to a String - // WARNING: it doesn't replace the content but appends to it String output; serializeJson(doc, output); } diff --git a/third-party/ArduinoJson/extras/CompileOptions.cmake b/third-party/ArduinoJson/extras/CompileOptions.cmake index 0cbd576..ae1139f 100644 --- a/third-party/ArduinoJson/extras/CompileOptions.cmake +++ b/third-party/ArduinoJson/extras/CompileOptions.cmake @@ -32,8 +32,18 @@ endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.8) AND(NOT ${COVERAGE})) add_compile_options(-g -Og) - else() - add_compile_options(-g -O0) + else() # GCC 4.8 + add_compile_options( + -g + -O0 # GCC 4.8 doesn't support -Og + -Wno-shadow # allow the same name for a function parameter and a member functions + -Wp,-w # Disable preprocessing warnings (see below) + ) + # GCC 4.8 doesn't support __has_include, so we need to help him + add_definitions( + -DARDUINOJSON_ENABLE_STD_STRING=1 + -DARDUINOJSON_ENABLE_STD_STREAM=1 + ) endif() add_compile_options( @@ -64,6 +74,9 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + add_compile_options(-stdlib=libc++) + link_libraries(c++ m) + if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.0) AND(NOT ${COVERAGE})) add_compile_options(-g -Og) else() diff --git a/third-party/ArduinoJson/extras/ci/espidf/CMakeLists.txt b/third-party/ArduinoJson/extras/ci/espidf/CMakeLists.txt index 3b87896..38d393d 100644 --- a/third-party/ArduinoJson/extras/ci/espidf/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/ci/espidf/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License cmake_minimum_required(VERSION 3.5) diff --git a/third-party/ArduinoJson/extras/ci/espidf/main/CMakeLists.txt b/third-party/ArduinoJson/extras/ci/espidf/main/CMakeLists.txt index 3e10ef8..e32eb7c 100644 --- a/third-party/ArduinoJson/extras/ci/espidf/main/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/ci/espidf/main/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License idf_component_register( diff --git a/third-party/ArduinoJson/extras/ci/espidf/main/main.cpp b/third-party/ArduinoJson/extras/ci/espidf/main/main.cpp index 4818a67..f65aa39 100644 --- a/third-party/ArduinoJson/extras/ci/espidf/main/main.cpp +++ b/third-party/ArduinoJson/extras/ci/espidf/main/main.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include extern "C" void app_main() { char buffer[256]; - StaticJsonDocument<200> doc; + JsonDocument doc; doc["hello"] = "world"; serializeJson(doc, buffer); diff --git a/third-party/ArduinoJson/extras/conf_test/avr.cpp b/third-party/ArduinoJson/extras/conf_test/avr.cpp index b2b105e..e0061ea 100644 --- a/third-party/ArduinoJson/extras/conf_test/avr.cpp +++ b/third-party/ArduinoJson/extras/conf_test/avr.cpp @@ -4,8 +4,7 @@ static_assert(ARDUINOJSON_ENABLE_PROGMEM == 1, "ARDUINOJSON_ENABLE_PROGMEM"); static_assert(ARDUINOJSON_USE_LONG_LONG == 0, "ARDUINOJSON_USE_LONG_LONG"); -static_assert(ARDUINOJSON_SLOT_OFFSET_SIZE == 1, - "ARDUINOJSON_SLOT_OFFSET_SIZE"); +static_assert(ARDUINOJSON_SLOT_ID_SIZE == 1, "ARDUINOJSON_SLOT_ID_SIZE"); static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN"); diff --git a/third-party/ArduinoJson/extras/conf_test/esp8266.cpp b/third-party/ArduinoJson/extras/conf_test/esp8266.cpp index caf70b2..b2e6d06 100644 --- a/third-party/ArduinoJson/extras/conf_test/esp8266.cpp +++ b/third-party/ArduinoJson/extras/conf_test/esp8266.cpp @@ -2,8 +2,7 @@ static_assert(ARDUINOJSON_USE_LONG_LONG == 1, "ARDUINOJSON_USE_LONG_LONG"); -static_assert(ARDUINOJSON_SLOT_OFFSET_SIZE == 2, - "ARDUINOJSON_SLOT_OFFSET_SIZE"); +static_assert(ARDUINOJSON_SLOT_ID_SIZE == 2, "ARDUINOJSON_SLOT_ID_SIZE"); static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN"); diff --git a/third-party/ArduinoJson/extras/conf_test/x64.cpp b/third-party/ArduinoJson/extras/conf_test/x64.cpp index 97838e3..2b533bf 100644 --- a/third-party/ArduinoJson/extras/conf_test/x64.cpp +++ b/third-party/ArduinoJson/extras/conf_test/x64.cpp @@ -2,14 +2,13 @@ static_assert(ARDUINOJSON_USE_LONG_LONG == 1, "ARDUINOJSON_USE_LONG_LONG"); -static_assert(ARDUINOJSON_SLOT_OFFSET_SIZE == 4, - "ARDUINOJSON_SLOT_OFFSET_SIZE"); +static_assert(ARDUINOJSON_SLOT_ID_SIZE == 4, "ARDUINOJSON_SLOT_ID_SIZE"); static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN"); static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE"); -static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 32, +static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 24, "sizeof(VariantSlot)"); int main() {} diff --git a/third-party/ArduinoJson/extras/conf_test/x86.cpp b/third-party/ArduinoJson/extras/conf_test/x86.cpp index f3dab30..a9874ef 100644 --- a/third-party/ArduinoJson/extras/conf_test/x86.cpp +++ b/third-party/ArduinoJson/extras/conf_test/x86.cpp @@ -2,8 +2,7 @@ static_assert(ARDUINOJSON_USE_LONG_LONG == 1, "ARDUINOJSON_USE_LONG_LONG"); -static_assert(ARDUINOJSON_SLOT_OFFSET_SIZE == 2, - "ARDUINOJSON_SLOT_OFFSET_SIZE"); +static_assert(ARDUINOJSON_SLOT_ID_SIZE == 2, "ARDUINOJSON_SLOT_ID_SIZE"); static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN"); diff --git a/third-party/ArduinoJson/extras/fuzzing/CMakeLists.txt b/third-party/ArduinoJson/extras/fuzzing/CMakeLists.txt index 1d439f4..911375e 100644 --- a/third-party/ArduinoJson/extras/fuzzing/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/fuzzing/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License set(CMAKE_CXX_STANDARD 11) diff --git a/third-party/ArduinoJson/extras/fuzzing/json_fuzzer.cpp b/third-party/ArduinoJson/extras/fuzzing/json_fuzzer.cpp index 043cd42..8d78aa3 100644 --- a/third-party/ArduinoJson/extras/fuzzing/json_fuzzer.cpp +++ b/third-party/ArduinoJson/extras/fuzzing/json_fuzzer.cpp @@ -1,7 +1,7 @@ #include extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - DynamicJsonDocument doc(4096); + JsonDocument doc; DeserializationError error = deserializeJson(doc, data, size); if (!error) { std::string json; diff --git a/third-party/ArduinoJson/extras/fuzzing/msgpack_fuzzer.cpp b/third-party/ArduinoJson/extras/fuzzing/msgpack_fuzzer.cpp index b6ab141..3011501 100644 --- a/third-party/ArduinoJson/extras/fuzzing/msgpack_fuzzer.cpp +++ b/third-party/ArduinoJson/extras/fuzzing/msgpack_fuzzer.cpp @@ -1,7 +1,7 @@ #include extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - DynamicJsonDocument doc(4096); + JsonDocument doc; DeserializationError error = deserializeMsgPack(doc, data, size); if (!error) { std::string json; diff --git a/third-party/ArduinoJson/extras/fuzzing/reproducer.cpp b/third-party/ArduinoJson/extras/fuzzing/reproducer.cpp index a004d01..1595a9a 100644 --- a/third-party/ArduinoJson/extras/fuzzing/reproducer.cpp +++ b/third-party/ArduinoJson/extras/fuzzing/reproducer.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // This file is NOT use by Google's OSS fuzz diff --git a/third-party/ArduinoJson/extras/scripts/get-release-page.sh b/third-party/ArduinoJson/extras/scripts/get-release-page.sh index 9bf943e..9eb53e1 100755 --- a/third-party/ArduinoJson/extras/scripts/get-release-page.sh +++ b/third-party/ArduinoJson/extras/scripts/get-release-page.sh @@ -8,7 +8,7 @@ ARDUINOJSON_H="$3" cat << END --- -branch: v6 +branch: v7 version: $VERSION date: '$(date +'%Y-%m-%d')' $(extras/scripts/wandbox/publish.sh "$ARDUINOJSON_H") diff --git a/third-party/ArduinoJson/extras/scripts/publish-particle-library.sh b/third-party/ArduinoJson/extras/scripts/publish-particle-library.sh index 3ee7f91..d410c47 100755 --- a/third-party/ArduinoJson/extras/scripts/publish-particle-library.sh +++ b/third-party/ArduinoJson/extras/scripts/publish-particle-library.sh @@ -14,5 +14,5 @@ cp -r "$SOURCE_DIR/src" "$WORK_DIR/" cp -r "$SOURCE_DIR/examples" "$WORK_DIR/" cd "$WORK_DIR" -particle library upload -v -particle library publish -v +particle library upload +particle library publish diff --git a/third-party/ArduinoJson/extras/scripts/publish.sh b/third-party/ArduinoJson/extras/scripts/publish.sh index af9546a..60af5fc 100755 --- a/third-party/ArduinoJson/extras/scripts/publish.sh +++ b/third-party/ArduinoJson/extras/scripts/publish.sh @@ -2,7 +2,7 @@ set -eu -which awk sed jq 7z curl perl >/dev/null +which awk sed jq curl perl >/dev/null cd "$(dirname "$0")/../.." @@ -15,6 +15,7 @@ VERSION="$1" DATE=$(date +%F) TAG="v$VERSION" VERSION_REGEX='[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9]+)?' +STARS=$(curl -s https://api.github.com/repos/bblanchon/ArduinoJson | jq '.stargazers_count') update_version_in_source () { IFS=".-" read MAJOR MINOR REVISION EXTRA < <(echo "$VERSION") @@ -29,16 +30,25 @@ update_version_in_source () { sed -i~ -bE "s/(project\\s*\\(ArduinoJson\\s+VERSION\\s+).*?\\)/\\1$MAJOR.$MINOR.$REVISION)/" CMakeLists.txt rm CMakeLists.txt~ - sed -i~ -bE "s/\"version\":.*$/\"version\": \"$VERSION\",/" library.json + sed -i~ -bE \ + -e "s/\"version\":.*$/\"version\": \"$VERSION\",/" \ + -e "s/[0-9]+ stars/$STARS stars/" \ + library.json rm library.json~ - sed -i~ -bE "s/version=.*$/version=$VERSION/" library.properties + sed -i~ -bE \ + -e "s/version=.*$/version=$VERSION/" \ + -e "s/[0-9]+ stars/$STARS stars/" \ + library.properties rm library.properties~ sed -i~ -bE "s/version: .*$/version: $VERSION.{build}/" appveyor.yml rm appveyor.yml~ - sed -i~ -bE "s/^version: .*$/version: \"$VERSION\"/" idf_component.yml + sed -i~ -bE \ + -e "s/^version: .*$/version: \"$VERSION\"/" \ + -e "s/[0-9]+ stars/$STARS stars/" \ + idf_component.yml rm idf_component.yml~ sed -i~ -bE \ @@ -70,7 +80,6 @@ commit_new_version add_tag push -extras/scripts/build-arduino-package.sh . "../ArduinoJson-$TAG.zip" extras/scripts/build-single-header.sh "src/ArduinoJson.h" "../ArduinoJson-$TAG.h" extras/scripts/build-single-header.sh "src/ArduinoJson.hpp" "../ArduinoJson-$TAG.hpp" extras/scripts/get-release-page.sh "$VERSION" "CHANGELOG.md" "../ArduinoJson-$TAG.h" > "../ArduinoJson-$TAG.md" diff --git a/third-party/ArduinoJson/extras/scripts/wandbox/JsonGeneratorExample.cpp b/third-party/ArduinoJson/extras/scripts/wandbox/JsonGeneratorExample.cpp index b35d185..313f93b 100644 --- a/third-party/ArduinoJson/extras/scripts/wandbox/JsonGeneratorExample.cpp +++ b/third-party/ArduinoJson/extras/scripts/wandbox/JsonGeneratorExample.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to generate a JSON document with ArduinoJson. @@ -9,35 +9,18 @@ int main() { // Allocate the JSON document - // - // Inside the brackets, 200 is the RAM allocated to this document. - // Don't forget to change this value to match your requirement. - // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<200> doc; + JsonDocument doc; - // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonDocument which allocates in the heap. - // - // DynamicJsonDocument doc(200); - - // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonDocument which allocates in the heap. - // - // DynamicJsonDocument doc(200); - - // Add values in the document - // + // Add values in the document. doc["sensor"] = "gps"; doc["time"] = 1351824120; - // Add an array. - // - JsonArray data = doc.createNestedArray("data"); + // Add an array + JsonArray data = doc["data"].to(); data.add(48.756080); data.add(2.302038); // Generate the minified JSON and send it to STDOUT - // serializeJson(doc, std::cout); // The above line prints: // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} @@ -46,7 +29,6 @@ int main() { std::cout << std::endl; // Generate the prettified JSON and send it to STDOUT - // serializeJsonPretty(doc, std::cout); // The above line prints: // { diff --git a/third-party/ArduinoJson/extras/scripts/wandbox/JsonParserExample.cpp b/third-party/ArduinoJson/extras/scripts/wandbox/JsonParserExample.cpp index 396f98c..cf653a4 100644 --- a/third-party/ArduinoJson/extras/scripts/wandbox/JsonParserExample.cpp +++ b/third-party/ArduinoJson/extras/scripts/wandbox/JsonParserExample.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to deserialize a JSON document with ArduinoJson. @@ -9,38 +9,22 @@ int main() { // Allocate the JSON document - // - // Inside the brackets, 200 is the capacity of the memory pool in bytes. - // Don't forget to change this value to match your JSON document. - // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<300> doc; - - // StaticJsonDocument allocates memory on the stack, it can be - // replaced by DynamicJsonDocument which allocates in the heap. - // - // DynamicJsonDocument doc(200); + JsonDocument doc; - // JSON input string. - // - // Using a char[], as shown here, enables the "zero-copy" mode. This mode uses - // the minimal amount of memory because the JsonDocument stores pointers to - // the input buffer. - // If you use another type of input, ArduinoJson must copy the strings from - // the input to the JsonDocument, so you need to increase the capacity of the - // JsonDocument. - char json[] = + // JSON input string + const char* json = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; // Deserialize the JSON document DeserializationError error = deserializeJson(doc, json); - // Test if parsing succeeds. + // Test if parsing succeeds if (error) { std::cerr << "deserializeJson() failed: " << error.c_str() << std::endl; return 1; } - // Fetch values. + // Fetch the values // // Most of the time, you can rely on the implicit casts. // In other case, you can do doc["time"].as(); @@ -49,7 +33,7 @@ int main() { double latitude = doc["data"][0]; double longitude = doc["data"][1]; - // Print values. + // Print the values std::cout << sensor << std::endl; std::cout << time << std::endl; std::cout << latitude << std::endl; diff --git a/third-party/ArduinoJson/extras/scripts/wandbox/MsgPackParserExample.cpp b/third-party/ArduinoJson/extras/scripts/wandbox/MsgPackParserExample.cpp index 763de84..cb797aa 100644 --- a/third-party/ArduinoJson/extras/scripts/wandbox/MsgPackParserExample.cpp +++ b/third-party/ArduinoJson/extras/scripts/wandbox/MsgPackParserExample.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // // This example shows how to generate a JSON document with ArduinoJson. @@ -9,22 +9,9 @@ int main() { // Allocate the JSON document - // - // Inside the brackets, 300 is the size of the memory pool in bytes. - // Don't forget to change this value to match your JSON document. - // Use https://arduinojson.org/assistant to compute the capacity. - StaticJsonDocument<300> doc; - - // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonObject which allocates in the heap. - // - // DynamicJsonObject doc(200); + JsonDocument doc; - // MessagePack input string. - // - // It's better to use a char[] as shown here. - // If you use a const char* or a String, ArduinoJson will - // have to make a copy of the input in the JsonBuffer. + // The MessagePack input string uint8_t input[] = {131, 166, 115, 101, 110, 115, 111, 114, 163, 103, 112, 115, 164, 116, 105, 109, 101, 206, 80, 147, 50, 248, 164, 100, 97, 116, 97, 146, 203, 64, 72, 96, 199, 58, 188, 148, @@ -36,20 +23,16 @@ int main() { // "data": [48.75608, 2.302038] // } - // doc of the object tree. - // - // It's a reference to the JsonObject, the actual bytes are inside the - // JsonBuffer with all the other nodes of the object tree. - // Memory is freed when jsonBuffer goes out of scope. + // Parse the input DeserializationError error = deserializeMsgPack(doc, input); - // Test if parsing succeeds. + // Test if parsing succeeds if (error) { std::cerr << "deserializeMsgPack() failed: " << error.c_str() << std::endl; return 1; } - // Fetch values. + // Fetch the values // // Most of the time, you can rely on the implicit casts. // In other case, you can do doc["time"].as(); @@ -58,7 +41,7 @@ int main() { double latitude = doc["data"][0]; double longitude = doc["data"][1]; - // Print values. + // Print the values std::cout << sensor << std::endl; std::cout << time << std::endl; std::cout << latitude << std::endl; diff --git a/third-party/ArduinoJson/extras/tests/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/CMakeLists.txt index c62401f..f79a3c9 100644 --- a/third-party/ArduinoJson/extras/tests/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License set(CMAKE_CXX_STANDARD 11) @@ -12,15 +12,19 @@ link_libraries(ArduinoJson catch) include_directories(Helpers) add_subdirectory(Cpp17) add_subdirectory(Cpp20) +add_subdirectory(Deprecated) add_subdirectory(FailingBuilds) add_subdirectory(IntegrationTests) add_subdirectory(JsonArray) +add_subdirectory(JsonArrayConst) add_subdirectory(JsonDeserializer) add_subdirectory(JsonDocument) add_subdirectory(JsonObject) +add_subdirectory(JsonObjectConst) add_subdirectory(JsonSerializer) add_subdirectory(JsonVariant) -add_subdirectory(MemoryPool) +add_subdirectory(JsonVariantConst) +add_subdirectory(ResourceManager) add_subdirectory(Misc) add_subdirectory(MixedConfiguration) add_subdirectory(MsgPackDeserializer) diff --git a/third-party/ArduinoJson/extras/tests/Cpp17/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/Cpp17/CMakeLists.txt index 62f2784..ff5cc0e 100644 --- a/third-party/ArduinoJson/extras/tests/Cpp17/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/Cpp17/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License if(MSVC_VERSION LESS 1910) diff --git a/third-party/ArduinoJson/extras/tests/Cpp17/string_view.cpp b/third-party/ArduinoJson/extras/tests/Cpp17/string_view.cpp index 6a51ce2..32163b2 100644 --- a/third-party/ArduinoJson/extras/tests/Cpp17/string_view.cpp +++ b/third-party/ArduinoJson/extras/tests/Cpp17/string_view.cpp @@ -1,14 +1,27 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +// we expect ArduinoJson.h to include +// but we don't want it to included accidentally +#undef ARDUINO +#define ARDUINOJSON_ENABLE_STD_STREAM 0 +#define ARDUINOJSON_ENABLE_STD_STRING 0 + #include #include -#include +#include "Allocators.hpp" #if !ARDUINOJSON_ENABLE_STRING_VIEW # error ARDUINOJSON_ENABLE_STRING_VIEW must be set to 1 #endif +using ArduinoJson::detail::sizeofArray; + TEST_CASE("string_view") { - StaticJsonDocument<256> doc; + SpyingAllocator spy; + JsonDocument doc(&spy); JsonVariant variant = doc.to(); SECTION("deserializeJson()") { @@ -19,7 +32,7 @@ TEST_CASE("string_view") { SECTION("JsonDocument::set()") { doc.set(std::string_view("123", 2)); - REQUIRE(doc.as() == "12"); + REQUIRE(doc.as() == "12"); } SECTION("JsonDocument::operator[]() const") { @@ -53,16 +66,15 @@ TEST_CASE("string_view") { SECTION("String deduplication") { doc.add(std::string_view("example one", 7)); - REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + 8); - doc.add(std::string_view("example two", 7)); - REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); - doc.add(std::string_view("example\0tree", 12)); - REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(3) + 21); - doc.add(std::string_view("example\0tree and a half", 12)); - REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(4) + 21); + + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + Allocate(sizeofString("example tree")), + }); } SECTION("as()") { diff --git a/third-party/ArduinoJson/extras/tests/Cpp20/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/Cpp20/CMakeLists.txt index e993e97..637af5c 100644 --- a/third-party/ArduinoJson/extras/tests/Cpp20/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/Cpp20/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License if(MSVC_VERSION LESS 1910) diff --git a/third-party/ArduinoJson/extras/tests/Cpp20/smoke_test.cpp b/third-party/ArduinoJson/extras/tests/Cpp20/smoke_test.cpp index dc41e87..72dd50f 100644 --- a/third-party/ArduinoJson/extras/tests/Cpp20/smoke_test.cpp +++ b/third-party/ArduinoJson/extras/tests/Cpp20/smoke_test.cpp @@ -4,7 +4,7 @@ #include TEST_CASE("C++20 smoke test") { - StaticJsonDocument<128> doc; + JsonDocument doc; deserializeJson(doc, "{\"hello\":\"world\"}"); REQUIRE(doc["hello"] == "world"); diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/BasicJsonDocument.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/BasicJsonDocument.cpp new file mode 100644 index 0000000..0b69aee --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/BasicJsonDocument.cpp @@ -0,0 +1,69 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include + +using ArduinoJson::detail::is_base_of; + +static std::string allocatorLog; + +struct CustomAllocator { + CustomAllocator() { + allocatorLog = ""; + } + + void* allocate(size_t n) { + allocatorLog += "A"; + return malloc(n); + } + + void deallocate(void* p) { + free(p); + allocatorLog += "D"; + } + + void* reallocate(void* p, size_t n) { + allocatorLog += "R"; + return realloc(p, n); + } +}; + +TEST_CASE("BasicJsonDocument") { + allocatorLog.clear(); + + SECTION("is a JsonDocument") { + REQUIRE( + is_base_of>::value == + true); + } + + SECTION("deserialize / serialize") { + BasicJsonDocument doc(256); + deserializeJson(doc, "{\"hello\":\"world\"}"); + REQUIRE(doc.as() == "{\"hello\":\"world\"}"); + doc.clear(); + REQUIRE(allocatorLog == "ARAARDDD"); + } + + SECTION("copy") { + BasicJsonDocument doc(256); + doc["hello"] = "world"; + auto copy = doc; + REQUIRE(copy.as() == "{\"hello\":\"world\"}"); + REQUIRE(allocatorLog == "AA"); + } + + SECTION("capacity") { + BasicJsonDocument doc(256); + REQUIRE(doc.capacity() == 256); + } + + SECTION("garbageCollect()") { + BasicJsonDocument doc(256); + doc.garbageCollect(); + } +} diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/Deprecated/CMakeLists.txt new file mode 100644 index 0000000..9cefe82 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/CMakeLists.txt @@ -0,0 +1,34 @@ +# ArduinoJson - https://arduinojson.org +# Copyright © 2014-2024, Benoit BLANCHON +# MIT License + +if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") + add_compile_options( + -w + ) +endif() + +if(MSVC) + add_compile_options( + /wd4996 + ) +endif() + +add_executable(DeprecatedTests + add.cpp + createNestedArray.cpp + createNestedObject.cpp + BasicJsonDocument.cpp + DynamicJsonDocument.cpp + macros.cpp + memoryUsage.cpp + shallowCopy.cpp + StaticJsonDocument.cpp +) + +add_test(Deprecated DeprecatedTests) + +set_tests_properties(Deprecated + PROPERTIES + LABELS "Catch" +) diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/DynamicJsonDocument.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/DynamicJsonDocument.cpp new file mode 100644 index 0000000..df9634b --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/DynamicJsonDocument.cpp @@ -0,0 +1,37 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +using ArduinoJson::detail::is_base_of; + +TEST_CASE("DynamicJsonDocument") { + SECTION("is a JsonDocument") { + REQUIRE(is_base_of::value == true); + } + + SECTION("deserialize / serialize") { + DynamicJsonDocument doc(256); + deserializeJson(doc, "{\"hello\":\"world\"}"); + REQUIRE(doc.as() == "{\"hello\":\"world\"}"); + } + + SECTION("copy") { + DynamicJsonDocument doc(256); + doc["hello"] = "world"; + auto copy = doc; + REQUIRE(copy.as() == "{\"hello\":\"world\"}"); + } + + SECTION("capacity") { + DynamicJsonDocument doc(256); + REQUIRE(doc.capacity() == 256); + } + + SECTION("garbageCollect()") { + DynamicJsonDocument doc(256); + doc.garbageCollect(); + } +} diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/StaticJsonDocument.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/StaticJsonDocument.cpp new file mode 100644 index 0000000..60ca6f2 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/StaticJsonDocument.cpp @@ -0,0 +1,32 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +using ArduinoJson::detail::is_base_of; + +TEST_CASE("StaticJsonDocument") { + SECTION("is a JsonDocument") { + REQUIRE(is_base_of>::value == true); + } + + SECTION("deserialize / serialize") { + StaticJsonDocument<256> doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + REQUIRE(doc.as() == "{\"hello\":\"world\"}"); + } + + SECTION("copy") { + StaticJsonDocument<256> doc; + doc["hello"] = "world"; + auto copy = doc; + REQUIRE(copy.as() == "{\"hello\":\"world\"}"); + } + + SECTION("capacity") { + StaticJsonDocument<256> doc; + REQUIRE(doc.capacity() == 256); + } +} diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/add.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/add.cpp new file mode 100644 index 0000000..de961d1 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/add.cpp @@ -0,0 +1,38 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonArray::add()") { + JsonDocument doc; + JsonArray array = doc.to(); + array.add().set(42); + REQUIRE(doc.as() == "[42]"); +} + +TEST_CASE("JsonDocument::add()") { + JsonDocument doc; + doc.add().set(42); + REQUIRE(doc.as() == "[42]"); +} + +TEST_CASE("ElementProxy::add()") { + JsonDocument doc; + doc[0].add().set(42); + REQUIRE(doc.as() == "[[42]]"); +} + +TEST_CASE("MemberProxy::add()") { + JsonDocument doc; + doc["x"].add().set(42); + REQUIRE(doc.as() == "{\"x\":[42]}"); +} + +TEST_CASE("JsonVariant::add()") { + JsonDocument doc; + JsonVariant v = doc.add(); + v.add().set(42); + REQUIRE(doc.as() == "[[42]]"); +} diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/createNestedArray.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/createNestedArray.cpp new file mode 100644 index 0000000..716517f --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/createNestedArray.cpp @@ -0,0 +1,111 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include + +TEST_CASE("JsonDocument::createNestedArray()") { + JsonDocument doc; + + SECTION("createNestedArray()") { + JsonArray array = doc.createNestedArray(); + array.add(42); + REQUIRE(doc.as() == "[[42]]"); + } + + SECTION("createNestedArray(const char*)") { + JsonArray array = doc.createNestedArray("key"); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } + + SECTION("createNestedArray(std::string)") { + JsonArray array = doc.createNestedArray(std::string("key")); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("createNestedArray(VLA)") { + size_t i = 16; + char vla[i]; + strcpy(vla, "key"); + JsonArray array = doc.createNestedArray(vla); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } +#endif +} + +TEST_CASE("JsonArray::createNestedArray()") { + JsonDocument doc; + JsonArray array = doc.to(); + JsonArray nestedArray = array.createNestedArray(); + nestedArray.add(42); + REQUIRE(doc.as() == "[[42]]"); +} + +TEST_CASE("JsonObject::createNestedArray()") { + JsonDocument doc; + JsonObject object = doc.to(); + + SECTION("createNestedArray(const char*)") { + JsonArray array = object.createNestedArray("key"); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } + + SECTION("createNestedArray(std::string)") { + JsonArray array = object.createNestedArray(std::string("key")); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("createNestedArray(VLA)") { + size_t i = 16; + char vla[i]; + strcpy(vla, "key"); + JsonArray array = object.createNestedArray(vla); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } +#endif +} + +TEST_CASE("JsonVariant::createNestedArray()") { + JsonDocument doc; + JsonVariant variant = doc.to(); + + SECTION("createNestedArray()") { + JsonArray array = variant.createNestedArray(); + array.add(42); + REQUIRE(doc.as() == "[[42]]"); + } + + SECTION("createNestedArray(const char*)") { + JsonArray array = variant.createNestedArray("key"); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } + + SECTION("createNestedArray(std::string)") { + JsonArray array = variant.createNestedArray(std::string("key")); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("createNestedArray(VLA)") { + size_t i = 16; + char vla[i]; + strcpy(vla, "key"); + JsonArray array = variant.createNestedArray(vla); + array.add(42); + REQUIRE(doc.as() == "{\"key\":[42]}"); + } +#endif +} diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/createNestedObject.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/createNestedObject.cpp new file mode 100644 index 0000000..684f31d --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/createNestedObject.cpp @@ -0,0 +1,111 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include + +TEST_CASE("JsonDocument::createNestedObject()") { + JsonDocument doc; + + SECTION("createNestedObject()") { + JsonObject object = doc.createNestedObject(); + object["hello"] = "world"; + REQUIRE(doc.as() == "[{\"hello\":\"world\"}]"); + } + + SECTION("createNestedObject(const char*)") { + JsonObject object = doc.createNestedObject("key"); + object["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } + + SECTION("createNestedObject(std::string)") { + JsonObject object = doc.createNestedObject(std::string("key")); + object["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("createNestedObject(VLA)") { + size_t i = 16; + char vla[i]; + strcpy(vla, "key"); + JsonObject object = doc.createNestedObject(vla); + object["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } +#endif +} + +TEST_CASE("JsonArray::createNestedObject()") { + JsonDocument doc; + JsonArray array = doc.to(); + JsonObject object = array.createNestedObject(); + object["hello"] = "world"; + REQUIRE(doc.as() == "[{\"hello\":\"world\"}]"); +} + +TEST_CASE("JsonObject::createNestedObject()") { + JsonDocument doc; + JsonObject object = doc.to(); + + SECTION("createNestedObject(const char*)") { + JsonObject nestedObject = object.createNestedObject("key"); + nestedObject["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } + + SECTION("createNestedObject(std::string)") { + JsonObject nestedObject = object.createNestedObject(std::string("key")); + nestedObject["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("createNestedObject(VLA)") { + size_t i = 16; + char vla[i]; + strcpy(vla, "key"); + JsonObject nestedObject = object.createNestedObject(vla); + nestedObject["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } +#endif +} + +TEST_CASE("JsonVariant::createNestedObject()") { + JsonDocument doc; + JsonVariant variant = doc.to(); + + SECTION("createNestedObject()") { + JsonObject object = variant.createNestedObject(); + object["hello"] = "world"; + REQUIRE(doc.as() == "[{\"hello\":\"world\"}]"); + } + + SECTION("createNestedObject(const char*)") { + JsonObject object = variant.createNestedObject("key"); + object["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } + + SECTION("createNestedObject(std::string)") { + JsonObject object = variant.createNestedObject(std::string("key")); + object["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("createNestedObject(VLA)") { + size_t i = 16; + char vla[i]; + strcpy(vla, "key"); + JsonObject object = variant.createNestedObject(vla); + object["hello"] = "world"; + REQUIRE(doc.as() == "{\"key\":{\"hello\":\"world\"}}"); + } +#endif +} diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/macros.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/macros.cpp new file mode 100644 index 0000000..9db8f15 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/macros.cpp @@ -0,0 +1,18 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JSON_ARRAY_SIZE") { + REQUIRE(JSON_ARRAY_SIZE(10) == ArduinoJson::detail::sizeofArray(10)); +} + +TEST_CASE("JSON_OBJECT_SIZE") { + REQUIRE(JSON_OBJECT_SIZE(10) == ArduinoJson::detail::sizeofObject(10)); +} + +TEST_CASE("JSON_STRING_SIZE") { + REQUIRE(JSON_STRING_SIZE(10) == ArduinoJson::detail::sizeofString(10)); +} diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/memoryUsage.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/memoryUsage.cpp new file mode 100644 index 0000000..00b5bbb --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/memoryUsage.cpp @@ -0,0 +1,51 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonArray::memoryUsage()") { + JsonArray array; + REQUIRE(array.memoryUsage() == 0); +} + +TEST_CASE("JsonArrayConst::memoryUsage()") { + JsonArrayConst array; + REQUIRE(array.memoryUsage() == 0); +} + +TEST_CASE("JsonDocument::memoryUsage()") { + JsonDocument doc; + REQUIRE(doc.memoryUsage() == 0); +} + +TEST_CASE("JsonObject::memoryUsage()") { + JsonObject array; + REQUIRE(array.memoryUsage() == 0); +} + +TEST_CASE("JsonObjectConst::memoryUsage()") { + JsonObjectConst array; + REQUIRE(array.memoryUsage() == 0); +} + +TEST_CASE("JsonVariant::memoryUsage()") { + JsonVariant doc; + REQUIRE(doc.memoryUsage() == 0); +} + +TEST_CASE("JsonVariantConst::memoryUsage()") { + JsonVariantConst doc; + REQUIRE(doc.memoryUsage() == 0); +} + +TEST_CASE("ElementProxy::memoryUsage()") { + JsonDocument doc; + REQUIRE(doc[0].memoryUsage() == 0); +} + +TEST_CASE("MemberProxy::memoryUsage()") { + JsonDocument doc; + REQUIRE(doc["hello"].memoryUsage() == 0); +} diff --git a/third-party/ArduinoJson/extras/tests/Deprecated/shallowCopy.cpp b/third-party/ArduinoJson/extras/tests/Deprecated/shallowCopy.cpp new file mode 100644 index 0000000..ab5d6c4 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Deprecated/shallowCopy.cpp @@ -0,0 +1,14 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("shallowCopy()") { + JsonDocument doc1, doc2; + doc1["b"] = "c"; + doc2["a"].shallowCopy(doc1); + + REQUIRE(doc2.as() == "{\"a\":{\"b\":\"c\"}}"); +} diff --git a/third-party/ArduinoJson/extras/tests/FailingBuilds/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/FailingBuilds/CMakeLists.txt index 0464908..7ee4a46 100644 --- a/third-party/ArduinoJson/extras/tests/FailingBuilds/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/FailingBuilds/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License macro(build_should_fail target) @@ -23,18 +23,12 @@ endmacro() add_executable(Issue978 Issue978.cpp) build_should_fail(Issue978) -add_executable(Issue1189 Issue1189.cpp) -build_should_fail(Issue1189) - add_executable(read_long_long read_long_long.cpp) build_should_fail(read_long_long) add_executable(write_long_long write_long_long.cpp) build_should_fail(write_long_long) -add_executable(delete_jsondocument delete_jsondocument.cpp) -build_should_fail(delete_jsondocument) - add_executable(variant_as_char variant_as_char.cpp) build_should_fail(variant_as_char) diff --git a/third-party/ArduinoJson/extras/tests/FailingBuilds/Issue978.cpp b/third-party/ArduinoJson/extras/tests/FailingBuilds/Issue978.cpp index d85aaa0..2ebbf94 100644 --- a/third-party/ArduinoJson/extras/tests/FailingBuilds/Issue978.cpp +++ b/third-party/ArduinoJson/extras/tests/FailingBuilds/Issue978.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,6 +8,6 @@ struct Stream {}; int main() { Stream* stream = 0; - DynamicJsonDocument doc(1024); + JsonDocument doc; deserializeJson(doc, stream); } diff --git a/third-party/ArduinoJson/extras/tests/FailingBuilds/assign_char.cpp b/third-party/ArduinoJson/extras/tests/FailingBuilds/assign_char.cpp index b9d897f..b565376 100644 --- a/third-party/ArduinoJson/extras/tests/FailingBuilds/assign_char.cpp +++ b/third-party/ArduinoJson/extras/tests/FailingBuilds/assign_char.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,6 +7,6 @@ // See issue #1498 int main() { - DynamicJsonDocument doc(1024); + JsonDocument doc; doc["dummy"] = 'A'; } diff --git a/third-party/ArduinoJson/extras/tests/FailingBuilds/read_long_long.cpp b/third-party/ArduinoJson/extras/tests/FailingBuilds/read_long_long.cpp index 6fe5992..7577698 100644 --- a/third-party/ArduinoJson/extras/tests/FailingBuilds/read_long_long.cpp +++ b/third-party/ArduinoJson/extras/tests/FailingBuilds/read_long_long.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_USE_LONG_LONG 0 @@ -11,6 +11,6 @@ ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(long long) int main() { - DynamicJsonDocument doc(1024); + JsonDocument doc; doc["dummy"].as(); } diff --git a/third-party/ArduinoJson/extras/tests/FailingBuilds/variant_as_char.cpp b/third-party/ArduinoJson/extras/tests/FailingBuilds/variant_as_char.cpp index 1a9e834..37685a6 100644 --- a/third-party/ArduinoJson/extras/tests/FailingBuilds/variant_as_char.cpp +++ b/third-party/ArduinoJson/extras/tests/FailingBuilds/variant_as_char.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,6 +7,6 @@ // See issue #1498 int main() { - DynamicJsonDocument doc(1024); + JsonDocument doc; doc["dummy"].as(); } diff --git a/third-party/ArduinoJson/extras/tests/FailingBuilds/write_long_long.cpp b/third-party/ArduinoJson/extras/tests/FailingBuilds/write_long_long.cpp index 6ff8356..a8d1460 100644 --- a/third-party/ArduinoJson/extras/tests/FailingBuilds/write_long_long.cpp +++ b/third-party/ArduinoJson/extras/tests/FailingBuilds/write_long_long.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_USE_LONG_LONG 0 @@ -10,6 +10,6 @@ #endif int main() { - DynamicJsonDocument doc(1024); + JsonDocument doc; doc["dummy"] = static_cast(42); } diff --git a/third-party/ArduinoJson/extras/tests/Helpers/Allocators.hpp b/third-party/ArduinoJson/extras/tests/Helpers/Allocators.hpp new file mode 100644 index 0000000..5df98ed --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Helpers/Allocators.hpp @@ -0,0 +1,283 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#pragma once + +#include +#include +#include + +#include + +struct FailingAllocator : ArduinoJson::Allocator { + static FailingAllocator* instance() { + static FailingAllocator allocator; + return &allocator; + } + + private: + FailingAllocator() = default; + ~FailingAllocator() = default; + + void* allocate(size_t) override { + return nullptr; + } + + void deallocate(void*) override {} + + void* reallocate(void*, size_t) override { + return nullptr; + } +}; + +class AllocatorLogEntry { + public: + AllocatorLogEntry(std::string s, size_t n = 1) : str_(s), count_(n) {} + + const std::string& str() const { + return str_; + } + + size_t count() const { + return count_; + } + + AllocatorLogEntry operator*(size_t n) const { + return AllocatorLogEntry(str_, n); + } + + private: + std::string str_; + size_t count_; +}; + +inline AllocatorLogEntry Allocate(size_t s) { + char buffer[32]; + sprintf(buffer, "allocate(%zu)", s); + return AllocatorLogEntry(buffer); +} + +inline AllocatorLogEntry AllocateFail(size_t s) { + char buffer[32]; + sprintf(buffer, "allocate(%zu) -> nullptr", s); + return AllocatorLogEntry(buffer); +} + +inline AllocatorLogEntry Reallocate(size_t s1, size_t s2) { + char buffer[32]; + sprintf(buffer, "reallocate(%zu, %zu)", s1, s2); + return AllocatorLogEntry(buffer); +} + +inline AllocatorLogEntry ReallocateFail(size_t s1, size_t s2) { + char buffer[32]; + sprintf(buffer, "reallocate(%zu, %zu) -> nullptr", s1, s2); + return AllocatorLogEntry(buffer); +} + +inline AllocatorLogEntry Deallocate(size_t s) { + char buffer[32]; + sprintf(buffer, "deallocate(%zu)", s); + return AllocatorLogEntry(buffer); +} + +class AllocatorLog { + public: + AllocatorLog() = default; + AllocatorLog(std::initializer_list list) { + for (auto& entry : list) + append(entry); + } + + void clear() { + log_.str(""); + } + + void append(const AllocatorLogEntry& entry) { + for (size_t i = 0; i < entry.count(); i++) + log_ << entry.str() << "\n"; + } + + std::string str() const { + auto s = log_.str(); + if (s.empty()) + return "(empty)"; + s.pop_back(); // remove the trailing '\n' + return s; + } + + bool operator==(const AllocatorLog& other) const { + return str() == other.str(); + } + + friend std::ostream& operator<<(std::ostream& os, const AllocatorLog& log) { + os << log.str(); + return os; + } + + private: + std::ostringstream log_; +}; + +class SpyingAllocator : public ArduinoJson::Allocator { + public: + SpyingAllocator( + Allocator* upstream = ArduinoJson::detail::DefaultAllocator::instance()) + : upstream_(upstream) {} + virtual ~SpyingAllocator() {} + + size_t allocatedBytes() const { + return allocatedBytes_; + } + + void* allocate(size_t n) override { + auto block = reinterpret_cast( + upstream_->allocate(sizeof(AllocatedBlock) + n - 1)); + if (block) { + log_.append(Allocate(n)); + allocatedBytes_ += n; + block->size = n; + return block->payload; + } else { + log_.append(AllocateFail(n)); + return nullptr; + } + } + + void deallocate(void* p) override { + auto block = AllocatedBlock::fromPayload(p); + allocatedBytes_ -= block->size; + log_.append(Deallocate(block ? block->size : 0)); + upstream_->deallocate(block); + } + + void* reallocate(void* p, size_t n) override { + auto block = AllocatedBlock::fromPayload(p); + auto oldSize = block ? block->size : 0; + block = reinterpret_cast( + upstream_->reallocate(block, sizeof(AllocatedBlock) + n - 1)); + if (block) { + log_.append(Reallocate(oldSize, n)); + block->size = n; + allocatedBytes_ += n - oldSize; + return block->payload; + } else { + log_.append(ReallocateFail(oldSize, n)); + return nullptr; + } + } + + void clearLog() { + log_.clear(); + } + + const AllocatorLog& log() const { + return log_; + } + + private: + struct AllocatedBlock { + size_t size; + char payload[1]; + + static AllocatedBlock* fromPayload(void* p) { + if (!p) + return nullptr; + return reinterpret_cast( + // Cast to void* to silence "cast increases required alignment of + // target type [-Werror=cast-align]" + reinterpret_cast(reinterpret_cast(p) - + offsetof(AllocatedBlock, payload))); + } + }; + + AllocatorLog log_; + Allocator* upstream_; + size_t allocatedBytes_ = 0; +}; + +class KillswitchAllocator : public ArduinoJson::Allocator { + public: + KillswitchAllocator( + Allocator* upstream = ArduinoJson::detail::DefaultAllocator::instance()) + : working_(true), upstream_(upstream) {} + virtual ~KillswitchAllocator() {} + + void* allocate(size_t n) override { + return working_ ? upstream_->allocate(n) : 0; + } + + void deallocate(void* p) override { + upstream_->deallocate(p); + } + + void* reallocate(void* ptr, size_t n) override { + return working_ ? upstream_->reallocate(ptr, n) : 0; + } + + // Turn the killswitch on, so all allocation fail + void on() { + working_ = false; + } + + private: + bool working_; + Allocator* upstream_; +}; + +class TimebombAllocator : public ArduinoJson::Allocator { + public: + TimebombAllocator( + size_t initialCountdown, + Allocator* upstream = ArduinoJson::detail::DefaultAllocator::instance()) + : countdown_(initialCountdown), upstream_(upstream) {} + virtual ~TimebombAllocator() {} + + void* allocate(size_t n) override { + if (!countdown_) + return nullptr; + countdown_--; + return upstream_->allocate(n); + } + + void deallocate(void* p) override { + upstream_->deallocate(p); + } + + void* reallocate(void* ptr, size_t n) override { + if (!countdown_) + return nullptr; + countdown_--; + return upstream_->reallocate(ptr, n); + } + + void setCountdown(size_t value) { + countdown_ = value; + } + + private: + size_t countdown_ = 0; + Allocator* upstream_; +}; + +inline size_t sizeofPoolList(size_t n = ARDUINOJSON_INITIAL_POOL_COUNT) { + return sizeof(ArduinoJson::detail::VariantPool) * n; +} + +inline size_t sizeofPool( + ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) { + return ArduinoJson::detail::VariantPool::slotsToBytes(n); +} + +inline size_t sizeofStringBuffer(size_t iteration = 1) { + // returns 31, 63, 127, 255, etc. + auto capacity = ArduinoJson::detail::StringBuilder::initialCapacity; + for (size_t i = 1; i < iteration; i++) + capacity = capacity * 2 + 1; + return ArduinoJson::detail::sizeofString(capacity); +} + +inline size_t sizeofString(const char* s) { + return ArduinoJson::detail::sizeofString(strlen(s)); +} diff --git a/third-party/ArduinoJson/extras/tests/Helpers/Arduino.h b/third-party/ArduinoJson/extras/tests/Helpers/Arduino.h index ef3640d..4b8c27c 100644 --- a/third-party/ArduinoJson/extras/tests/Helpers/Arduino.h +++ b/third-party/ArduinoJson/extras/tests/Helpers/Arduino.h @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/extras/tests/Helpers/CustomReader.hpp b/third-party/ArduinoJson/extras/tests/Helpers/CustomReader.hpp index 66525a2..66350a7 100644 --- a/third-party/ArduinoJson/extras/tests/Helpers/CustomReader.hpp +++ b/third-party/ArduinoJson/extras/tests/Helpers/CustomReader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/extras/tests/Helpers/api/Print.h b/third-party/ArduinoJson/extras/tests/Helpers/api/Print.h index d3c27cc..c9ec191 100644 --- a/third-party/ArduinoJson/extras/tests/Helpers/api/Print.h +++ b/third-party/ArduinoJson/extras/tests/Helpers/api/Print.h @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/extras/tests/Helpers/api/Stream.h b/third-party/ArduinoJson/extras/tests/Helpers/api/Stream.h index 387940b..2cd4651 100644 --- a/third-party/ArduinoJson/extras/tests/Helpers/api/Stream.h +++ b/third-party/ArduinoJson/extras/tests/Helpers/api/Stream.h @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/extras/tests/Helpers/api/String.h b/third-party/ArduinoJson/extras/tests/Helpers/api/String.h index 64c763f..2e8fdfe 100644 --- a/third-party/ArduinoJson/extras/tests/Helpers/api/String.h +++ b/third-party/ArduinoJson/extras/tests/Helpers/api/String.h @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -9,11 +9,14 @@ // Reproduces Arduino's String class class String { public: - String() : _maxCapacity(1024) {} - explicit String(const char* s) : _str(s), _maxCapacity(1024) {} + String() = default; + String(const char* s) { + if (s) + str_.assign(s); + } void limitCapacityTo(size_t maxCapacity) { - _maxCapacity = maxCapacity; + maxCapacity_ = maxCapacity; } unsigned char concat(const char* s) { @@ -21,45 +24,48 @@ class String { } size_t length() const { - return _str.size(); + return str_.size(); } const char* c_str() const { - return _str.c_str(); + return str_.c_str(); } bool operator==(const char* s) const { - return _str == s; + return str_ == s; } String& operator=(const char* s) { - _str.assign(s); + if (s) + str_.assign(s); + else + str_.clear(); return *this; } char operator[](unsigned int index) const { - if (index >= _str.size()) + if (index >= str_.size()) return 0; - return _str[index]; + return str_[index]; } friend std::ostream& operator<<(std::ostream& lhs, const ::String& rhs) { - lhs << rhs._str; + lhs << rhs.str_; return lhs; } protected: // This function is protected in most Arduino cores unsigned char concat(const char* s, size_t n) { - if (_str.size() + n > _maxCapacity) + if (str_.size() + n > maxCapacity_) return 0; - _str.append(s, n); + str_.append(s, n); return 1; } private: - std::string _str; - size_t _maxCapacity; + std::string str_; + size_t maxCapacity_ = 1024; }; class StringSumHelper : public ::String {}; diff --git a/third-party/ArduinoJson/extras/tests/Helpers/avr/pgmspace.h b/third-party/ArduinoJson/extras/tests/Helpers/avr/pgmspace.h index 378065d..2cdd182 100644 --- a/third-party/ArduinoJson/extras/tests/Helpers/avr/pgmspace.h +++ b/third-party/ArduinoJson/extras/tests/Helpers/avr/pgmspace.h @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/extras/tests/IntegrationTests/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/IntegrationTests/CMakeLists.txt index 9ee858d..adc0ebf 100644 --- a/third-party/ArduinoJson/extras/tests/IntegrationTests/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/IntegrationTests/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(IntegrationTests diff --git a/third-party/ArduinoJson/extras/tests/IntegrationTests/gbathree.cpp b/third-party/ArduinoJson/extras/tests/IntegrationTests/gbathree.cpp index 34c4d0d..db649aa 100644 --- a/third-party/ArduinoJson/extras/tests/IntegrationTests/gbathree.cpp +++ b/third-party/ArduinoJson/extras/tests/IntegrationTests/gbathree.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("Gbathree") { - DynamicJsonDocument doc(4096); + JsonDocument doc; DeserializationError error = deserializeJson( doc, diff --git a/third-party/ArduinoJson/extras/tests/IntegrationTests/issue772.cpp b/third-party/ArduinoJson/extras/tests/IntegrationTests/issue772.cpp index dd85a08..57e0b2c 100644 --- a/third-party/ArduinoJson/extras/tests/IntegrationTests/issue772.cpp +++ b/third-party/ArduinoJson/extras/tests/IntegrationTests/issue772.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,8 +8,8 @@ // https://github.com/bblanchon/ArduinoJson/issues/772 TEST_CASE("Issue772") { - DynamicJsonDocument doc1(4096); - DynamicJsonDocument doc2(4096); + JsonDocument doc1; + JsonDocument doc2; DeserializationError err; std::string data = "{\"state\":{\"reported\":{\"timestamp\":\"2018-07-02T09:40:12Z\"," diff --git a/third-party/ArduinoJson/extras/tests/IntegrationTests/openweathermap.cpp b/third-party/ArduinoJson/extras/tests/IntegrationTests/openweathermap.cpp index e91ac0a..2d55b54 100644 --- a/third-party/ArduinoJson/extras/tests/IntegrationTests/openweathermap.cpp +++ b/third-party/ArduinoJson/extras/tests/IntegrationTests/openweathermap.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -53,12 +53,12 @@ TEST_CASE("OpenWeatherMap") { "]}"; // clang-format on - StaticJsonDocument<512> filter; + JsonDocument filter; filter["list"][0]["dt"] = true; filter["list"][0]["main"]["temp"] = true; filter["list"][0]["weather"][0]["description"] = true; - DynamicJsonDocument doc(16384); + JsonDocument doc; REQUIRE( deserializeJson(doc, input_json, DeserializationOption::Filter(filter)) == diff --git a/third-party/ArduinoJson/extras/tests/IntegrationTests/round_trip.cpp b/third-party/ArduinoJson/extras/tests/IntegrationTests/round_trip.cpp index ede311d..4fd5d2d 100644 --- a/third-party/ArduinoJson/extras/tests/IntegrationTests/round_trip.cpp +++ b/third-party/ArduinoJson/extras/tests/IntegrationTests/round_trip.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include void check(std::string originalJson) { - DynamicJsonDocument doc(16384); + JsonDocument doc; std::string prettyJson; deserializeJson(doc, originalJson); diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonArray/CMakeLists.txt index d97a2b1..bb9719a 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/JsonArray/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(JsonArrayTests @@ -7,11 +7,9 @@ add_executable(JsonArrayTests clear.cpp compare.cpp copyArray.cpp - createNested.cpp equals.cpp isNull.cpp iterator.cpp - memoryUsage.cpp nesting.cpp remove.cpp size.cpp diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/add.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/add.cpp index 2708c7d..22f9920 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/add.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/add.cpp @@ -1,12 +1,17 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include -TEST_CASE("JsonArray::add()") { - DynamicJsonDocument doc(4096); +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; + +TEST_CASE("JsonArray::add(T)") { + SpyingAllocator spy; + JsonDocument doc(&spy); JsonArray array = doc.to(); SECTION("int") { @@ -51,7 +56,7 @@ TEST_CASE("JsonArray::add()") { #endif SECTION("nested array") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonArray arr = doc2.to(); array.add(arr); @@ -62,7 +67,7 @@ TEST_CASE("JsonArray::add()") { } SECTION("nested object") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonObject obj = doc2.to(); array.add(obj); @@ -74,7 +79,7 @@ TEST_CASE("JsonArray::add()") { SECTION("array subscript") { const char* str = "hello"; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonArray arr = doc2.to(); arr.add(str); @@ -85,7 +90,7 @@ TEST_CASE("JsonArray::add()") { SECTION("object subscript") { const char* str = "hello"; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonObject obj = doc2.to(); obj["x"] = str; @@ -96,43 +101,81 @@ TEST_CASE("JsonArray::add()") { SECTION("should not duplicate const char*") { array.add("world"); - const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); } SECTION("should duplicate char*") { array.add(const_cast("world")); - const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("should duplicate std::string") { array.add(std::string("world")); - const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } - SECTION("should not duplicate serialized(const char*)") { + SECTION("should duplicate serialized(const char*)") { array.add(serialized("{}")); - const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("{}")), + }); } SECTION("should duplicate serialized(char*)") { array.add(serialized(const_cast("{}"))); - const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(2); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("{}")), + }); } SECTION("should duplicate serialized(std::string)") { array.add(serialized(std::string("{}"))); - const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(2); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("{}")), + }); } SECTION("should duplicate serialized(std::string)") { array.add(serialized(std::string("\0XX", 3))); - const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(3); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString(" XX")), + }); + } +} + +TEST_CASE("JsonArray::add()") { + JsonDocument doc; + JsonArray array = doc.to(); + + SECTION("add()") { + JsonArray nestedArray = array.add(); + nestedArray.add(1); + nestedArray.add(2); + REQUIRE(doc.as() == "[[1,2]]"); + } + + SECTION("add()") { + JsonObject nestedObject = array.add(); + nestedObject["a"] = 1; + nestedObject["b"] = 2; + REQUIRE(doc.as() == "[{\"a\":1,\"b\":2}]"); + } + + SECTION("add()") { + JsonVariant nestedVariant = array.add(); + nestedVariant.set(42); + REQUIRE(doc.as() == "[42]"); } } diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/clear.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/clear.cpp index 3a593c5..8ac4548 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/clear.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/clear.cpp @@ -1,10 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + TEST_CASE("JsonArray::clear()") { SECTION("No-op on null JsonArray") { JsonArray array; @@ -14,7 +16,7 @@ TEST_CASE("JsonArray::clear()") { } SECTION("Removes all elements") { - StaticJsonDocument<64> doc; + JsonDocument doc; JsonArray array = doc.to(); array.add(1); array.add(2); @@ -22,4 +24,23 @@ TEST_CASE("JsonArray::clear()") { REQUIRE(array.size() == 0); REQUIRE(array.isNull() == false); } + + SECTION("Removed elements are recycled") { + SpyingAllocator spy; + JsonDocument doc(&spy); + JsonArray array = doc.to(); + + // fill the pool entirely + for (int i = 0; i < ARDUINOJSON_POOL_CAPACITY; i++) + array.add(i); + + // clear and fill again + array.clear(); + for (int i = 0; i < ARDUINOJSON_POOL_CAPACITY; i++) + array.add(i); + + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); + } } diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/compare.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/compare.cpp index 1e64e16..b18bcda 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/compare.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/compare.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("Compare JsonArray with JsonArray") { - StaticJsonDocument<256> doc; + JsonDocument doc; SECTION("Compare with unbound") { JsonArray array = doc.to(); @@ -43,15 +43,15 @@ TEST_CASE("Compare JsonArray with JsonArray") { } SECTION("Compare with identical array") { - JsonArray array1 = doc.createNestedArray(); + JsonArray array1 = doc.add(); array1.add(1); array1.add("hello"); - array1.createNestedObject(); + array1.add(); - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello"); - array2.createNestedObject(); + array2.add(); CHECK(array1 == array2); CHECK(array1 <= array2); @@ -62,15 +62,15 @@ TEST_CASE("Compare JsonArray with JsonArray") { } SECTION("Compare with different array") { - JsonArray array1 = doc.createNestedArray(); + JsonArray array1 = doc.add(); array1.add(1); array1.add("hello1"); - array1.createNestedObject(); + array1.add(); - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello2"); - array2.createNestedObject(); + array2.add(); CHECK(array1 != array2); CHECK_FALSE(array1 == array2); @@ -82,7 +82,7 @@ TEST_CASE("Compare JsonArray with JsonArray") { } TEST_CASE("Compare JsonArray with JsonVariant") { - StaticJsonDocument<256> doc; + JsonDocument doc; SECTION("Compare with self") { JsonArray array = doc.to(); @@ -107,15 +107,15 @@ TEST_CASE("Compare JsonArray with JsonVariant") { } SECTION("Compare with identical array") { - JsonArray array = doc.createNestedArray(); + JsonArray array = doc.add(); array.add(1); array.add("hello"); - array.createNestedObject(); + array.add(); - JsonVariant variant = doc.createNestedArray(); + JsonVariant variant = doc.add(); variant.add(1); variant.add("hello"); - variant.createNestedObject(); + variant.add(); CHECK(array == variant); CHECK(array <= variant); @@ -133,15 +133,15 @@ TEST_CASE("Compare JsonArray with JsonVariant") { } SECTION("Compare with different array") { - JsonArray array = doc.createNestedArray(); + JsonArray array = doc.add(); array.add(1); array.add("hello1"); - array.createNestedObject(); + array.add(); - JsonVariant variant = doc.createNestedArray(); + JsonVariant variant = doc.add(); variant.add(1); variant.add("hello2"); - variant.createNestedObject(); + variant.add(); CHECK(array != variant); CHECK_FALSE(array == variant); @@ -153,7 +153,7 @@ TEST_CASE("Compare JsonArray with JsonVariant") { } TEST_CASE("Compare JsonArray with JsonVariantConst") { - StaticJsonDocument<256> doc; + JsonDocument doc; SECTION("Compare with unbound") { JsonArray array = doc.to(); @@ -199,15 +199,15 @@ TEST_CASE("Compare JsonArray with JsonVariantConst") { } SECTION("Compare with identical array") { - JsonArray array = doc.createNestedArray(); + JsonArray array = doc.add(); array.add(1); array.add("hello"); - array.createNestedObject(); + array.add(); - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello"); - array2.createNestedObject(); + array2.add(); JsonVariantConst variant = array2; CHECK(array == variant); @@ -226,15 +226,15 @@ TEST_CASE("Compare JsonArray with JsonVariantConst") { } SECTION("Compare with different array") { - JsonArray array = doc.createNestedArray(); + JsonArray array = doc.add(); array.add(1); array.add("hello1"); - array.createNestedObject(); + array.add(); - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello2"); - array2.createNestedObject(); + array2.add(); JsonVariantConst variant = array2; CHECK(array != variant); @@ -247,7 +247,7 @@ TEST_CASE("Compare JsonArray with JsonVariantConst") { } TEST_CASE("Compare JsonArray with JsonArrayConst") { - StaticJsonDocument<256> doc; + JsonDocument doc; SECTION("Compare with unbound") { JsonArray array = doc.to(); @@ -292,15 +292,15 @@ TEST_CASE("Compare JsonArray with JsonArrayConst") { } SECTION("Compare with identical array") { - JsonArray array1 = doc.createNestedArray(); + JsonArray array1 = doc.add(); array1.add(1); array1.add("hello"); - array1.createNestedObject(); + array1.add(); - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello"); - array2.createNestedObject(); + array2.add(); JsonArrayConst carray2 = array2; CHECK(array1 == carray2); @@ -319,15 +319,15 @@ TEST_CASE("Compare JsonArray with JsonArrayConst") { } SECTION("Compare with different array") { - JsonArray array1 = doc.createNestedArray(); + JsonArray array1 = doc.add(); array1.add(1); array1.add("hello1"); - array1.createNestedObject(); + array1.add(); - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello2"); - array2.createNestedObject(); + array2.add(); JsonArrayConst carray2 = array2; CHECK(array1 != carray2); @@ -347,7 +347,7 @@ TEST_CASE("Compare JsonArray with JsonArrayConst") { } TEST_CASE("Compare JsonArrayConst with JsonArrayConst") { - StaticJsonDocument<256> doc; + JsonDocument doc; SECTION("Compare with unbound") { JsonArray array = doc.to(); @@ -387,16 +387,16 @@ TEST_CASE("Compare JsonArrayConst with JsonArrayConst") { } SECTION("Compare with identical array") { - JsonArray array1 = doc.createNestedArray(); + JsonArray array1 = doc.add(); array1.add(1); array1.add("hello"); - array1.createNestedObject(); + array1.add(); JsonArrayConst carray1 = array1; - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello"); - array2.createNestedObject(); + array2.add(); JsonArrayConst carray2 = array2; CHECK(carray1 == carray2); @@ -408,16 +408,16 @@ TEST_CASE("Compare JsonArrayConst with JsonArrayConst") { } SECTION("Compare with different array") { - JsonArray array1 = doc.createNestedArray(); + JsonArray array1 = doc.add(); array1.add(1); array1.add("hello1"); - array1.createNestedObject(); + array1.add(); JsonArrayConst carray1 = array1; - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello2"); - array2.createNestedObject(); + array2.add(); JsonArrayConst carray2 = array2; CHECK(carray1 != carray2); @@ -430,7 +430,7 @@ TEST_CASE("Compare JsonArrayConst with JsonArrayConst") { } TEST_CASE("Compare JsonArrayConst with JsonVariant") { - StaticJsonDocument<256> doc; + JsonDocument doc; SECTION("Compare with self") { JsonArray array = doc.to(); @@ -455,16 +455,16 @@ TEST_CASE("Compare JsonArrayConst with JsonVariant") { } SECTION("Compare with identical array") { - JsonArray array1 = doc.createNestedArray(); + JsonArray array1 = doc.add(); array1.add(1); array1.add("hello"); - array1.createNestedObject(); + array1.add(); JsonArrayConst carray1 = array1; - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello"); - array2.createNestedObject(); + array2.add(); JsonVariant variant2 = array2; CHECK(carray1 == variant2); @@ -483,16 +483,16 @@ TEST_CASE("Compare JsonArrayConst with JsonVariant") { } SECTION("Compare with different array") { - JsonArray array1 = doc.createNestedArray(); + JsonArray array1 = doc.add(); array1.add(1); array1.add("hello1"); - array1.createNestedObject(); + array1.add(); JsonArrayConst carray1 = array1; - JsonArray array2 = doc.createNestedArray(); + JsonArray array2 = doc.add(); array2.add(1); array2.add("hello2"); - array2.createNestedObject(); + array2.add(); JsonVariant variant2 = array2; CHECK(carray1 != variant2); diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/copyArray.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/copyArray.cpp index 7973c37..f7a2ada 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/copyArray.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/copyArray.cpp @@ -1,13 +1,15 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + TEST_CASE("copyArray()") { SECTION("int[] -> JsonArray") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); char json[32]; int source[] = {1, 2, 3}; @@ -20,7 +22,7 @@ TEST_CASE("copyArray()") { } SECTION("std::string[] -> JsonArray") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); char json[32]; std::string source[] = {"a", "b", "c"}; @@ -33,7 +35,7 @@ TEST_CASE("copyArray()") { } SECTION("const char*[] -> JsonArray") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); char json[32]; const char* source[] = {"a", "b", "c"}; @@ -46,7 +48,7 @@ TEST_CASE("copyArray()") { } SECTION("const char[][] -> JsonArray") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); char json[32]; char source[][2] = {"a", "b", "c"}; @@ -59,7 +61,7 @@ TEST_CASE("copyArray()") { } SECTION("const char[][] -> JsonDocument") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[32]; char source[][2] = {"a", "b", "c"}; @@ -71,7 +73,7 @@ TEST_CASE("copyArray()") { } SECTION("const char[][] -> MemberProxy") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[32]; char source[][2] = {"a", "b", "c"}; @@ -83,7 +85,7 @@ TEST_CASE("copyArray()") { } SECTION("int[] -> JsonDocument") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[32]; int source[] = {1, 2, 3}; @@ -95,7 +97,7 @@ TEST_CASE("copyArray()") { } SECTION("int[] -> MemberProxy") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[32]; int source[] = {1, 2, 3}; @@ -107,21 +109,16 @@ TEST_CASE("copyArray()") { } SECTION("int[] -> JsonArray, but not enough memory") { - const size_t SIZE = JSON_ARRAY_SIZE(2); - StaticJsonDocument doc; + JsonDocument doc(FailingAllocator::instance()); JsonArray array = doc.to(); - char json[32]; int source[] = {1, 2, 3}; bool ok = copyArray(source, array); REQUIRE_FALSE(ok); - - serializeJson(array, json); - CHECK(std::string("[1,2]") == json); } SECTION("int[][] -> JsonArray") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; @@ -134,7 +131,7 @@ TEST_CASE("copyArray()") { } SECTION("int[][] -> MemberProxy") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; @@ -146,7 +143,7 @@ TEST_CASE("copyArray()") { } SECTION("int[][] -> JsonDocument") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; @@ -158,25 +155,16 @@ TEST_CASE("copyArray()") { } SECTION("int[][] -> JsonArray, but not enough memory") { - const size_t SIZE = - JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); - StaticJsonDocument doc; + JsonDocument doc(FailingAllocator::instance()); JsonArray array = doc.to(); - char json[32] = ""; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; - CAPTURE(SIZE); - bool ok = copyArray(source, array); - CAPTURE(doc.memoryUsage()); - CHECK_FALSE(ok); - - serializeJson(array, json); - CHECK(std::string("[[1,2,3],[4,5]]") == json); + REQUIRE(ok == false); } SECTION("JsonArray -> int[], with more space than needed") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "[1,2,3]"; DeserializationError err = deserializeJson(doc, json); CHECK(err == DeserializationError::Ok); @@ -193,7 +181,7 @@ TEST_CASE("copyArray()") { } SECTION("JsonArray -> int[], without enough space") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "[1,2,3]"; DeserializationError err = deserializeJson(doc, json); CHECK(err == DeserializationError::Ok); @@ -208,7 +196,7 @@ TEST_CASE("copyArray()") { } SECTION("JsonArray -> std::string[]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "[\"a\",\"b\",\"c\"]"; DeserializationError err = deserializeJson(doc, json); CHECK(err == DeserializationError::Ok); @@ -225,7 +213,7 @@ TEST_CASE("copyArray()") { } SECTION("JsonArray -> char[N][]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "[\"a12345\",\"b123456\",\"c1234567\"]"; DeserializationError err = deserializeJson(doc, json); CHECK(err == DeserializationError::Ok); @@ -242,7 +230,7 @@ TEST_CASE("copyArray()") { } SECTION("JsonDocument -> int[]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "[1,2,3]"; DeserializationError err = deserializeJson(doc, json); CHECK(err == DeserializationError::Ok); @@ -258,7 +246,7 @@ TEST_CASE("copyArray()") { } SECTION("MemberProxy -> int[]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "{\"data\":[1,2,3]}"; DeserializationError err = deserializeJson(doc, json); CHECK(err == DeserializationError::Ok); @@ -274,7 +262,7 @@ TEST_CASE("copyArray()") { } SECTION("ElementProxy -> int[]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "[[1,2,3]]"; DeserializationError err = deserializeJson(doc, json); CHECK(err == DeserializationError::Ok); @@ -290,7 +278,7 @@ TEST_CASE("copyArray()") { } SECTION("JsonArray -> int[][]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "[[1,2],[3],[4]]"; DeserializationError err = deserializeJson(doc, json); @@ -309,7 +297,7 @@ TEST_CASE("copyArray()") { } SECTION("JsonDocument -> int[][]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "[[1,2],[3],[4]]"; DeserializationError err = deserializeJson(doc, json); @@ -327,7 +315,7 @@ TEST_CASE("copyArray()") { } SECTION("MemberProxy -> int[][]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; char json[] = "{\"data\":[[1,2],[3],[4]]}"; DeserializationError err = deserializeJson(doc, json); diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/equals.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/equals.cpp index 4998d38..4f5af46 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/equals.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/equals.cpp @@ -1,25 +1,22 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonArray::operator==()") { - DynamicJsonDocument doc1(4096); + JsonDocument doc1; JsonArray array1 = doc1.to(); - JsonArrayConst array1c = array1; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonArray array2 = doc2.to(); - JsonArrayConst array2c = array2; SECTION("should return false when arrays differ") { array1.add("coucou"); array2.add(1); REQUIRE_FALSE(array1 == array2); - REQUIRE_FALSE(array1c == array2c); } SECTION("should return false when LHS has more elements") { @@ -28,7 +25,6 @@ TEST_CASE("JsonArray::operator==()") { array2.add(1); REQUIRE_FALSE(array1 == array2); - REQUIRE_FALSE(array1c == array2c); } SECTION("should return false when RHS has more elements") { @@ -37,7 +33,6 @@ TEST_CASE("JsonArray::operator==()") { array2.add(2); REQUIRE_FALSE(array1 == array2); - REQUIRE_FALSE(array1c == array2c); } SECTION("should return true when arrays equal") { @@ -45,7 +40,6 @@ TEST_CASE("JsonArray::operator==()") { array2.add("coucou"); REQUIRE(array1 == array2); - REQUIRE(array1c == array2c); } SECTION("should return false when RHS is null") { diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/isNull.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/isNull.cpp index 0da13be..dc22f4b 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/isNull.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/isNull.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -12,25 +12,12 @@ TEST_CASE("JsonArray::isNull()") { } SECTION("returns false") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray arr = doc.to(); REQUIRE(arr.isNull() == false); } } -TEST_CASE("JsonArrayConst::isNull()") { - SECTION("returns true") { - JsonArrayConst arr; - REQUIRE(arr.isNull() == true); - } - - SECTION("returns false") { - DynamicJsonDocument doc(4096); - JsonArrayConst arr = doc.to(); - REQUIRE(arr.isNull() == false); - } -} - TEST_CASE("JsonArray::operator bool()") { SECTION("returns false") { JsonArray arr; @@ -38,21 +25,8 @@ TEST_CASE("JsonArray::operator bool()") { } SECTION("returns true") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray arr = doc.to(); REQUIRE(static_cast(arr) == true); } } - -TEST_CASE("JsonArrayConst::operator bool()") { - SECTION("returns false") { - JsonArrayConst arr; - REQUIRE(static_cast(arr) == false); - } - - SECTION("returns true") { - DynamicJsonDocument doc(4096); - JsonArrayConst arr = doc.to(); - REQUIRE(static_cast(arr) == true); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/iterator.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/iterator.cpp index 50eb276..8158975 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/iterator.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/iterator.cpp @@ -1,35 +1,29 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include -template -static void run_iterator_test() { - StaticJsonDocument doc; - JsonArray tmp = doc.to(); - tmp.add(12); - tmp.add(34); - - TArray array = tmp; - typename TArray::iterator it = array.begin(); - typename TArray::iterator end = array.end(); - - REQUIRE(end != it); - REQUIRE(12 == it->template as()); - REQUIRE(12 == static_cast(*it)); - ++it; - REQUIRE(end != it); - REQUIRE(34 == it->template as()); - REQUIRE(34 == static_cast(*it)); - ++it; - REQUIRE(end == it); -} - TEST_CASE("JsonArray::begin()/end()") { SECTION("Non null JsonArray") { - run_iterator_test(); + JsonDocument doc; + JsonArray array = doc.to(); + array.add(12); + array.add(34); + + auto it = array.begin(); + auto end = array.end(); + + REQUIRE(end != it); + REQUIRE(12 == it->as()); + REQUIRE(12 == static_cast(*it)); + ++it; + REQUIRE(end != it); + REQUIRE(34 == it->as()); + REQUIRE(34 == static_cast(*it)); + ++it; + REQUIRE(end == it); } SECTION("Null JsonArray") { @@ -38,15 +32,3 @@ TEST_CASE("JsonArray::begin()/end()") { REQUIRE(array.begin() == array.end()); } } - -TEST_CASE("JsonArrayConst::begin()/end()") { - SECTION("Non null JsonArrayConst") { - run_iterator_test(); - } - - SECTION("Null JsonArrayConst") { - JsonArrayConst array; - - REQUIRE(array.begin() == array.end()); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/nesting.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/nesting.cpp index fc1be8c..a49b01c 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/nesting.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/nesting.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonArray::nesting()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray arr = doc.to(); SECTION("return 0 if uninitialized") { @@ -24,12 +24,12 @@ TEST_CASE("JsonArray::nesting()") { } SECTION("returns 2 with nested array") { - arr.createNestedArray(); + arr.add(); REQUIRE(arr.nesting() == 2); } SECTION("returns 2 with nested object") { - arr.createNestedObject(); + arr.add(); REQUIRE(arr.nesting() == 2); } } diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/remove.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/remove.cpp index f75efda..6e67130 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/remove.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/remove.cpp @@ -1,12 +1,14 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + TEST_CASE("JsonArray::remove()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); array.add(1); array.add(2); @@ -87,3 +89,23 @@ TEST_CASE("JsonArray::remove()") { unboundArray.remove(unboundArray.begin()); } } + +TEST_CASE("Removed elements are recycled") { + SpyingAllocator spy; + JsonDocument doc(&spy); + JsonArray array = doc.to(); + + // fill the pool entirely + for (int i = 0; i < ARDUINOJSON_POOL_CAPACITY; i++) + array.add(i); + + // free one slot in the pool + array.remove(0); + + // add one element; it should use the free slot + array.add(42); + + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), // only one pool + }); +} diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/size.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/size.cpp index 6edd4db..599b37c 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/size.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/size.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonArray::size()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); SECTION("returns 0 is empty") { diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/std_string.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/std_string.cpp index 7d3ec9f..fc28d52 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/std_string.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/std_string.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -12,7 +12,7 @@ static void eraseString(std::string& str) { } TEST_CASE("std::string") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); SECTION("add()") { diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/subscript.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/subscript.cpp index 3079d2f..fde7617 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/subscript.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/subscript.cpp @@ -1,13 +1,16 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include #include +#include "Allocators.hpp" + TEST_CASE("JsonArray::operator[]") { - DynamicJsonDocument doc(4096); + SpyingAllocator spy; + JsonDocument doc(&spy); JsonArray array = doc.to(); SECTION("Pad with null") { @@ -65,7 +68,7 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("nested array") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonArray arr2 = doc2.to(); array[0] = arr2; @@ -76,7 +79,7 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("nested object") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonObject obj = doc2.to(); array[0] = obj; @@ -87,7 +90,7 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("array subscript") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonArray arr2 = doc2.to(); const char* str = "hello"; @@ -100,7 +103,7 @@ TEST_CASE("JsonArray::operator[]") { SECTION("object subscript") { const char* str = "hello"; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonObject obj = doc2.to(); obj["x"] = str; @@ -112,20 +115,25 @@ TEST_CASE("JsonArray::operator[]") { SECTION("should not duplicate const char*") { array[0] = "world"; - const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); } SECTION("should duplicate char*") { array[0] = const_cast("world"); - const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("should duplicate std::string") { array[0] = std::string("world"); - const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("array[0].to()") { @@ -157,18 +165,3 @@ TEST_CASE("JsonArray::operator[]") { } #endif } - -TEST_CASE("JsonArrayConst::operator[]") { - DynamicJsonDocument doc(4096); - JsonArray array = doc.to(); - array.add(0); - - SECTION("int") { - array[0] = 123; - JsonArrayConst carr = array; - - REQUIRE(123 == carr[0].as()); - REQUIRE(true == carr[0].is()); - REQUIRE(false == carr[0].is()); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonArray/unbound.cpp b/third-party/ArduinoJson/extras/tests/JsonArray/unbound.cpp index 0e21310..21d4ebf 100644 --- a/third-party/ArduinoJson/extras/tests/JsonArray/unbound.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonArray/unbound.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -19,14 +19,6 @@ TEST_CASE("Unbound JsonArray") { REQUIRE(0 == array.size()); } - SECTION("CreateNestedArrayFails") { - REQUIRE(array.createNestedArray().isNull()); - } - - SECTION("CreateNestedObjectFails") { - REQUIRE(array.createNestedObject().isNull()); - } - SECTION("PrintToWritesBrackets") { char buffer[32]; serializeJson(array, buffer, sizeof(buffer)); diff --git a/third-party/ArduinoJson/extras/tests/JsonArrayConst/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonArrayConst/CMakeLists.txt new file mode 100644 index 0000000..8608a89 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonArrayConst/CMakeLists.txt @@ -0,0 +1,19 @@ +# ArduinoJson - https://arduinojson.org +# Copyright © 2014-2024, Benoit BLANCHON +# MIT License + +add_executable(JsonArrayConstTests + equals.cpp + isNull.cpp + iterator.cpp + nesting.cpp + size.cpp + subscript.cpp +) + +add_test(JsonArrayConst JsonArrayConstTests) + +set_tests_properties(JsonArrayConst + PROPERTIES + LABELS "Catch" +) diff --git a/third-party/ArduinoJson/extras/tests/JsonArrayConst/equals.cpp b/third-party/ArduinoJson/extras/tests/JsonArrayConst/equals.cpp new file mode 100644 index 0000000..ba60d38 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonArrayConst/equals.cpp @@ -0,0 +1,63 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonArrayConst::operator==()") { + JsonDocument doc1; + JsonArrayConst array1 = doc1.to(); + + JsonDocument doc2; + JsonArrayConst array2 = doc2.to(); + + SECTION("should return false when arrays differ") { + doc1.add("coucou"); + doc2.add(1); + + REQUIRE_FALSE(array1 == array2); + } + + SECTION("should return false when LHS has more elements") { + doc1.add(1); + doc1.add(2); + doc2.add(1); + + REQUIRE_FALSE(array1 == array2); + } + + SECTION("should return false when RHS has more elements") { + doc1.add(1); + doc2.add(1); + doc2.add(2); + + REQUIRE_FALSE(array1 == array2); + } + + SECTION("should return true when arrays equal") { + doc1.add("coucou"); + doc2.add("coucou"); + + REQUIRE(array1 == array2); + } + + SECTION("should return false when RHS is null") { + JsonArrayConst null; + + REQUIRE_FALSE(array1 == null); + } + + SECTION("should return false when LHS is null") { + JsonArrayConst null; + + REQUIRE_FALSE(null == array1); + } + + SECTION("should return true when both are null") { + JsonArrayConst null1; + JsonArrayConst null2; + + REQUIRE(null1 == null2); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonArrayConst/isNull.cpp b/third-party/ArduinoJson/extras/tests/JsonArrayConst/isNull.cpp new file mode 100644 index 0000000..26b64ae --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonArrayConst/isNull.cpp @@ -0,0 +1,32 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonArrayConst::isNull()") { + SECTION("returns true") { + JsonArrayConst arr; + REQUIRE(arr.isNull() == true); + } + + SECTION("returns false") { + JsonDocument doc; + JsonArrayConst arr = doc.to(); + REQUIRE(arr.isNull() == false); + } +} + +TEST_CASE("JsonArrayConst::operator bool()") { + SECTION("returns false") { + JsonArrayConst arr; + REQUIRE(static_cast(arr) == false); + } + + SECTION("returns true") { + JsonDocument doc; + JsonArrayConst arr = doc.to(); + REQUIRE(static_cast(arr) == true); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonArrayConst/iterator.cpp b/third-party/ArduinoJson/extras/tests/JsonArrayConst/iterator.cpp new file mode 100644 index 0000000..5eeb56a --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonArrayConst/iterator.cpp @@ -0,0 +1,34 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonArrayConst::begin()/end()") { + SECTION("Non null JsonArrayConst") { + JsonDocument doc; + JsonArrayConst array = doc.to(); + doc.add(12); + doc.add(34); + + auto it = array.begin(); + auto end = array.end(); + + REQUIRE(end != it); + REQUIRE(12 == it->as()); + REQUIRE(12 == static_cast(*it)); + ++it; + REQUIRE(end != it); + REQUIRE(34 == it->as()); + REQUIRE(34 == static_cast(*it)); + ++it; + REQUIRE(end == it); + } + + SECTION("Null JsonArrayConst") { + JsonArrayConst array; + + REQUIRE(array.begin() == array.end()); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonArrayConst/nesting.cpp b/third-party/ArduinoJson/extras/tests/JsonArrayConst/nesting.cpp new file mode 100644 index 0000000..860754a --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonArrayConst/nesting.cpp @@ -0,0 +1,35 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonArrayConst::nesting()") { + JsonDocument doc; + JsonArrayConst arr = doc.to(); + + SECTION("return 0 if unbound") { + JsonArrayConst unbound; + REQUIRE(unbound.nesting() == 0); + } + + SECTION("returns 1 for empty array") { + REQUIRE(arr.nesting() == 1); + } + + SECTION("returns 1 for flat array") { + doc.add("hello"); + REQUIRE(arr.nesting() == 1); + } + + SECTION("returns 2 with nested array") { + doc.add(); + REQUIRE(arr.nesting() == 2); + } + + SECTION("returns 2 with nested object") { + doc.add(); + REQUIRE(arr.nesting() == 2); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonArrayConst/size.cpp b/third-party/ArduinoJson/extras/tests/JsonArrayConst/size.cpp new file mode 100644 index 0000000..a59551a --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonArrayConst/size.cpp @@ -0,0 +1,27 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonArrayConst::size()") { + JsonDocument doc; + JsonArrayConst array = doc.to(); + + SECTION("returns 0 if unbound") { + JsonArrayConst unbound; + REQUIRE(0U == unbound.size()); + } + + SECTION("returns 0 is empty") { + REQUIRE(0U == array.size()); + } + + SECTION("return number of elements") { + doc.add("hello"); + doc.add("world"); + + REQUIRE(2U == array.size()); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonArrayConst/subscript.cpp b/third-party/ArduinoJson/extras/tests/JsonArrayConst/subscript.cpp new file mode 100644 index 0000000..4525287 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonArrayConst/subscript.cpp @@ -0,0 +1,20 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include + +TEST_CASE("JsonArrayConst::operator[]") { + JsonDocument doc; + JsonArrayConst arr = doc.to(); + doc.add(1); + doc.add(2); + doc.add(3); + + REQUIRE(1 == arr[0].as()); + REQUIRE(2 == arr[1].as()); + REQUIRE(3 == arr[2].as()); + REQUIRE(0 == arr[3].as()); +} diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonDeserializer/CMakeLists.txt index f60ad41..a503f45 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/CMakeLists.txt @@ -1,20 +1,18 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(JsonDeserializerTests array.cpp - array_static.cpp DeserializationError.cpp + destination_types.cpp + errors.cpp filter.cpp - incomplete_input.cpp input_types.cpp - invalid_input.cpp misc.cpp nestingLimit.cpp number.cpp object.cpp - object_static.cpp string.cpp ) diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/DeserializationError.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/DeserializationError.cpp index fd1b188..17c8c40 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/DeserializationError.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/DeserializationError.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/array.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/array.cpp index b30269c..71a567d 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/array.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/array.cpp @@ -1,12 +1,17 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; + TEST_CASE("deserialize JSON array") { - DynamicJsonDocument doc(4096); + SpyingAllocator spy; + JsonDocument doc(&spy); SECTION("An empty array") { DeserializationError err = deserializeJson(doc, "[]"); @@ -244,10 +249,71 @@ TEST_CASE("deserialize JSON array") { SECTION("Should clear the JsonArray") { deserializeJson(doc, "[1,2,3,4]"); + spy.clearLog(); + deserializeJson(doc, "[]"); - JsonArray arr = doc.as(); + JsonArray arr = doc.as(); REQUIRE(arr.size() == 0); - REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofArray(4)), + }); + } +} + +TEST_CASE("deserialize JSON array under memory constraints") { + TimebombAllocator timebomb(100); + SpyingAllocator spy(&timebomb); + JsonDocument doc(&spy); + + SECTION("empty array requires no allocation") { + timebomb.setCountdown(0); + char input[] = "[]"; + + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::Ok); + } + + SECTION("allocation of pool list fails") { + timebomb.setCountdown(0); + char input[] = "[1]"; + + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::NoMemory); + REQUIRE(doc.as() == "[]"); + } + + SECTION("allocation of pool fails") { + timebomb.setCountdown(0); + char input[] = "[1]"; + + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::NoMemory); + REQUIRE(doc.as() == "[]"); + } + + SECTION("allocation of string fails in array") { + timebomb.setCountdown(1); + char input[] = "[0,\"hi!\"]"; + + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::NoMemory); + REQUIRE(doc.as() == "[0,null]"); + } + + SECTION("don't store space characters") { + deserializeJson(doc, " [ \"1234567\" ] "); + + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("1234567")), + Reallocate(sizeofPool(), sizeofArray(1)), + }); } } diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/destination_types.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/destination_types.cpp new file mode 100644 index 0000000..d74dfb7 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/destination_types.cpp @@ -0,0 +1,108 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include + +#include +#include + +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; +using ArduinoJson::detail::sizeofObject; + +TEST_CASE("deserializeJson(JsonDocument&)") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc.add(std::string("hello")); + spy.clearLog(); + + auto err = deserializeJson(doc, "[42]"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "[42]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofPool()), + Deallocate(sizeofString("hello")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofArray(1)), + }); +} + +TEST_CASE("deserializeJson(JsonVariant)") { + SECTION("variant is bound") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc.add(std::string("hello")); + spy.clearLog(); + + JsonVariant variant = doc[0]; + + auto err = deserializeJson(variant, "[42]"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "[[42]]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("hello")), + }); + } + + SECTION("variant is unbound") { + JsonVariant variant; + + auto err = deserializeJson(variant, "[42]"); + + REQUIRE(err == DeserializationError::NoMemory); + } +} + +TEST_CASE("deserializeJson(ElementProxy)") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc.add(std::string("hello")); + spy.clearLog(); + + SECTION("element already exists") { + auto err = deserializeJson(doc[0], "[42]"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "[[42]]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("hello")), + }); + } + + SECTION("element must be created") { + auto err = deserializeJson(doc[1], "[42]"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "[\"hello\",[42]]"); + REQUIRE(spy.log() == AllocatorLog{}); + } +} + +TEST_CASE("deserializeJson(MemberProxy)") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc[std::string("hello")] = std::string("world"); + spy.clearLog(); + + SECTION("member already exists") { + auto err = deserializeJson(doc["hello"], "[42]"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "{\"hello\":[42]}"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("world")), + }); + } + + SECTION("member must be created exists") { + auto err = deserializeJson(doc["value"], "[42]"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "{\"hello\":\"world\",\"value\":[42]}"); + REQUIRE(spy.log() == AllocatorLog{}); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/errors.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/errors.cpp new file mode 100644 index 0000000..35b4de2 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/errors.cpp @@ -0,0 +1,120 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#define ARDUINOJSON_DECODE_UNICODE 1 +#include +#include + +TEST_CASE("deserializeJson() returns IncompleteInput") { + const char* testCases[] = { + // strings + "\"\\", + "\"hello", + "\'hello", + // unicode + "'\\u", + "'\\u00", + "'\\u000", + // false + "f", + "fa", + "fal", + "fals", + // true + "t", + "tr", + "tru", + // null + "n", + "nu", + "nul", + // object + "{", + "{a", + "{a:", + "{a:1", + "{a:1,", + "{a:1,b", + "{a:1,b:", + }; + + for (auto input : testCases) { + SECTION(input) { + JsonDocument doc; + REQUIRE(deserializeJson(doc, input) == + DeserializationError::IncompleteInput); + } + } +} + +TEST_CASE("deserializeJson() returns InvalidInput") { + const char* testCases[] = { + // unicode + "'\\u'", "'\\u000g'", "'\\u000'", "'\\u000G'", "'\\u000/'", "\\x1234", + // numbers + "6a9", "1,", "2]", "3}", + // constants + "nulL", "tru3", "fals3", + // garbage + "%*$£¤"}; + + for (auto input : testCases) { + SECTION(input) { + JsonDocument doc; + REQUIRE(deserializeJson(doc, input) == + DeserializationError::InvalidInput); + } + } +} + +TEST_CASE("deserializeJson() oversees some edge cases") { + const char* testCases[] = { + "'\\ud83d'", // leading surrogate without a trailing surrogate + "'\\udda4'", // trailing surrogate without a leading surrogate + "'\\ud83d\\ud83d'", // two leading surrogates + }; + + for (auto input : testCases) { + SECTION(input) { + JsonDocument doc; + REQUIRE(deserializeJson(doc, input) == DeserializationError::Ok); + } + } +} + +TEST_CASE("deserializeJson() returns EmptyInput") { + JsonDocument doc; + + SECTION("null") { + auto err = deserializeJson(doc, static_cast(0)); + REQUIRE(err == DeserializationError::EmptyInput); + } + + SECTION("Empty string") { + auto err = deserializeJson(doc, ""); + REQUIRE(err == DeserializationError::EmptyInput); + } + + SECTION("Only spaces") { + auto err = deserializeJson(doc, " \t\n\r"); + REQUIRE(err == DeserializationError::EmptyInput); + } +} + +TEST_CASE("deserializeJson() returns NoMemory if string length overflows") { + JsonDocument doc; + auto maxLength = ArduinoJson::detail::StringNode::maxLength; + + SECTION("max length should succeed") { + auto err = deserializeJson(doc, "\"" + std::string(maxLength, 'a') + "\""); + + REQUIRE(err == DeserializationError::Ok); + } + + SECTION("one above max length should fail") { + auto err = + deserializeJson(doc, "\"" + std::string(maxLength + 1, 'a') + "\""); + REQUIRE(err == DeserializationError::NoMemory); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/filter.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/filter.cpp index f1c6e2e..b183382 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/filter.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/filter.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_ENABLE_COMMENTS 1 @@ -9,8 +9,14 @@ #include #include +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; +using ArduinoJson::detail::sizeofObject; + TEST_CASE("Filtering") { struct TestCase { + const char* description; const char* input; const char* filter; uint8_t nestingLimit; @@ -19,707 +25,699 @@ TEST_CASE("Filtering") { size_t memoryUsage; }; - // clang-format off TestCase testCases[] = { - { - "{\"hello\":\"world\"}", // 1. input - "null", // 2. filter - 10, // 3. nestingLimit - DeserializationError::Ok, // 4. error - "null", // 5. output - 0 // 6. memoryUsage - }, - { - "{\"hello\":\"world\"}", - "false", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - "{\"abcdefg\":\"hijklmn\"}", - "true", - 10, - DeserializationError::Ok, - "{\"abcdefg\":\"hijklmn\"}", - JSON_OBJECT_SIZE(1) + 16 - }, - { - "{\"hello\":\"world\"}", - "{}", - 10, - DeserializationError::Ok, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // Input in an object, but filter wants an array - "{\"hello\":\"world\"}", - "[]", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - // Member is a string, but filter wants an array - "{\"example\":\"example\"}", - "{\"example\":[true]}", - 10, - DeserializationError::Ok, - "{\"example\":null}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // Member is a number, but filter wants an array - "{\"example\":42}", - "{\"example\":[true]}", - 10, - DeserializationError::Ok, - "{\"example\":null}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // Input is an array, but filter wants an object - "[\"hello\",\"world\"]", - "{}", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - // Input is a bool, but filter wants an object - "true", - "{}", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - // Input is a string, but filter wants an object - "\"hello\"", - "{}", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - // skip an integer - "{\"an_integer\":666,example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // skip a float - "{\"a_float\":12.34e-6,example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // skip false - "{\"a_bool\":false,example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // skip true - "{\"a_bool\":true,example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // skip null - "{\"a_bool\":null,example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip a double-quoted string - "{\"a_double_quoted_string\":\"hello\",example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip a single-quoted string - "{\"a_single_quoted_string\":'hello',example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip an empty array - "{\"an_empty_array\":[],example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip an empty array with spaces in it - "{\"an_empty_array\":[\t],example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip an array - "{\"an_array\":[1,2,3],example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip an array with spaces in it - "{\"an_array\": [ 1 , 2 , 3 ] ,example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip an empty object - "{\"an_empty_object\":{},example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip an empty object with spaces in it - "{\"an_empty_object\":{ },example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // can skip an object - "{\"an_object\":{a:1,'b':2,\"c\":3},example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // skip an object with spaces in it - "{\"an_object\" : { a : 1 , 'b' : 2 , \"c\" : 3 } ,example:42}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{\"example\":42}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - "{\"an_integer\": 0,\"example\":{\"type\":\"int\",\"outcome\":42}}", - "{\"example\":{\"outcome\":true}}", - 10, - DeserializationError::Ok, - "{\"example\":{\"outcome\":42}}", - 2 * JSON_OBJECT_SIZE(1) + 16 - }, - { - // wildcard - "{\"example\":{\"type\":\"int\",\"outcome\":42}}", - "{\"*\":{\"outcome\":true}}", - 10, - DeserializationError::Ok, - "{\"example\":{\"outcome\":42}}", - 2 * JSON_OBJECT_SIZE(1) + 16 - }, - { - // exclusion filter (issue #1628) - "{\"example\":1,\"ignored\":2}", - "{\"*\":true,\"ignored\":false}", - 10, - DeserializationError::Ok, - "{\"example\":1}", - JSON_OBJECT_SIZE(1) + 8 - }, - { - // only the first element of array counts - "[1,2,3]", - "[true, false]", - 10, - DeserializationError::Ok, - "[1,2,3]", - JSON_ARRAY_SIZE(3) - }, - { - // only the first element of array counts - "[1,2,3]", - "[false, true]", - 10, - DeserializationError::Ok, - "[]", - JSON_ARRAY_SIZE(0) - }, - { - // filter members of object in array - "[{\"example\":1,\"ignore\":2},{\"example\":3,\"ignore\":4}]", - "[{\"example\":true}]", - 10, - DeserializationError::Ok, - "[{\"example\":1},{\"example\":3}]", - JSON_ARRAY_SIZE(2) + 2 * JSON_OBJECT_SIZE(1) + 8 - }, - { - "[',2,3]", - "[false,true]", - 10, - DeserializationError::IncompleteInput, - "[]", - JSON_ARRAY_SIZE(0) - }, - { - "[\",2,3]", - "[false,true]", - 10, - DeserializationError::IncompleteInput, - "[]", - JSON_ARRAY_SIZE(0) - }, - { - // detect errors in skipped value - "[!,2,\\]", - "[false]", - 10, - DeserializationError::InvalidInput, - "[]", - JSON_ARRAY_SIZE(0) - }, - { - // detect incomplete string event if it's skipped - "\"ABC", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // detect incomplete string event if it's skipped - "'ABC", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // handle escaped quotes - "'A\\'BC'", - "false", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - // handle escaped quotes - "\"A\\\"BC\"", - "false", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - // detect incomplete string in presence of escaped quotes - "'A\\'BC", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // detect incomplete string in presence of escaped quotes - "\"A\\\"BC", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // skip empty array - "[]", - "false", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - // skip empty array with spaces - " [ ] ", - "false", - 10, - DeserializationError::Ok, - "null", - 0 - }, - { - // bubble up element error even if array is skipped - "[1,'2,3]", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // bubble up member error even if object is skipped - "{'hello':'worl}", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // bubble up colon error even if object is skipped - "{'hello','world'}", - "false", - 10, - DeserializationError::InvalidInput, - "null", - 0 - }, - { - // bubble up key error even if object is skipped - "{'hello:1}", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // detect invalid value in skipped object - "{'hello':!}", - "false", - 10, - DeserializationError::InvalidInput, - "null", - 0 - }, - { - // ignore invalid value in skipped object - "{'hello':\\}", - "false", - 10, - DeserializationError::InvalidInput, - "null", - 0 - }, - { - // check nesting limit even for ignored objects - "{}", - "false", - 0, - DeserializationError::TooDeep, - "null", - 0 - }, - { - // check nesting limit even for ignored objects - "{'hello':{}}", - "false", - 1, - DeserializationError::TooDeep, - "null", - 0 - }, - { - // check nesting limit even for ignored values in objects - "{'hello':{}}", - "{}", - 1, - DeserializationError::TooDeep, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // check nesting limit even for ignored arrays - "[]", - "false", - 0, - DeserializationError::TooDeep, - "null", - 0 - }, - { - // check nesting limit even for ignored arrays - "[[]]", - "false", - 1, - DeserializationError::TooDeep, - "null", - 0 - }, - { - // check nesting limit even for ignored values in arrays - "[[]]", - "[]", - 1, - DeserializationError::TooDeep, - "[]", - JSON_ARRAY_SIZE(0) - }, - { - // supports back-slash at the end of skipped string - "\"hell\\", - "false", - 1, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // invalid comment at after an element in a skipped array - "[1/]", - "false", - 10, - DeserializationError::InvalidInput, - "null", - 0 - }, - { - // incomplete comment at after an element in a skipped array - "[1/*]", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // missing comma in a skipped array - "[1 2]", - "false", - 10, - DeserializationError::InvalidInput, - "null", - 0 - }, - { - // invalid comment at the beginning of array - "[/1]", - "[false]", - 10, - DeserializationError::InvalidInput, - "[]", - JSON_ARRAY_SIZE(0) - }, - { - // incomplete comment at the begining of an array - "[/*]", - "[false]", - 10, - DeserializationError::IncompleteInput, - "[]", - JSON_ARRAY_SIZE(0) - }, - { - // invalid comment before key - "{/1:2}", - "{}", - 10, - DeserializationError::InvalidInput, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // incomplete comment before key - "{/*:2}", - "{}", - 10, - DeserializationError::IncompleteInput, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // invalid comment after key - "{\"example\"/1:2}", - "{}", - 10, - DeserializationError::InvalidInput, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // incomplete comment after key - "{\"example\"/*:2}", - "{}", - 10, - DeserializationError::IncompleteInput, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // invalid comment after colon - "{\"example\":/12}", - "{}", - 10, - DeserializationError::InvalidInput, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // incomplete comment after colon - "{\"example\":/*2}", - "{}", - 10, - DeserializationError::IncompleteInput, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // comment next to an integer - "{\"ignore\":1//,\"example\":2\n}", - "{\"example\":true}", - 10, - DeserializationError::Ok, - "{}", - JSON_OBJECT_SIZE(0) - }, - { - // invalid comment after opening brace of a skipped object - "{/1:2}", - "false", - 10, - DeserializationError::InvalidInput, - "null", - 0 - }, - { - // incomplete after opening brace of a skipped object - "{/*:2}", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // invalid comment after key of a skipped object - "{\"example\"/:2}", - "false", - 10, - DeserializationError::InvalidInput, - "null", - 0 - }, - { - // incomplete comment after key of a skipped object - "{\"example\"/*:2}", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // invalid comment after value in a skipped object - "{\"example\":2/}", - "false", - 10, - DeserializationError::InvalidInput, - "null", - 0 - }, - { - // incomplete comment after value of a skipped object - "{\"example\":2/*}", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - { - // incomplete comment after comma in skipped object - "{\"example\":2,/*}", - "false", - 10, - DeserializationError::IncompleteInput, - "null", - 0 - }, - }; // clang-format on - - for (size_t i = 0; i < sizeof(testCases) / sizeof(testCases[0]); i++) { - CAPTURE(i); - - DynamicJsonDocument filter(256); - DynamicJsonDocument doc(256); - TestCase& tc = testCases[i]; - - CAPTURE(tc.filter); - REQUIRE(deserializeJson(filter, tc.filter) == DeserializationError::Ok); - - CAPTURE(tc.input); - CAPTURE(tc.nestingLimit); - CHECK(deserializeJson(doc, tc.input, DeserializationOption::Filter(filter), - DeserializationOption::NestingLimit( - tc.nestingLimit)) == tc.error); - - CHECK(doc.as() == tc.output); - CHECK(doc.memoryUsage() == tc.memoryUsage); - } -} + { + "Input is object, filter is null", // description + "{\"hello\":\"world\"}", // input + "null", // filter + 10, // nestingLimit + DeserializationError::Ok, // error + "null", // output + 0, // memoryUsage + }, + { + "Input is object, filter is false", + "{\"hello\":\"world\"}", + "false", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Input is object, filter is true", + "{\"abcdefg\":\"hijklmn\"}", + "true", + 10, + DeserializationError::Ok, + "{\"abcdefg\":\"hijklmn\"}", + sizeofObject(1) + sizeofString("abcdefg") + sizeofString("hijklmn"), + }, + { + "Input is object, filter is empty object", + "{\"hello\":\"world\"}", + "{}", + 10, + DeserializationError::Ok, + "{}", + sizeofObject(0), + }, + { + "Input in an object, but filter wants an array", + "{\"hello\":\"world\"}", + "[]", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Member is a string, but filter wants an array", + "{\"example\":\"example\"}", + "{\"example\":[true]}", + 10, + DeserializationError::Ok, + "{\"example\":null}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Member is a number, but filter wants an array", + "{\"example\":42}", + "{\"example\":[true]}", + 10, + DeserializationError::Ok, + "{\"example\":null}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Input is an array, but filter wants an object", + "[\"hello\",\"world\"]", + "{}", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Input is a bool, but filter wants an object", + "true", + "{}", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Input is a string, but filter wants an object", + "\"hello\"", + "{}", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Skip an integer", + "{\"an_integer\":666,example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip a float", + "{\"a_float\":12.34e-6,example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip false", + "{\"a_bool\":false,example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip true", + "{\"a_bool\":true,example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip null", + "{\"a_bool\":null,example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip a double-quoted string", + "{\"a_double_quoted_string\":\"hello\",example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip a single-quoted string", + "{\"a_single_quoted_string\":'hello',example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip an empty array", + "{\"an_empty_array\":[],example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip an empty array with spaces in it", + "{\"an_empty_array\":[\t],example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip an array", + "{\"an_array\":[1,2,3],example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip an array with spaces in it", + "{\"an_array\": [ 1 , 2 , 3 ] ,example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip an empty nested object", + "{\"an_empty_object\":{},example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip an empty nested object with spaces in it", + "{\"an_empty_object\":{ },example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip a nested object", + "{\"an_object\":{a:1,'b':2,\"c\":3},example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip an object with spaces in it", + "{\"an_object\" : { a : 1 , 'b' : 2 , \"c\" : 3 } ,example:42}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{\"example\":42}", + sizeofObject(1) + sizeofString("example"), + }, + { + "Skip a string in a nested object", + "{\"an_integer\": 0,\"example\":{\"type\":\"int\",\"outcome\":42}}", + "{\"example\":{\"outcome\":true}}", + 10, + DeserializationError::Ok, + "{\"example\":{\"outcome\":42}}", + 2 * sizeofObject(1) + 2 * sizeofString("example"), + }, + { + "wildcard", + "{\"example\":{\"type\":\"int\",\"outcome\":42}}", + "{\"*\":{\"outcome\":true}}", + 10, + DeserializationError::Ok, + "{\"example\":{\"outcome\":42}}", + 2 * sizeofObject(1) + 2 * sizeofString("example"), + }, + { + "exclusion filter (issue #1628)", + "{\"example\":1,\"ignored\":2}", + "{\"*\":true,\"ignored\":false}", + 10, + DeserializationError::Ok, + "{\"example\":1}", + sizeofObject(1) + sizeofString("example"), + }, + { + "only the first element of array counts", + "[1,2,3]", + "[true, false]", + 10, + DeserializationError::Ok, + "[1,2,3]", + sizeofArray(3), + }, + { + "only the first element of array counts", + "[1,2,3]", + "[false, true]", + 10, + DeserializationError::Ok, + "[]", + sizeofArray(0), + }, + { + "filter members of object in array", + "[{\"example\":1,\"ignore\":2},{\"example\":3,\"ignore\":4}]", + "[{\"example\":true}]", + 10, + DeserializationError::Ok, + "[{\"example\":1},{\"example\":3}]", + sizeofArray(2) + 2 * sizeofObject(1) + sizeofString("example"), + }, + { + "Unclosed single quote in skipped element", + "[',2,3]", + "[false,true]", + 10, + DeserializationError::IncompleteInput, + "[]", + sizeofArray(0), + }, + { + "Unclosed double quote in skipped element", + "[\",2,3]", + "[false,true]", + 10, + DeserializationError::IncompleteInput, + "[]", + sizeofArray(0), + }, + { + "Detect errors in skipped value", + "[!,2,\\]", + "[false]", + 10, + DeserializationError::InvalidInput, + "[]", + sizeofArray(0), + }, + { + "Detect incomplete string event if it's skipped", + "\"ABC", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Detect incomplete string event if it's skipped", + "'ABC", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Handle escaped quotes", + "'A\\'BC'", + "false", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Handle escaped quotes", + "\"A\\\"BC\"", + "false", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Detect incomplete string in presence of escaped quotes", + "'A\\'BC", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Detect incomplete string in presence of escaped quotes", + "\"A\\\"BC", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "skip empty array", + "[]", + "false", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Skip empty array with spaces", + " [ ] ", + "false", + 10, + DeserializationError::Ok, + "null", + 0, + }, + { + "Bubble up element error even if array is skipped", + "[1,'2,3]", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Bubble up member error even if object is skipped", + "{'hello':'worl}", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Bubble up colon error even if object is skipped", + "{'hello','world'}", + "false", + 10, + DeserializationError::InvalidInput, + "null", + 0, + }, + { + "Bubble up key error even if object is skipped", + "{'hello:1}", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Detect invalid value in skipped object", + "{'hello':!}", + "false", + 10, + DeserializationError::InvalidInput, + "null", + 0, + }, + { + "Ignore invalid value in skipped object", + "{'hello':\\}", + "false", + 10, + DeserializationError::InvalidInput, + "null", + 0, + }, + { + "Check nesting limit even for ignored objects", + "{}", + "false", + 0, + DeserializationError::TooDeep, + "null", + 0, + }, + { + "Check nesting limit even for ignored objects", + "{'hello':{}}", + "false", + 1, + DeserializationError::TooDeep, + "null", + 0, + }, + { + "Check nesting limit even for ignored values in objects", + "{'hello':{}}", + "{}", + 1, + DeserializationError::TooDeep, + "{}", + sizeofObject(0), + }, + { + "Check nesting limit even for ignored arrays", + "[]", + "false", + 0, + DeserializationError::TooDeep, + "null", + 0, + }, + { + "Check nesting limit even for ignored arrays", + "[[]]", + "false", + 1, + DeserializationError::TooDeep, + "null", + 0, + }, + { + "Check nesting limit even for ignored values in arrays", + "[[]]", + "[]", + 1, + DeserializationError::TooDeep, + "[]", + sizeofArray(0), + }, + { + "Supports back-slash at the end of skipped string", + "\"hell\\", + "false", + 1, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Invalid comment at after an element in a skipped array", + "[1/]", + "false", + 10, + DeserializationError::InvalidInput, + "null", + 0, + }, + { + "Incomplete comment at after an element in a skipped array", + "[1/*]", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Missing comma in a skipped array", + "[1 2]", + "false", + 10, + DeserializationError::InvalidInput, + "null", + 0, + }, + { + "Invalid comment at the beginning of array", + "[/1]", + "[false]", + 10, + DeserializationError::InvalidInput, + "[]", + sizeofArray(0), + }, + { + "Incomplete comment at the begining of an array", + "[/*]", + "[false]", + 10, + DeserializationError::IncompleteInput, + "[]", + sizeofArray(0), + }, + { + "Invalid comment before key", + "{/1:2}", + "{}", + 10, + DeserializationError::InvalidInput, + "{}", + sizeofObject(0), + }, + { + "Incomplete comment before key", + "{/*:2}", + "{}", + 10, + DeserializationError::IncompleteInput, + "{}", + sizeofObject(0), + }, + { + "Invalid comment after key", + "{\"example\"/1:2}", + "{}", + 10, + DeserializationError::InvalidInput, + "{}", + sizeofObject(0), + }, + { + "Incomplete comment after key", + "{\"example\"/*:2}", + "{}", + 10, + DeserializationError::IncompleteInput, + "{}", + sizeofObject(0), + }, + { + "Invalid comment after colon", + "{\"example\":/12}", + "{}", + 10, + DeserializationError::InvalidInput, + "{}", + sizeofObject(0), + }, + { + "Incomplete comment after colon", + "{\"example\":/*2}", + "{}", + 10, + DeserializationError::IncompleteInput, + "{}", + sizeofObject(0), + }, + { + "Comment next to an integer", + "{\"ignore\":1//,\"example\":2\n}", + "{\"example\":true}", + 10, + DeserializationError::Ok, + "{}", + sizeofObject(0), + }, + { + "Invalid comment after opening brace of a skipped object", + "{/1:2}", + "false", + 10, + DeserializationError::InvalidInput, + "null", + 0, + }, + { + "Incomplete after opening brace of a skipped object", + "{/*:2}", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Invalid comment after key of a skipped object", + "{\"example\"/:2}", + "false", + 10, + DeserializationError::InvalidInput, + "null", + 0, + }, + { + "Incomplete comment after key of a skipped object", + "{\"example\"/*:2}", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Invalid comment after value in a skipped object", + "{\"example\":2/}", + "false", + 10, + DeserializationError::InvalidInput, + "null", + 0, + }, + { + "Incomplete comment after value of a skipped object", + "{\"example\":2/*}", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + { + "Incomplete comment after comma in skipped object", + "{\"example\":2,/*}", + "false", + 10, + DeserializationError::IncompleteInput, + "null", + 0, + }, + }; + + for (auto& tc : testCases) { + SECTION(tc.description) { + SpyingAllocator spy; + JsonDocument filter; + JsonDocument doc(&spy); -TEST_CASE("Zero-copy mode") { // issue #1697 - char input[] = "{\"include\":42,\"exclude\":666}"; + REQUIRE(deserializeJson(filter, tc.filter) == DeserializationError::Ok); - StaticJsonDocument<256> filter; - filter["include"] = true; + CHECK(deserializeJson( + doc, tc.input, DeserializationOption::Filter(filter), + DeserializationOption::NestingLimit(tc.nestingLimit)) == + tc.error); - StaticJsonDocument<256> doc; - DeserializationError err = - deserializeJson(doc, input, DeserializationOption::Filter(filter)); + CHECK(doc.as() == tc.output); - REQUIRE(err == DeserializationError::Ok); - CHECK(doc.as() == "{\"include\":42}"); + doc.shrinkToFit(); + CHECK(spy.allocatedBytes() == tc.memoryUsage); + } + } } TEST_CASE("Overloads") { - StaticJsonDocument<256> doc; - StaticJsonDocument<256> filter; + JsonDocument doc; + JsonDocument filter; using namespace DeserializationOption; @@ -807,3 +805,17 @@ TEST_CASE("Overloads") { } #endif } + +TEST_CASE("shrink filter") { + JsonDocument doc; + SpyingAllocator spy; + JsonDocument filter(&spy); + filter["a"] = true; + spy.clearLog(); + + deserializeJson(doc, "{}", DeserializationOption::Filter(filter)); + + REQUIRE(spy.log() == AllocatorLog{ + Reallocate(sizeofPool(), sizeofObject(1)), + }); +} diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/input_types.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/input_types.cpp index 788319f..94f3c0e 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/input_types.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/input_types.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,25 +7,34 @@ #include #include +#include "Allocators.hpp" #include "CustomReader.hpp" +using ArduinoJson::detail::sizeofObject; + TEST_CASE("deserializeJson(char*)") { - StaticJsonDocument<1024> doc; + SpyingAllocator spy; + JsonDocument doc(&spy); - SECTION("should not duplicate strings") { - char input[] = "{\"hello\":\"world\"}"; + char input[] = "{\"hello\":\"world\"}"; - DeserializationError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == DeserializationError::Ok); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1)); - CHECK(doc.as().memoryUsage() == - JSON_OBJECT_SIZE(1)); // issue #1318 - } + REQUIRE(err == DeserializationError::Ok); + + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("hello")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("world")), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } TEST_CASE("deserializeJson(unsigned char*, unsigned int)") { // issue #1897 - StaticJsonDocument<1024> doc; + JsonDocument doc; unsigned char input[] = "{\"hello\":\"world\"}"; unsigned char* input_ptr = input; @@ -37,7 +46,7 @@ TEST_CASE("deserializeJson(unsigned char*, unsigned int)") { // issue #1897 } TEST_CASE("deserializeJson(uint8_t*, size_t)") { // issue #1898 - StaticJsonDocument<1024> doc; + JsonDocument doc; uint8_t input[] = "{\"hello\":\"world\"}"; uint8_t* input_ptr = input; @@ -49,7 +58,7 @@ TEST_CASE("deserializeJson(uint8_t*, size_t)") { // issue #1898 } TEST_CASE("deserializeJson(const std::string&)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("should accept const string") { const std::string input("[42]"); @@ -78,7 +87,7 @@ TEST_CASE("deserializeJson(const std::string&)") { } TEST_CASE("deserializeJson(std::istream&)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("array") { std::istringstream json(" [ 42 ] "); @@ -149,7 +158,7 @@ TEST_CASE("deserializeJson(VLA)") { char vla[i]; strcpy(vla, "{\"a\":42}"); - StaticJsonDocument doc; + JsonDocument doc; DeserializationError err = deserializeJson(doc, vla); REQUIRE(err == DeserializationError::Ok); @@ -157,7 +166,7 @@ TEST_CASE("deserializeJson(VLA)") { #endif TEST_CASE("deserializeJson(CustomReader)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; CustomReader reader("[4,2]"); DeserializationError err = deserializeJson(doc, reader); @@ -168,10 +177,10 @@ TEST_CASE("deserializeJson(CustomReader)") { } TEST_CASE("deserializeJson(JsonDocument&, MemberProxy)") { - DynamicJsonDocument doc1(4096); + JsonDocument doc1; doc1["payload"] = "[4,2]"; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; DeserializationError err = deserializeJson(doc2, doc1["payload"]); REQUIRE(err == DeserializationError::Ok); @@ -181,10 +190,10 @@ TEST_CASE("deserializeJson(JsonDocument&, MemberProxy)") { } TEST_CASE("deserializeJson(JsonDocument&, JsonVariant)") { - DynamicJsonDocument doc1(4096); + JsonDocument doc1; doc1["payload"] = "[4,2]"; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; DeserializationError err = deserializeJson(doc2, doc1["payload"].as()); @@ -195,10 +204,10 @@ TEST_CASE("deserializeJson(JsonDocument&, JsonVariant)") { } TEST_CASE("deserializeJson(JsonDocument&, JsonVariantConst)") { - DynamicJsonDocument doc1(4096); + JsonDocument doc1; doc1["payload"] = "[4,2]"; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; DeserializationError err = deserializeJson(doc2, doc1["payload"].as()); @@ -209,10 +218,10 @@ TEST_CASE("deserializeJson(JsonDocument&, JsonVariantConst)") { } TEST_CASE("deserializeJson(JsonDocument&, ElementProxy)") { - DynamicJsonDocument doc1(4096); + JsonDocument doc1; doc1[0] = "[4,2]"; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; DeserializationError err = deserializeJson(doc2, doc1[0]); REQUIRE(err == DeserializationError::Ok); diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/misc.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/misc.cpp index 4f22de1..cc5d10f 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/misc.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/misc.cpp @@ -1,117 +1,49 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include -using namespace Catch::Matchers; +#include "Allocators.hpp" -TEST_CASE("deserializeJson(DynamicJsonDocument&)") { - DynamicJsonDocument doc(4096); +using ArduinoJson::detail::sizeofArray; - SECTION("Edge cases") { - SECTION("null char*") { - DeserializationError err = deserializeJson(doc, static_cast(0)); +TEST_CASE("deserializeJson() misc cases") { + SpyingAllocator spy; + JsonDocument doc(&spy); - REQUIRE(err != DeserializationError::Ok); - } - - SECTION("null const char*") { - DeserializationError err = - deserializeJson(doc, static_cast(0)); - - REQUIRE(err != DeserializationError::Ok); - } - - SECTION("Empty input") { - DeserializationError err = deserializeJson(doc, ""); - - REQUIRE(err == DeserializationError::EmptyInput); - } - - SECTION("Only spaces") { - DeserializationError err = deserializeJson(doc, " \t\n\r"); - - REQUIRE(err == DeserializationError::EmptyInput); - } - - SECTION("issue #628") { - DeserializationError err = deserializeJson(doc, "null"); - REQUIRE(err == DeserializationError::Ok); - REQUIRE(doc.is() == false); - } - - SECTION("Garbage") { - DeserializationError err = deserializeJson(doc, "%*$£¤"); - - REQUIRE(err == DeserializationError::InvalidInput); - } + SECTION("null") { + DeserializationError err = deserializeJson(doc, "null"); + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.is() == false); } - SECTION("Booleans") { - SECTION("True") { - DeserializationError err = deserializeJson(doc, "true"); + SECTION("true") { + DeserializationError err = deserializeJson(doc, "true"); - REQUIRE(err == DeserializationError::Ok); - REQUIRE(doc.is()); - REQUIRE(doc.as() == true); - } - - SECTION("False") { - DeserializationError err = deserializeJson(doc, "false"); - - REQUIRE(err == DeserializationError::Ok); - REQUIRE(doc.is()); - REQUIRE(doc.as() == false); - } + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.as() == true); } - SECTION("Premature null-terminator") { - SECTION("In escape sequence") { - DeserializationError err = deserializeJson(doc, "\"\\"); - - REQUIRE(err == DeserializationError::IncompleteInput); - } + SECTION("false") { + DeserializationError err = deserializeJson(doc, "false"); - SECTION("In double quoted string") { - DeserializationError err = deserializeJson(doc, "\"hello"); - - REQUIRE(err == DeserializationError::IncompleteInput); - } - - SECTION("In single quoted string") { - DeserializationError err = deserializeJson(doc, "'hello"); - - REQUIRE(err == DeserializationError::IncompleteInput); - } - } - - SECTION("Premature end of input") { - SECTION("In escape sequence") { - DeserializationError err = deserializeJson(doc, "\"\\n\"", 2); - - REQUIRE(err == DeserializationError::IncompleteInput); - } - - SECTION("In double quoted string") { - DeserializationError err = deserializeJson(doc, "\"hello\"", 6); - - REQUIRE(err == DeserializationError::IncompleteInput); - } - - SECTION("In single quoted string") { - DeserializationError err = deserializeJson(doc, "'hello'", 6); - - REQUIRE(err == DeserializationError::IncompleteInput); - } + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.as() == false); } SECTION("Should clear the JsonVariant") { deserializeJson(doc, "[1,2,3]"); + spy.clearLog(); + deserializeJson(doc, "{}"); REQUIRE(doc.is()); - REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofArray(3)), + }); } } diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/nestingLimit.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/nestingLimit.cpp index cf55dc8..c5c5403 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/nestingLimit.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/nestingLimit.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -12,7 +12,7 @@ REQUIRE(DeserializationError::TooDeep == expression); TEST_CASE("JsonDeserializer nesting") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("Input = const char*") { SECTION("limit = 0") { diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/number.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/number.cpp index 05cf89e..5359573 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/number.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/number.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_USE_LONG_LONG 0 @@ -16,7 +16,7 @@ using ArduinoJson::detail::isnan; } // namespace my TEST_CASE("deserialize an integer") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("Integer") { SECTION("0") { diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/object.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/object.cpp index 814258e..501e87a 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/object.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/object.cpp @@ -1,12 +1,17 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofObject; + TEST_CASE("deserialize JSON object") { - DynamicJsonDocument doc(4096); + SpyingAllocator spy; + JsonDocument doc(&spy); SECTION("An empty object") { DeserializationError err = deserializeJson(doc, "{}"); @@ -277,7 +282,22 @@ TEST_CASE("deserialize JSON object") { DeserializationError err = deserializeJson(doc, "{a:{b:{c:1}},a:2}"); REQUIRE(err == DeserializationError::Ok); - REQUIRE(doc["a"] == 2); + REQUIRE(doc.as() == "{\"a\":2}"); + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("a")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("b")), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("c")), + Allocate(sizeofStringBuffer()), + Deallocate(sizeofString("b")), + Deallocate(sizeofString("c")), + Deallocate(sizeofStringBuffer()), + Reallocate(sizeofPool(), sizeofObject(2) + sizeofObject(1)), + }); } SECTION("Repeated key with zero copy mode") { // issue #1697 @@ -299,12 +319,17 @@ TEST_CASE("deserialize JSON object") { SECTION("Should clear the JsonObject") { deserializeJson(doc, "{\"hello\":\"world\"}"); + spy.clearLog(); + deserializeJson(doc, "{}"); - JsonObject obj = doc.as(); REQUIRE(doc.is()); - REQUIRE(obj.size() == 0); - REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + REQUIRE(doc.size() == 0); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofObject(1)), + Deallocate(sizeofString("hello")), + Deallocate(sizeofString("world")), + }); } SECTION("Issue #1335") { @@ -313,3 +338,48 @@ TEST_CASE("deserialize JSON object") { CHECK(doc.as() == json); } } + +TEST_CASE("deserialize JSON object under memory constraints") { + TimebombAllocator timebomb(1024); + JsonDocument doc(&timebomb); + + SECTION("empty object requires no allocation") { + timebomb.setCountdown(0); + char input[] = "{}"; + + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "{}"); + } + + SECTION("key allocation fails") { + timebomb.setCountdown(0); + char input[] = "{\"a\":1}"; + + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::NoMemory); + REQUIRE(doc.as() == "{}"); + } + + SECTION("pool allocation fails") { + timebomb.setCountdown(2); + char input[] = "{\"a\":1}"; + + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::NoMemory); + REQUIRE(doc.as() == "{}"); + } + + SECTION("string allocation fails") { + timebomb.setCountdown(3); + char input[] = "{\"a\":\"b\"}"; + + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::NoMemory); + REQUIRE(doc.as() == "{\"a\":null}"); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonDeserializer/string.cpp b/third-party/ArduinoJson/extras/tests/JsonDeserializer/string.cpp index 2379d45..a47ab76 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDeserializer/string.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDeserializer/string.cpp @@ -1,11 +1,16 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_DECODE_UNICODE 1 #include #include +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; +using ArduinoJson::detail::sizeofObject; + TEST_CASE("Valid JSON strings value") { struct TestCase { const char* input; @@ -35,7 +40,7 @@ TEST_CASE("Valid JSON strings value") { }; const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); - DynamicJsonDocument doc(4096); + JsonDocument doc; for (size_t i = 0; i < testCount; i++) { const TestCase& testCase = testCases[i]; @@ -47,7 +52,7 @@ TEST_CASE("Valid JSON strings value") { } TEST_CASE("\\u0000") { - StaticJsonDocument<200> doc; + JsonDocument doc; DeserializationError err = deserializeJson(doc, "\"wx\\u0000yz\""); REQUIRE(err == DeserializationError::Ok); @@ -68,7 +73,7 @@ TEST_CASE("Truncated JSON string") { const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000"}; const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); - DynamicJsonDocument doc(4096); + JsonDocument doc; for (size_t i = 0; i < testCount; i++) { const char* input = testCases[i]; @@ -83,7 +88,7 @@ TEST_CASE("Invalid JSON string") { "'\\u000G'", "'\\u000/'", "'\\x1234'"}; const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); - DynamicJsonDocument doc(4096); + JsonDocument doc; for (size_t i = 0; i < testCount; i++) { const char* input = testCases[i]; @@ -92,41 +97,102 @@ TEST_CASE("Invalid JSON string") { } } -TEST_CASE("Not enough room to save the key") { - DynamicJsonDocument doc(JSON_OBJECT_SIZE(1) + 8); +TEST_CASE("Allocation of the key fails") { + TimebombAllocator timebomb(0); + SpyingAllocator spy(&timebomb); + JsonDocument doc(&spy); - SECTION("Quoted string") { + SECTION("Quoted string, first member") { REQUIRE(deserializeJson(doc, "{\"example\":1}") == - DeserializationError::Ok); - REQUIRE(deserializeJson(doc, "{\"accuracy\":1}") == DeserializationError::NoMemory); + REQUIRE(spy.log() == AllocatorLog{ + AllocateFail(sizeofStringBuffer()), + }); + } + + SECTION("Quoted string, second member") { + timebomb.setCountdown(3); REQUIRE(deserializeJson(doc, "{\"hello\":1,\"world\"}") == - DeserializationError::NoMemory); // fails in the second string + DeserializationError::NoMemory); + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("hello")), + Allocate(sizeofPool()), + AllocateFail(sizeofStringBuffer()), + ReallocateFail(sizeofPool(), sizeofObject(1)), + }); } - SECTION("Non-quoted string") { - REQUIRE(deserializeJson(doc, "{example:1}") == DeserializationError::Ok); - REQUIRE(deserializeJson(doc, "{accuracy:1}") == + SECTION("Non-Quoted string, first member") { + REQUIRE(deserializeJson(doc, "{example:1}") == DeserializationError::NoMemory); + REQUIRE(spy.log() == AllocatorLog{ + AllocateFail(sizeofStringBuffer()), + }); + } + + SECTION("Non-Quoted string, second member") { + timebomb.setCountdown(3); REQUIRE(deserializeJson(doc, "{hello:1,world}") == - DeserializationError::NoMemory); // fails in the second string + DeserializationError::NoMemory); + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("hello")), + Allocate(sizeofPool()), + AllocateFail(sizeofStringBuffer()), + ReallocateFail(sizeofPool(), sizeofObject(1)), + }); } } -TEST_CASE("Empty memory pool") { - // NOLINTNEXTLINE(clang-analyzer-optin.portability.UnixAPI) - DynamicJsonDocument doc(0); +TEST_CASE("String allocation fails") { + SpyingAllocator spy(FailingAllocator::instance()); + JsonDocument doc(&spy); SECTION("Input is const char*") { REQUIRE(deserializeJson(doc, "\"hello\"") == DeserializationError::NoMemory); - REQUIRE(deserializeJson(doc, "\"\"") == DeserializationError::NoMemory); + REQUIRE(spy.log() == AllocatorLog{ + AllocateFail(sizeofStringBuffer()), + }); } +} - SECTION("Input is const char*") { - char hello[] = "\"hello\""; - REQUIRE(deserializeJson(doc, hello) == DeserializationError::Ok); - char empty[] = "\"hello\""; - REQUIRE(deserializeJson(doc, empty) == DeserializationError::Ok); - } +TEST_CASE("Deduplicate values") { + SpyingAllocator spy; + JsonDocument doc(&spy); + deserializeJson(doc, "[\"example\",\"example\"]"); + + CHECK(doc[0].as() == doc[1].as()); + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("example")), + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + Reallocate(sizeofPool(), sizeofArray(2)), + }); +} + +TEST_CASE("Deduplicate keys") { + SpyingAllocator spy; + JsonDocument doc(&spy); + deserializeJson(doc, "[{\"example\":1},{\"example\":2}]"); + + const char* key1 = doc[0].as().begin()->key().c_str(); + const char* key2 = doc[1].as().begin()->key().c_str(); + CHECK(key1 == key2); + + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("example")), + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + Reallocate(sizeofPool(), sizeofArray(2) + 2 * sizeofObject(1)), + }); } diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonDocument/CMakeLists.txt index 3e9b468..e6b6f1d 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/CMakeLists.txt @@ -1,15 +1,15 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(JsonDocumentTests add.cpp - BasicJsonDocument.cpp + assignment.cpp cast.cpp + clear.cpp compare.cpp + constructor.cpp containsKey.cpp - createNested.cpp - DynamicJsonDocument.cpp ElementProxy.cpp isNull.cpp issue1120.cpp @@ -19,7 +19,6 @@ add_executable(JsonDocumentTests remove.cpp shrinkToFit.cpp size.cpp - StaticJsonDocument.cpp subscript.cpp swap.cpp ) diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/ElementProxy.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/ElementProxy.cpp index 00fcdda..d13f210 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/ElementProxy.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/ElementProxy.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,8 +8,8 @@ typedef ArduinoJson::detail::ElementProxy ElementProxy; TEST_CASE("ElementProxy::add()") { - DynamicJsonDocument doc(4096); - doc.add(); + JsonDocument doc; + doc.add(); ElementProxy ep = doc[0]; SECTION("add(int)") { @@ -34,8 +34,8 @@ TEST_CASE("ElementProxy::add()") { } TEST_CASE("ElementProxy::clear()") { - DynamicJsonDocument doc(4096); - doc.add(); + JsonDocument doc; + doc.add(); ElementProxy ep = doc[0]; SECTION("size goes back to zero") { @@ -54,7 +54,7 @@ TEST_CASE("ElementProxy::clear()") { } TEST_CASE("ElementProxy::operator==()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("1 vs 1") { doc.add(1); @@ -94,8 +94,8 @@ TEST_CASE("ElementProxy::operator==()") { } TEST_CASE("ElementProxy::remove()") { - DynamicJsonDocument doc(4096); - doc.add(); + JsonDocument doc; + doc.add(); ElementProxy ep = doc[0]; SECTION("remove(int)") { @@ -142,7 +142,7 @@ TEST_CASE("ElementProxy::remove()") { } TEST_CASE("ElementProxy::set()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; ElementProxy ep = doc[0]; SECTION("set(int)") { @@ -167,8 +167,8 @@ TEST_CASE("ElementProxy::set()") { } TEST_CASE("ElementProxy::size()") { - DynamicJsonDocument doc(4096); - doc.add(); + JsonDocument doc; + doc.add(); ElementProxy ep = doc[0]; SECTION("returns 0") { @@ -188,23 +188,8 @@ TEST_CASE("ElementProxy::size()") { } } -TEST_CASE("ElementProxy::memoryUsage()") { - DynamicJsonDocument doc(4096); - doc.add(); - ElementProxy ep = doc[0]; - - SECTION("returns 0 for null") { - REQUIRE(ep.memoryUsage() == 0); - } - - SECTION("returns size for string") { - ep.set(std::string("hello")); - REQUIRE(ep.memoryUsage() == 6); - } -} - TEST_CASE("ElementProxy::operator[]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; ElementProxy ep = doc[1]; SECTION("set member") { @@ -221,7 +206,7 @@ TEST_CASE("ElementProxy::operator[]") { } TEST_CASE("ElementProxy cast to JsonVariantConst") { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc[0] = "world"; const ElementProxy ep = doc[0]; @@ -232,7 +217,7 @@ TEST_CASE("ElementProxy cast to JsonVariantConst") { } TEST_CASE("ElementProxy cast to JsonVariant") { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc[0] = "world"; ElementProxy ep = doc[0]; @@ -245,11 +230,3 @@ TEST_CASE("ElementProxy cast to JsonVariant") { CHECK(doc.as() == "[\"toto\"]"); } - -TEST_CASE("ElementProxy::shallowCopy()") { - StaticJsonDocument<1024> doc1, doc2; - doc2["hello"] = "world"; - doc1[0].shallowCopy(doc2); - - CHECK(doc1.as() == "[{\"hello\":\"world\"}]"); -} diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/MemberProxy.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/MemberProxy.cpp index a3707b0..5bdafa0 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/MemberProxy.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/MemberProxy.cpp @@ -1,15 +1,23 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License +#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 +#define ARDUINOJSON_ENABLE_PROGMEM 1 #include + #include +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; +using ArduinoJson::detail::sizeofObject; + typedef ArduinoJson::detail::MemberProxy MemberProxy; TEST_CASE("MemberProxy::add()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; MemberProxy mp = doc["hello"]; SECTION("add(int)") { @@ -26,7 +34,7 @@ TEST_CASE("MemberProxy::add()") { } TEST_CASE("MemberProxy::clear()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; MemberProxy mp = doc["hello"]; SECTION("size goes back to zero") { @@ -45,7 +53,7 @@ TEST_CASE("MemberProxy::clear()") { } TEST_CASE("MemberProxy::operator==()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("1 vs 1") { doc["a"] = 1; @@ -85,7 +93,7 @@ TEST_CASE("MemberProxy::operator==()") { } TEST_CASE("MemberProxy::containsKey()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; MemberProxy mp = doc["hello"]; SECTION("containsKey(const char*)") { @@ -104,7 +112,7 @@ TEST_CASE("MemberProxy::containsKey()") { } TEST_CASE("MemberProxy::operator|()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("const char*") { doc["a"] = "hello"; @@ -127,7 +135,7 @@ TEST_CASE("MemberProxy::operator|()") { JsonObject object = doc.to(); object["hello"] = "world"; - StaticJsonDocument<0> emptyDoc; + JsonDocument emptyDoc; JsonObject anotherObject = object["hello"] | emptyDoc.to(); REQUIRE(anotherObject.isNull() == false); @@ -136,7 +144,7 @@ TEST_CASE("MemberProxy::operator|()") { } TEST_CASE("MemberProxy::remove()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; MemberProxy mp = doc["hello"]; SECTION("remove(int)") { @@ -183,7 +191,7 @@ TEST_CASE("MemberProxy::remove()") { } TEST_CASE("MemberProxy::set()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; MemberProxy mp = doc["hello"]; SECTION("set(int)") { @@ -208,7 +216,7 @@ TEST_CASE("MemberProxy::set()") { } TEST_CASE("MemberProxy::size()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; MemberProxy mp = doc["hello"]; SECTION("returns 0") { @@ -230,22 +238,8 @@ TEST_CASE("MemberProxy::size()") { } } -TEST_CASE("MemberProxy::memoryUsage()") { - DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; - - SECTION("returns 0 when null") { - REQUIRE(mp.memoryUsage() == 0); - } - - SECTION("return the size for a string") { - mp.set(std::string("hello")); - REQUIRE(mp.memoryUsage() == 6); - } -} - TEST_CASE("MemberProxy::operator[]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; MemberProxy mp = doc["hello"]; SECTION("set member") { @@ -262,7 +256,7 @@ TEST_CASE("MemberProxy::operator[]") { } TEST_CASE("MemberProxy cast to JsonVariantConst") { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc["hello"] = "world"; const MemberProxy mp = doc["hello"]; @@ -273,7 +267,7 @@ TEST_CASE("MemberProxy cast to JsonVariantConst") { } TEST_CASE("MemberProxy cast to JsonVariant") { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc["hello"] = "world"; MemberProxy mp = doc["hello"]; @@ -287,42 +281,83 @@ TEST_CASE("MemberProxy cast to JsonVariant") { CHECK(doc.as() == "{\"hello\":\"toto\"}"); } -TEST_CASE("MemberProxy::createNestedArray()") { - StaticJsonDocument<1024> doc; - JsonArray arr = doc["items"].createNestedArray(); - arr.add(42); +TEST_CASE("Deduplicate keys") { + SpyingAllocator spy; + JsonDocument doc(&spy); - CHECK(doc["items"][0][0] == 42); -} + SECTION("std::string") { + doc[0][std::string("example")] = 1; + doc[1][std::string("example")] = 2; -TEST_CASE("MemberProxy::createNestedArray(key)") { - StaticJsonDocument<1024> doc; - JsonArray arr = doc["weather"].createNestedArray("temp"); - arr.add(42); + const char* key1 = doc[0].as().begin()->key().c_str(); + const char* key2 = doc[1].as().begin()->key().c_str(); + CHECK(key1 == key2); - CHECK(doc["weather"]["temp"][0] == 42); -} + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + }); + } -TEST_CASE("MemberProxy::createNestedObject()") { - StaticJsonDocument<1024> doc; - JsonObject obj = doc["items"].createNestedObject(); - obj["value"] = 42; + SECTION("char*") { + char key[] = "example"; + doc[0][key] = 1; + doc[1][key] = 2; - CHECK(doc["items"][0]["value"] == 42); -} + const char* key1 = doc[0].as().begin()->key().c_str(); + const char* key2 = doc[1].as().begin()->key().c_str(); + CHECK(key1 == key2); + + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + }); + } + + SECTION("Arduino String") { + doc[0][String("example")] = 1; + doc[1][String("example")] = 2; + + const char* key1 = doc[0].as().begin()->key().c_str(); + const char* key2 = doc[1].as().begin()->key().c_str(); + CHECK(key1 == key2); + + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + }); + } + + SECTION("Flash string") { + doc[0][F("example")] = 1; + doc[1][F("example")] = 2; -TEST_CASE("MemberProxy::createNestedObject(key)") { - StaticJsonDocument<1024> doc; - JsonObject obj = doc["status"].createNestedObject("weather"); - obj["temp"] = 42; + const char* key1 = doc[0].as().begin()->key().c_str(); + const char* key2 = doc[1].as().begin()->key().c_str(); + CHECK(key1 == key2); - CHECK(doc["status"]["weather"]["temp"] == 42); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + }); + } } -TEST_CASE("MemberProxy::shallowCopy()") { - StaticJsonDocument<1024> doc1, doc2; - doc2["hello"] = "world"; - doc1["obj"].shallowCopy(doc2); +TEST_CASE("MemberProxy under memory constraints") { + KillswitchAllocator killswitch; + SpyingAllocator spy(&killswitch); + JsonDocument doc(&spy); - CHECK(doc1.as() == "{\"obj\":{\"hello\":\"world\"}}"); + SECTION("key allocation fails") { + killswitch.on(); + + doc[std::string("hello")] = "world"; + + REQUIRE(doc.is()); + REQUIRE(doc.size() == 0); + REQUIRE(doc.overflowed() == true); + REQUIRE(spy.log() == AllocatorLog{ + AllocateFail(sizeofString("hello")), + }); + } } diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/add.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/add.cpp index 5843ac9..b7fe758 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/add.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/add.cpp @@ -1,22 +1,104 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License +#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 +#define ARDUINOJSON_ENABLE_PROGMEM 1 #include + #include -TEST_CASE("JsonDocument::add()") { - DynamicJsonDocument doc(4096); +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; + +TEST_CASE("JsonDocument::add(T)") { + SpyingAllocator spy; + JsonDocument doc(&spy); SECTION("integer") { doc.add(42); REQUIRE(doc.as() == "[42]"); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); } SECTION("const char*") { doc.add("hello"); REQUIRE(doc.as() == "[\"hello\"]"); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); + } + + SECTION("std::string") { + doc.add(std::string("example")); + doc.add(std::string("example")); + + CHECK(doc[0].as() == doc[1].as()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + }); + } + + SECTION("char*") { + char value[] = "example"; + doc.add(value); + doc.add(value); + + CHECK(doc[0].as() == doc[1].as()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + }); + } + + SECTION("Arduino String") { + doc.add(String("example")); + doc.add(String("example")); + + CHECK(doc[0].as() == doc[1].as()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + }); + } + + SECTION("Flash string") { + doc.add(F("example")); + doc.add(F("example")); + + CHECK(doc[0].as() == doc[1].as()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("example")), + }); + } +} + +TEST_CASE("JsonDocument::add()") { + JsonDocument doc; + + SECTION("JsonArray") { + JsonArray array = doc.add(); + array.add(1); + array.add(2); + REQUIRE(doc.as() == "[[1,2]]"); + } + + SECTION("JsonObject") { + JsonObject object = doc.add(); + object["hello"] = "world"; + REQUIRE(doc.as() == "[{\"hello\":\"world\"}]"); + } + + SECTION("JsonVariant") { + JsonVariant variant = doc.add(); + variant.set(42); + REQUIRE(doc.as() == "[42]"); } } diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/assignment.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/assignment.cpp new file mode 100644 index 0000000..832c12b --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/assignment.cpp @@ -0,0 +1,134 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include "Allocators.hpp" + +TEST_CASE("JsonDocument assignment") { + SpyingAllocator spyingAllocator; + + SECTION("Copy assignment same capacity") { + JsonDocument doc1(&spyingAllocator); + deserializeJson(doc1, "{\"hello\":\"world\"}"); + JsonDocument doc2(&spyingAllocator); + spyingAllocator.clearLog(); + + doc2 = doc1; + + REQUIRE(doc2.as() == "{\"hello\":\"world\"}"); + + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); + } + + SECTION("Copy assignment reallocates when capacity is smaller") { + JsonDocument doc1(&spyingAllocator); + deserializeJson(doc1, "[{\"hello\":\"world\"}]"); + JsonDocument doc2(&spyingAllocator); + spyingAllocator.clearLog(); + + doc2 = doc1; + + REQUIRE(doc2.as() == "[{\"hello\":\"world\"}]"); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("hello")), + Allocate(sizeofString("world")), + }); + } + + SECTION("Copy assignment reallocates when capacity is larger") { + JsonDocument doc1(&spyingAllocator); + deserializeJson(doc1, "{\"hello\":\"world\"}"); + JsonDocument doc2(&spyingAllocator); + spyingAllocator.clearLog(); + + doc2 = doc1; + + REQUIRE(doc2.as() == "{\"hello\":\"world\"}"); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); + } + + SECTION("Move assign") { + { + JsonDocument doc1(&spyingAllocator); + doc1[std::string("hello")] = std::string("world"); + JsonDocument doc2(&spyingAllocator); + + doc2 = std::move(doc1); + + REQUIRE(doc2.as() == "{\"hello\":\"world\"}"); + REQUIRE(doc1.as() == "null"); + } + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + Deallocate(sizeofString("hello")), + Deallocate(sizeofString("world")), + Deallocate(sizeofPool()), + }); + } + + SECTION("Assign from JsonObject") { + JsonDocument doc1; + JsonObject obj = doc1.to(); + obj["hello"] = "world"; + + JsonDocument doc2; + doc2 = obj; + + REQUIRE(doc2.as() == "{\"hello\":\"world\"}"); + } + + SECTION("Assign from JsonArray") { + JsonDocument doc1; + JsonArray arr = doc1.to(); + arr.add("hello"); + + JsonDocument doc2; + doc2 = arr; + + REQUIRE(doc2.as() == "[\"hello\"]"); + } + + SECTION("Assign from JsonVariant") { + JsonDocument doc1; + deserializeJson(doc1, "42"); + + JsonDocument doc2; + doc2 = doc1.as(); + + REQUIRE(doc2.as() == "42"); + } + + SECTION("Assign from MemberProxy") { + JsonDocument doc1; + doc1["value"] = 42; + + JsonDocument doc2; + doc2 = doc1["value"]; + + REQUIRE(doc2.as() == "42"); + } + + SECTION("Assign from ElementProxy") { + JsonDocument doc1; + doc1[0] = 42; + + JsonDocument doc2; + doc2 = doc1[0]; + + REQUIRE(doc2.as() == "42"); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/cast.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/cast.cpp index 253e1fc..05c9ee7 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/cast.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/cast.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,7 +8,7 @@ #include TEST_CASE("Implicit cast to JsonVariant") { - StaticJsonDocument<128> doc; + JsonDocument doc; doc["hello"] = "world"; diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/clear.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/clear.cpp new file mode 100644 index 0000000..8d3f227 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/clear.cpp @@ -0,0 +1,47 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include // malloc, free +#include + +#include "Allocators.hpp" + +TEST_CASE("JsonDocument::clear()") { + SpyingAllocator spy; + JsonDocument doc(&spy); + + SECTION("null") { + doc.clear(); + + REQUIRE(doc.isNull()); + REQUIRE(spy.log() == AllocatorLog{}); + } + + SECTION("releases resources") { + doc[std::string("hello")] = std::string("world"); + spy.clearLog(); + + doc.clear(); + + REQUIRE(doc.isNull()); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofPool()), + Deallocate(sizeofString("hello")), + Deallocate(sizeofString("world")), + }); + } + + SECTION("clear free list") { // issue #2034 + JsonObject obj = doc.to(); + obj["a"] = 1; + obj.clear(); // puts the slot in the free list + + doc.clear(); + + doc["b"] = 2; // will it pick from the free list? + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/compare.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/compare.cpp index d834b22..a1b8ef2 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/compare.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/compare.cpp @@ -1,60 +1,13 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include -TEST_CASE("DynamicJsonDocument::operator==(const DynamicJsonDocument&)") { - DynamicJsonDocument doc1(4096); - DynamicJsonDocument doc2(4096); - - SECTION("Empty") { - REQUIRE(doc1 == doc2); - REQUIRE_FALSE(doc1 != doc2); - } - - SECTION("With same object") { - doc1["hello"] = "world"; - doc2["hello"] = "world"; - REQUIRE(doc1 == doc2); - REQUIRE_FALSE(doc1 != doc2); - } - SECTION("With different object") { - doc1["hello"] = "world"; - doc2["world"] = "hello"; - REQUIRE_FALSE(doc1 == doc2); - REQUIRE(doc1 != doc2); - } -} - -TEST_CASE("DynamicJsonDocument::operator==(const StaticJsonDocument&)") { - DynamicJsonDocument doc1(4096); - StaticJsonDocument<256> doc2; - - SECTION("Empty") { - REQUIRE(doc1 == doc2); - REQUIRE_FALSE(doc1 != doc2); - } - - SECTION("With same object") { - doc1["hello"] = "world"; - doc2["hello"] = "world"; - REQUIRE(doc1 == doc2); - REQUIRE_FALSE(doc1 != doc2); - } - - SECTION("With different object") { - doc1["hello"] = "world"; - doc2["world"] = "hello"; - REQUIRE_FALSE(doc1 == doc2); - REQUIRE(doc1 != doc2); - } -} - -TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") { - StaticJsonDocument<256> doc1; - DynamicJsonDocument doc2(4096); +TEST_CASE("JsonDocument::operator==(const JsonDocument&)") { + JsonDocument doc1; + JsonDocument doc2; SECTION("Empty") { REQUIRE(doc1 == doc2); @@ -67,7 +20,6 @@ TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") { REQUIRE(doc1 == doc2); REQUIRE_FALSE(doc1 != doc2); } - SECTION("With different object") { doc1["hello"] = "world"; doc2["world"] = "hello"; @@ -75,29 +27,3 @@ TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") { REQUIRE(doc1 != doc2); } } - -TEST_CASE("JsonDocument::operator==(const JsonDocument&)") { - StaticJsonDocument<256> doc1; - StaticJsonDocument<256> doc2; - const JsonDocument& ref1 = doc1; - const JsonDocument& ref2 = doc2; - - SECTION("Empty") { - REQUIRE(ref1 == ref2); - REQUIRE_FALSE(ref1 != ref2); - } - - SECTION("With same object") { - doc1["hello"] = "world"; - doc2["hello"] = "world"; - REQUIRE(ref1 == ref2); - REQUIRE_FALSE(ref1 != ref2); - } - - SECTION("With different object") { - doc1["hello"] = "world"; - doc2["world"] = "hello"; - REQUIRE_FALSE(ref1 == ref2); - REQUIRE(ref1 != ref2); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/constructor.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/constructor.cpp new file mode 100644 index 0000000..4d63695 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/constructor.cpp @@ -0,0 +1,120 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include "Allocators.hpp" + +using ArduinoJson::detail::addPadding; + +TEST_CASE("JsonDocument constructor") { + SpyingAllocator spyingAllocator; + + SECTION("JsonDocument(size_t)") { + { JsonDocument doc(&spyingAllocator); } + REQUIRE(spyingAllocator.log() == AllocatorLog{}); + } + + SECTION("JsonDocument(const JsonDocument&)") { + { + JsonDocument doc1(&spyingAllocator); + doc1.set(std::string("The size of this string is 32!!")); + + JsonDocument doc2(doc1); + + REQUIRE(doc1.as() == "The size of this string is 32!!"); + REQUIRE(doc2.as() == "The size of this string is 32!!"); + } + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofStringBuffer()), + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + }); + } + + SECTION("JsonDocument(JsonDocument&&)") { + { + JsonDocument doc1(&spyingAllocator); + doc1.set(std::string("The size of this string is 32!!")); + + JsonDocument doc2(std::move(doc1)); + + REQUIRE(doc2.as() == "The size of this string is 32!!"); + REQUIRE(doc1.as() == "null"); + } + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + }); + } + + SECTION("JsonDocument(JsonObject, Allocator*)") { + JsonDocument doc1; + JsonObject obj = doc1.to(); + obj["hello"] = "world"; + + JsonDocument doc2(obj, &spyingAllocator); + + REQUIRE(doc2.as() == "{\"hello\":\"world\"}"); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); + } + + SECTION("JsonDocument(JsonObject)") { + JsonDocument doc1; + JsonObject obj = doc1.to(); + obj["hello"] = "world"; + + JsonDocument doc2(obj); + + REQUIRE(doc2.as() == "{\"hello\":\"world\"}"); + } + + SECTION("JsonDocument(JsonArray, Allocator*)") { + JsonDocument doc1; + JsonArray arr = doc1.to(); + arr.add("hello"); + + JsonDocument doc2(arr, &spyingAllocator); + + REQUIRE(doc2.as() == "[\"hello\"]"); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); + } + + SECTION("JsonDocument(JsonArray)") { + JsonDocument doc1; + JsonArray arr = doc1.to(); + arr.add("hello"); + + JsonDocument doc2(arr); + + REQUIRE(doc2.as() == "[\"hello\"]"); + } + + SECTION("JsonDocument(JsonVariant, Allocator*)") { + JsonDocument doc1; + deserializeJson(doc1, "\"hello\""); + + JsonDocument doc2(doc1.as(), &spyingAllocator); + + REQUIRE(doc2.as() == "hello"); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + }); + } + + SECTION("JsonDocument(JsonVariant)") { + JsonDocument doc1; + deserializeJson(doc1, "\"hello\""); + + JsonDocument doc2(doc1.as()); + + REQUIRE(doc2.as() == "hello"); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/containsKey.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/containsKey.cpp index 8274fc7..9425e01 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/containsKey.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/containsKey.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonDocument::containsKey()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("returns true on object") { doc["hello"] = "world"; diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/isNull.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/isNull.cpp index d5aaae0..219c306 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/isNull.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/isNull.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonDocument::isNull()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("returns true if uninitialized") { REQUIRE(doc.isNull() == true); diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/issue1120.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/issue1120.cpp index fbee477..766ecea 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/issue1120.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/issue1120.cpp @@ -3,7 +3,7 @@ #include TEST_CASE("Issue #1120") { - StaticJsonDocument<500> doc; + JsonDocument doc; constexpr char str[] = "{\"contents\":[{\"module\":\"Packet\"},{\"module\":\"Analog\"}]}"; deserializeJson(doc, str); diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/nesting.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/nesting.cpp index 7ac7e76..4f4a3a5 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/nesting.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/nesting.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonDocument::nesting()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("return 0 if uninitialized") { REQUIRE(doc.nesting() == 0); diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/overflowed.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/overflowed.cpp index e46d21b..145cbc9 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/overflowed.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/overflowed.cpp @@ -1,85 +1,95 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + TEST_CASE("JsonDocument::overflowed()") { + TimebombAllocator timebomb(10); + JsonDocument doc(&timebomb); + SECTION("returns false on a fresh object") { - StaticJsonDocument<0> doc; + timebomb.setCountdown(0); CHECK(doc.overflowed() == false); } SECTION("returns true after a failed insertion") { - StaticJsonDocument<0> doc; + timebomb.setCountdown(0); doc.add(0); CHECK(doc.overflowed() == true); } SECTION("returns false after successful insertion") { - StaticJsonDocument doc; + timebomb.setCountdown(2); doc.add(0); CHECK(doc.overflowed() == false); } SECTION("returns true after a failed string copy") { - StaticJsonDocument doc; + timebomb.setCountdown(0); doc.add(std::string("example")); CHECK(doc.overflowed() == true); } SECTION("returns false after a successful string copy") { - StaticJsonDocument doc; + timebomb.setCountdown(3); doc.add(std::string("example")); CHECK(doc.overflowed() == false); } SECTION("returns true after a failed member add") { - StaticJsonDocument<1> doc; + timebomb.setCountdown(0); doc["example"] = true; CHECK(doc.overflowed() == true); } SECTION("returns true after a failed deserialization") { - StaticJsonDocument doc; - deserializeJson(doc, "[\"example\"]"); + timebomb.setCountdown(0); + deserializeJson(doc, "[1, 2]"); CHECK(doc.overflowed() == true); } SECTION("returns false after a successful deserialization") { - StaticJsonDocument doc; + timebomb.setCountdown(3); deserializeJson(doc, "[\"example\"]"); CHECK(doc.overflowed() == false); } SECTION("returns false after clear()") { - StaticJsonDocument<0> doc; + timebomb.setCountdown(0); doc.add(0); doc.clear(); CHECK(doc.overflowed() == false); } SECTION("remains false after shrinkToFit()") { - DynamicJsonDocument doc(JSON_ARRAY_SIZE(1)); + timebomb.setCountdown(2); doc.add(0); + timebomb.setCountdown(2); doc.shrinkToFit(); CHECK(doc.overflowed() == false); } SECTION("remains true after shrinkToFit()") { - DynamicJsonDocument doc(JSON_ARRAY_SIZE(1)); - doc.add(0); + timebomb.setCountdown(0); doc.add(0); + timebomb.setCountdown(2); doc.shrinkToFit(); CHECK(doc.overflowed() == true); } - SECTION("return false after garbageCollect()") { - DynamicJsonDocument doc(JSON_ARRAY_SIZE(1)); - doc.add(0); - doc.add(0); - doc.garbageCollect(); + SECTION("returns false when string length doesn't overflow") { + auto maxLength = ArduinoJson::detail::StringNode::maxLength; + CHECK(doc.set(std::string(maxLength, 'a')) == true); CHECK(doc.overflowed() == false); } + + SECTION("returns true when string length overflows") { + auto maxLength = ArduinoJson::detail::StringNode::maxLength; + CHECK(doc.set(std::string(maxLength + 1, 'a')) == false); + CHECK(doc.overflowed() == true); + } } diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/remove.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/remove.cpp index 724b324..26048e3 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/remove.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/remove.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonDocument::remove()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("remove(int)") { doc.add(1); diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/shrinkToFit.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/shrinkToFit.cpp index a442334..82a65f4 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/shrinkToFit.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/shrinkToFit.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,145 +8,176 @@ #include // malloc, free #include -class ArmoredAllocator { +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; +using ArduinoJson::detail::sizeofObject; + +class ArmoredAllocator : public Allocator { public: - ArmoredAllocator() : ptr_(0), size_(0) {} + virtual ~ArmoredAllocator() {} - void* allocate(size_t size) { - ptr_ = malloc(size); - size_ = size; - return ptr_; + void* allocate(size_t size) override { + return malloc(size); } - void deallocate(void* ptr) { - REQUIRE(ptr == ptr_); + void deallocate(void* ptr) override { free(ptr); - ptr_ = 0; - size_ = 0; } - void* reallocate(void* ptr, size_t new_size) { - REQUIRE(ptr == ptr_); + void* reallocate(void* ptr, size_t new_size) override { // don't call realloc, instead alloc a new buffer and erase the old one // this way we make sure we support relocation void* new_ptr = malloc(new_size); - memcpy(new_ptr, ptr_, std::min(new_size, size_)); - memset(ptr_, '#', size_); // erase - free(ptr_); - ptr_ = new_ptr; + memset(new_ptr, '#', new_size); // erase + if (ptr) { + memcpy(new_ptr, ptr, std::min(new_size, new_size)); + free(ptr); + } return new_ptr; } - - private: - void* ptr_; - size_t size_; }; -typedef BasicJsonDocument ShrinkToFitTestDocument; +TEST_CASE("JsonDocument::shrinkToFit()") { + ArmoredAllocator armoredAllocator; + SpyingAllocator spyingAllocator(&armoredAllocator); + JsonDocument doc(&spyingAllocator); -void testShrinkToFit(ShrinkToFitTestDocument& doc, std::string expected_json, - size_t expected_size) { - // test twice: shrinkToFit() should be idempotent - for (int i = 0; i < 2; i++) { + SECTION("null") { doc.shrinkToFit(); - REQUIRE(doc.capacity() == expected_size); - REQUIRE(doc.memoryUsage() == expected_size); - - std::string json; - serializeJson(doc, json); - REQUIRE(json == expected_json); - } -} - -TEST_CASE("BasicJsonDocument::shrinkToFit()") { - ShrinkToFitTestDocument doc(4096); - - SECTION("null") { - testShrinkToFit(doc, "null", 0); + REQUIRE(doc.as() == "null"); + REQUIRE(spyingAllocator.log() == AllocatorLog{}); } SECTION("empty object") { deserializeJson(doc, "{}"); - testShrinkToFit(doc, "{}", JSON_OBJECT_SIZE(0)); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "{}"); + REQUIRE(spyingAllocator.log() == AllocatorLog{}); } SECTION("empty array") { deserializeJson(doc, "[]"); - testShrinkToFit(doc, "[]", JSON_ARRAY_SIZE(0)); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "[]"); + REQUIRE(spyingAllocator.log() == AllocatorLog{}); } SECTION("linked string") { doc.set("hello"); - testShrinkToFit(doc, "\"hello\"", 0); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "hello"); + REQUIRE(spyingAllocator.log() == AllocatorLog{}); } SECTION("owned string") { doc.set(std::string("abcdefg")); - testShrinkToFit(doc, "\"abcdefg\"", 8); - } + REQUIRE(doc.as() == "abcdefg"); + + doc.shrinkToFit(); - SECTION("linked raw") { - doc.set(serialized("[{},123]")); - testShrinkToFit(doc, "[{},123]", 0); + REQUIRE(doc.as() == "abcdefg"); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("abcdefg")), + }); } - SECTION("owned raw") { - doc.set(serialized(std::string("[{},12]"))); - testShrinkToFit(doc, "[{},12]", 8); + SECTION("raw string") { + doc.set(serialized("[{},12]")); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "[{},12]"); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("[{},12]")), + }); } SECTION("linked key") { doc["key"] = 42; - testShrinkToFit(doc, "{\"key\":42}", JSON_OBJECT_SIZE(1)); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "{\"key\":42}"); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("owned key") { doc[std::string("abcdefg")] = 42; - testShrinkToFit(doc, "{\"abcdefg\":42}", JSON_OBJECT_SIZE(1) + 8); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "{\"abcdefg\":42}"); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofString("abcdefg")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("linked string in array") { doc.add("hello"); - testShrinkToFit(doc, "[\"hello\"]", JSON_ARRAY_SIZE(1)); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "[\"hello\"]"); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofArray(1)), + }); } SECTION("owned string in array") { doc.add(std::string("abcdefg")); - testShrinkToFit(doc, "[\"abcdefg\"]", JSON_ARRAY_SIZE(1) + 8); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "[\"abcdefg\"]"); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("abcdefg")), + Reallocate(sizeofPool(), sizeofArray(1)), + }); } SECTION("linked string in object") { doc["key"] = "hello"; - testShrinkToFit(doc, "{\"key\":\"hello\"}", JSON_OBJECT_SIZE(1)); + + doc.shrinkToFit(); + + REQUIRE(doc.as() == "{\"key\":\"hello\"}"); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("owned string in object") { doc["key"] = std::string("abcdefg"); - testShrinkToFit(doc, "{\"key\":\"abcdefg\"}", JSON_ARRAY_SIZE(1) + 8); - } - - SECTION("unaligned") { - doc.add(std::string("?")); // two bytes in the string pool - REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 2); doc.shrinkToFit(); - // the new capacity should be padded to align the pointers - REQUIRE(doc.capacity() == JSON_OBJECT_SIZE(1) + sizeof(void*)); - REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 2); - REQUIRE(doc[0] == "?"); + REQUIRE(doc.as() == "{\"key\":\"abcdefg\"}"); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("abcdefg")), + Reallocate(sizeofPool(), sizeofPool(1)), + }); } } - -TEST_CASE("DynamicJsonDocument::shrinkToFit()") { - DynamicJsonDocument doc(4096); - - deserializeJson(doc, "{\"hello\":[\"world\"]"); - - doc.shrinkToFit(); - - std::string json; - serializeJson(doc, json); - REQUIRE(json == "{\"hello\":[\"world\"]}"); -} diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/size.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/size.cpp index b3205a1..53af226 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/size.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/size.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonDocument::size()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("returns 0") { REQUIRE(doc.size() == 0); diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/subscript.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/subscript.cpp index f4186f8..ed8a695 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/subscript.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/subscript.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonDocument::operator[]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; const JsonDocument& cdoc = doc; SECTION("object") { @@ -37,7 +37,7 @@ TEST_CASE("JsonDocument::operator[]") { } TEST_CASE("JsonDocument automatically promotes to object") { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc["one"]["two"]["three"] = 4; @@ -45,7 +45,7 @@ TEST_CASE("JsonDocument automatically promotes to object") { } TEST_CASE("JsonDocument automatically promotes to array") { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc[2] = 2; diff --git a/third-party/ArduinoJson/extras/tests/JsonDocument/swap.cpp b/third-party/ArduinoJson/extras/tests/JsonDocument/swap.cpp index 60d672f..3538308 100644 --- a/third-party/ArduinoJson/extras/tests/JsonDocument/swap.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonDocument/swap.cpp @@ -7,21 +7,19 @@ using namespace std; TEST_CASE("std::swap") { - SECTION("DynamicJsonDocument*") { - DynamicJsonDocument *p1, *p2; + SECTION("JsonDocument*") { + JsonDocument *p1, *p2; swap(p1, p2); // issue #1678 } - SECTION("DynamicJsonDocument") { - DynamicJsonDocument doc1(0x10), doc2(0x20); + SECTION("JsonDocument") { + JsonDocument doc1, doc2; doc1.set("hello"); doc2.set("world"); swap(doc1, doc2); - CHECK(doc1.capacity() == 0x20); CHECK(doc1.as() == "world"); - CHECK(doc2.capacity() == 0x10); CHECK(doc2.as() == "hello"); } } diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonObject/CMakeLists.txt index 8676811..15c4035 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/JsonObject/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(JsonObjectTests @@ -7,18 +7,15 @@ add_executable(JsonObjectTests compare.cpp containsKey.cpp copy.cpp - createNestedArray.cpp - createNestedObject.cpp equals.cpp - invalid.cpp isNull.cpp iterator.cpp - memoryUsage.cpp nesting.cpp remove.cpp size.cpp std_string.cpp subscript.cpp + unbound.cpp ) add_test(JsonObject JsonObjectTests) diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/clear.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/clear.cpp index e112a8d..6673d1c 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/clear.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/clear.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -14,7 +14,7 @@ TEST_CASE("JsonObject::clear()") { } SECTION("Removes all elements") { - StaticJsonDocument<64> doc; + JsonDocument doc; JsonObject obj = doc.to(); obj["hello"] = 1; obj["world"] = 2; diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/compare.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/compare.cpp index 9b747e3..0c3ff7e 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/compare.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/compare.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("Compare JsonObject with JsonObject") { - StaticJsonDocument<512> doc; + JsonDocument doc; SECTION("Compare with unbound") { JsonObject object = doc.to(); @@ -43,12 +43,12 @@ TEST_CASE("Compare JsonObject with JsonObject") { } SECTION("Compare with identical object") { - JsonObject object1 = doc.createNestedObject(); + JsonObject object1 = doc.add(); object1["a"] = 1; object1["b"] = "hello"; object1["c"][0] = false; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello"; object2["c"][0] = false; @@ -62,12 +62,12 @@ TEST_CASE("Compare JsonObject with JsonObject") { } SECTION("Compare with different object") { - JsonObject object1 = doc.createNestedObject(); + JsonObject object1 = doc.add(); object1["a"] = 1; object1["b"] = "hello1"; object1["c"][0] = false; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello2"; object2["c"][0] = false; @@ -82,7 +82,7 @@ TEST_CASE("Compare JsonObject with JsonObject") { } TEST_CASE("Compare JsonObject with JsonVariant") { - StaticJsonDocument<512> doc; + JsonDocument doc; SECTION("Compare with self") { JsonObject object = doc.to(); @@ -107,12 +107,12 @@ TEST_CASE("Compare JsonObject with JsonVariant") { } SECTION("Compare with identical object") { - JsonObject object = doc.createNestedObject(); + JsonObject object = doc.add(); object["a"] = 1; object["b"] = "hello"; object["c"][0] = false; - JsonVariant variant = doc.createNestedObject(); + JsonVariant variant = doc.add(); variant["a"] = 1; variant["b"] = "hello"; variant["c"][0] = false; @@ -133,12 +133,12 @@ TEST_CASE("Compare JsonObject with JsonVariant") { } SECTION("Compare with different object") { - JsonObject object = doc.createNestedObject(); + JsonObject object = doc.add(); object["a"] = 1; object["b"] = "hello1"; object["c"][0] = false; - JsonVariant variant = doc.createNestedObject(); + JsonVariant variant = doc.add(); variant["a"] = 1; variant["b"] = "hello2"; variant["c"][0] = false; @@ -153,7 +153,7 @@ TEST_CASE("Compare JsonObject with JsonVariant") { } TEST_CASE("Compare JsonObject with JsonVariantConst") { - StaticJsonDocument<512> doc; + JsonDocument doc; SECTION("Compare with unbound") { JsonObject object = doc.to(); @@ -199,12 +199,12 @@ TEST_CASE("Compare JsonObject with JsonVariantConst") { } SECTION("Compare with identical object") { - JsonObject object = doc.createNestedObject(); + JsonObject object = doc.add(); object["a"] = 1; object["b"] = "hello"; object["c"][0] = false; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello"; object2["c"][0] = false; @@ -226,12 +226,12 @@ TEST_CASE("Compare JsonObject with JsonVariantConst") { } SECTION("Compare with different object") { - JsonObject object = doc.createNestedObject(); + JsonObject object = doc.add(); object["a"] = 1; object["b"] = "hello1"; object["c"][0] = false; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello2"; object2["c"][0] = false; @@ -247,7 +247,7 @@ TEST_CASE("Compare JsonObject with JsonVariantConst") { } TEST_CASE("Compare JsonObject with JsonObjectConst") { - StaticJsonDocument<512> doc; + JsonDocument doc; SECTION("Compare with unbound") { JsonObject object = doc.to(); @@ -292,12 +292,12 @@ TEST_CASE("Compare JsonObject with JsonObjectConst") { } SECTION("Compare with identical object") { - JsonObject object1 = doc.createNestedObject(); + JsonObject object1 = doc.add(); object1["a"] = 1; object1["b"] = "hello"; object1["c"][0] = false; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello"; object2["c"][0] = false; @@ -319,12 +319,12 @@ TEST_CASE("Compare JsonObject with JsonObjectConst") { } SECTION("Compare with different object") { - JsonObject object1 = doc.createNestedObject(); + JsonObject object1 = doc.add(); object1["a"] = 1; object1["b"] = "hello1"; object1["c"][0] = false; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello2"; object2["c"][0] = false; @@ -347,7 +347,7 @@ TEST_CASE("Compare JsonObject with JsonObjectConst") { } TEST_CASE("Compare JsonObjectConst with JsonObjectConst") { - StaticJsonDocument<512> doc; + JsonDocument doc; SECTION("Compare with unbound") { JsonObject object = doc.to(); @@ -387,13 +387,13 @@ TEST_CASE("Compare JsonObjectConst with JsonObjectConst") { } SECTION("Compare with identical object") { - JsonObject object1 = doc.createNestedObject(); + JsonObject object1 = doc.add(); object1["a"] = 1; object1["b"] = "hello"; object1["c"][0] = false; JsonObjectConst carray1 = object1; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello"; object2["c"][0] = false; @@ -408,13 +408,13 @@ TEST_CASE("Compare JsonObjectConst with JsonObjectConst") { } SECTION("Compare with different object") { - JsonObject object1 = doc.createNestedObject(); + JsonObject object1 = doc.add(); object1["a"] = 1; object1["b"] = "hello1"; object1["c"][0] = false; JsonObjectConst carray1 = object1; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello2"; object2["c"][0] = false; @@ -430,7 +430,7 @@ TEST_CASE("Compare JsonObjectConst with JsonObjectConst") { } TEST_CASE("Compare JsonObjectConst with JsonVariant") { - StaticJsonDocument<512> doc; + JsonDocument doc; SECTION("Compare with self") { JsonObject object = doc.to(); @@ -455,13 +455,13 @@ TEST_CASE("Compare JsonObjectConst with JsonVariant") { } SECTION("Compare with identical object") { - JsonObject object1 = doc.createNestedObject(); + JsonObject object1 = doc.add(); object1["a"] = 1; object1["b"] = "hello"; object1["c"][0] = false; JsonObjectConst carray1 = object1; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello"; object2["c"][0] = false; @@ -483,13 +483,13 @@ TEST_CASE("Compare JsonObjectConst with JsonVariant") { } SECTION("Compare with different object") { - JsonObject object1 = doc.createNestedObject(); + JsonObject object1 = doc.add(); object1["a"] = 1; object1["b"] = "hello1"; object1["c"][0] = false; JsonObjectConst carray1 = object1; - JsonObject object2 = doc.createNestedObject(); + JsonObject object2 = doc.add(); object2["a"] = 1; object2["b"] = "hello2"; object2["c"][0] = false; diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/containsKey.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/containsKey.cpp index 85335a8..a5e20e9 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/containsKey.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/containsKey.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonObject::containsKey()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); obj["hello"] = 42; @@ -15,12 +15,6 @@ TEST_CASE("JsonObject::containsKey()") { REQUIRE(true == obj.containsKey("hello")); } - SECTION("works with JsonObjectConst") { - JsonObjectConst cobj = obj; - REQUIRE(false == cobj.containsKey("world")); - REQUIRE(true == cobj.containsKey("hello")); - } - SECTION("returns false after remove()") { obj.remove("hello"); diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/copy.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/copy.cpp index a4d5b5f..6c67d08 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/copy.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/copy.cpp @@ -1,65 +1,89 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + TEST_CASE("JsonObject::set()") { - DynamicJsonDocument doc1(4096); - DynamicJsonDocument doc2(4096); + SpyingAllocator spy; + JsonDocument doc1(&spy); + JsonDocument doc2(&spy); JsonObject obj1 = doc1.to(); JsonObject obj2 = doc2.to(); SECTION("doesn't copy static string in key or value") { obj1["hello"] = "world"; + spy.clearLog(); bool success = obj2.set(obj1); REQUIRE(success == true); - REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); REQUIRE(obj2["hello"] == std::string("world")); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); } SECTION("copy local string value") { obj1["hello"] = std::string("world"); + spy.clearLog(); bool success = obj2.set(obj1); REQUIRE(success == true); - REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); REQUIRE(obj2["hello"] == std::string("world")); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("copy local key") { obj1[std::string("hello")] = "world"; + spy.clearLog(); bool success = obj2.set(obj1); REQUIRE(success == true); - REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); REQUIRE(obj2["hello"] == std::string("world")); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + }); } SECTION("copy string from deserializeJson()") { deserializeJson(doc1, "{'hello':'world'}"); + spy.clearLog(); bool success = obj2.set(obj1); REQUIRE(success == true); - REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); REQUIRE(obj2["hello"] == std::string("world")); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("copy string from deserializeMsgPack()") { deserializeMsgPack(doc1, "\x81\xA5hello\xA5world"); + spy.clearLog(); bool success = obj2.set(obj1); REQUIRE(success == true); - REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); REQUIRE(obj2["hello"] == std::string("world")); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("should work with JsonObjectConst") { @@ -67,32 +91,34 @@ TEST_CASE("JsonObject::set()") { obj2.set(static_cast(obj1)); - REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); REQUIRE(obj2["hello"] == std::string("world")); } - SECTION("destination too small to store the key") { - StaticJsonDocument doc3; + SECTION("copy fails in the middle of an object") { + TimebombAllocator timebomb(2); + JsonDocument doc3(&timebomb); JsonObject obj3 = doc3.to(); - obj1[std::string("hello")] = "world"; + obj1[std::string("a")] = 1; + obj1[std::string("b")] = 2; bool success = obj3.set(obj1); REQUIRE(success == false); - REQUIRE(doc3.as() == "{}"); + REQUIRE(doc3.as() == "{\"a\":1}"); } - SECTION("destination too small to store the value") { - StaticJsonDocument doc3; + SECTION("copy fails in the middle of an array") { + TimebombAllocator timebomb(1); + JsonDocument doc3(&timebomb); JsonObject obj3 = doc3.to(); - obj1["hello"] = std::string("world"); + obj1["hello"][0] = std::string("world"); bool success = obj3.set(obj1); REQUIRE(success == false); - REQUIRE(doc3.as() == "{\"hello\":null}"); + REQUIRE(doc3.as() == "{\"hello\":[null]}"); } SECTION("destination is null") { diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/equals.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/equals.cpp index 02d451f..0ec4673 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/equals.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/equals.cpp @@ -1,25 +1,22 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonObject::operator==()") { - DynamicJsonDocument doc1(4096); + JsonDocument doc1; JsonObject obj1 = doc1.to(); - JsonObjectConst obj1c = obj1; - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonObject obj2 = doc2.to(); - JsonObjectConst obj2c = obj2; SECTION("should return false when objs differ") { obj1["hello"] = "coucou"; obj2["world"] = 1; REQUIRE_FALSE(obj1 == obj2); - REQUIRE_FALSE(obj1c == obj2c); } SECTION("should return false when LHS has more elements") { @@ -28,7 +25,6 @@ TEST_CASE("JsonObject::operator==()") { obj2["hello"] = "coucou"; REQUIRE_FALSE(obj1 == obj2); - REQUIRE_FALSE(obj1c == obj2c); } SECTION("should return false when RKS has more elements") { @@ -37,7 +33,6 @@ TEST_CASE("JsonObject::operator==()") { obj2["world"] = 666; REQUIRE_FALSE(obj1 == obj2); - REQUIRE_FALSE(obj1c == obj2c); } SECTION("should return true when objs equal") { @@ -48,20 +43,17 @@ TEST_CASE("JsonObject::operator==()") { obj2["hello"] = "world"; REQUIRE(obj1 == obj2); - REQUIRE(obj1c == obj2c); } SECTION("should return false when RHS is null") { JsonObject null; REQUIRE_FALSE(obj1 == null); - REQUIRE_FALSE(obj1c == null); } SECTION("should return false when LHS is null") { JsonObject null; REQUIRE_FALSE(null == obj2); - REQUIRE_FALSE(null == obj2c); } } diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/isNull.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/isNull.cpp index 9fdff95..51f7880 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/isNull.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/isNull.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -12,25 +12,12 @@ TEST_CASE("JsonObject::isNull()") { } SECTION("returns false") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); REQUIRE(obj.isNull() == false); } } -TEST_CASE("JsonObjectConst::isNull()") { - SECTION("returns true") { - JsonObjectConst obj; - REQUIRE(obj.isNull() == true); - } - - SECTION("returns false") { - DynamicJsonDocument doc(4096); - JsonObjectConst obj = doc.to(); - REQUIRE(obj.isNull() == false); - } -} - TEST_CASE("JsonObject::operator bool()") { SECTION("returns false") { JsonObject obj; @@ -38,21 +25,8 @@ TEST_CASE("JsonObject::operator bool()") { } SECTION("returns true") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); REQUIRE(static_cast(obj) == true); } } - -TEST_CASE("JsonObjectConst::operator bool()") { - SECTION("returns false") { - JsonObjectConst obj; - REQUIRE(static_cast(obj) == false); - } - - SECTION("returns true") { - DynamicJsonDocument doc(4096); - JsonObjectConst obj = doc.to(); - REQUIRE(static_cast(obj) == true); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/iterator.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/iterator.cpp index c48de5f..4918d27 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/iterator.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/iterator.cpp @@ -1,14 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include -using namespace Catch::Matchers; - TEST_CASE("JsonObject::begin()/end()") { - StaticJsonDocument doc; + JsonDocument doc; JsonObject obj = doc.to(); obj["ab"] = 12; obj["cd"] = 34; @@ -36,38 +34,3 @@ TEST_CASE("JsonObject::begin()/end()") { REQUIRE(null.begin() == null.end()); } } - -TEST_CASE("JsonObjectConst::begin()/end()") { - StaticJsonDocument doc; - JsonObject obj = doc.to(); - obj["ab"] = 12; - obj["cd"] = 34; - - JsonObjectConst cobj = obj; - - SECTION("Iteration") { - JsonObjectConst::iterator it = cobj.begin(); - REQUIRE(cobj.end() != it); - REQUIRE(it->key() == "ab"); - REQUIRE(12 == it->value()); - - ++it; - REQUIRE(cobj.end() != it); - JsonPairConst pair = *it; - REQUIRE(pair.key() == "cd"); - REQUIRE(34 == pair.value()); - - ++it; - REQUIRE(cobj.end() == it); - } - - SECTION("Dereferencing end() is safe") { - REQUIRE(cobj.end()->key().isNull()); - REQUIRE(cobj.end()->value().isNull()); - } - - SECTION("null JsonObjectConst") { - JsonObjectConst null; - REQUIRE(null.begin() == null.end()); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/nesting.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/nesting.cpp index 2ba98ad..39c26fa 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/nesting.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/nesting.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonObject::nesting()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); SECTION("return 0 if uninitialized") { @@ -24,12 +24,12 @@ TEST_CASE("JsonObject::nesting()") { } SECTION("returns 2 with nested array") { - obj.createNestedArray("nested"); + obj["nested"].to(); REQUIRE(obj.nesting() == 2); } SECTION("returns 2 with nested object") { - obj.createNestedObject("nested"); + obj["nested"].to(); REQUIRE(obj.nesting() == 2); } } diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/remove.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/remove.cpp index 1dbd4bd..0124c4a 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/remove.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/remove.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,7 +7,7 @@ #include TEST_CASE("JsonObject::remove()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); obj["a"] = 0; obj["b"] = 1; @@ -51,7 +51,8 @@ TEST_CASE("JsonObject::remove()") { } SECTION("Remove last") { - it += 2; + ++it; + ++it; obj.remove(it); serializeJson(obj, result); REQUIRE("{\"a\":0,\"b\":1}" == result); diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/size.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/size.cpp index d9c7bb7..5f48645 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/size.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/size.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,7 +7,7 @@ #include TEST_CASE("JsonObject::size()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); SECTION("initial size is zero") { diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/std_string.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/std_string.cpp index 8a93d3f..1bd533c 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/std_string.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/std_string.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -12,7 +12,7 @@ static void eraseString(std::string& str) { } TEST_CASE("std::string") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("operator[]") { char json[] = "{\"key\":\"value\"}"; @@ -32,26 +32,6 @@ TEST_CASE("std::string") { REQUIRE(std::string("value") == obj[std::string("key")]); } - SECTION("createNestedObject()") { - JsonObject obj = doc.to(); - std::string key = "key"; - char json[64]; - obj.createNestedObject(key); - eraseString(key); - serializeJson(doc, json, sizeof(json)); - REQUIRE(std::string("{\"key\":{}}") == json); - } - - SECTION("createNestedArray()") { - JsonObject obj = doc.to(); - std::string key = "key"; - char json[64]; - obj.createNestedArray(key); - eraseString(key); - serializeJson(doc, json, sizeof(json)); - REQUIRE(std::string("{\"key\":[]}") == json); - } - SECTION("containsKey()") { char json[] = "{\"key\":\"value\"}"; deserializeJson(doc, json); @@ -83,28 +63,4 @@ TEST_CASE("std::string") { eraseString(value); REQUIRE(std::string("world") == obj["hello"]); } - - SECTION("memoryUsage() increases when adding a new key") { - std::string key1("hello"), key2("world"); - JsonObject obj = doc.to(); - - obj[key1] = 1; - size_t sizeBefore = doc.memoryUsage(); - obj[key2] = 2; - size_t sizeAfter = doc.memoryUsage(); - - REQUIRE(sizeAfter - sizeBefore >= key2.size()); - } - - SECTION("memoryUsage() remains when adding the same key") { - std::string key("hello"); - JsonObject obj = doc.to(); - - obj[key] = 1; - size_t sizeBefore = doc.memoryUsage(); - obj[key] = 2; - size_t sizeAfter = doc.memoryUsage(); - - REQUIRE(sizeBefore == sizeAfter); - } } diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/subscript.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/subscript.cpp index afc567a..2f8c95f 100644 --- a/third-party/ArduinoJson/extras/tests/JsonObject/subscript.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonObject/subscript.cpp @@ -1,12 +1,15 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + TEST_CASE("JsonObject::operator[]") { - DynamicJsonDocument doc(4096); + SpyingAllocator spy; + JsonDocument doc(&spy); JsonObject obj = doc.to(); SECTION("int") { @@ -51,7 +54,7 @@ TEST_CASE("JsonObject::operator[]") { } SECTION("array") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonArray arr = doc2.to(); obj["hello"] = arr; @@ -62,7 +65,7 @@ TEST_CASE("JsonObject::operator[]") { } SECTION("object") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonObject obj2 = doc2.to(); obj["hello"] = obj2; @@ -73,7 +76,7 @@ TEST_CASE("JsonObject::operator[]") { } SECTION("array subscript") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonArray arr = doc2.to(); arr.add(42); @@ -83,7 +86,7 @@ TEST_CASE("JsonObject::operator[]") { } SECTION("object subscript") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonObject obj2 = doc2.to(); obj2["x"] = 42; @@ -100,56 +103,72 @@ TEST_CASE("JsonObject::operator[]") { SECTION("should not duplicate const char*") { obj["hello"] = "world"; - const size_t expectedSize = JSON_OBJECT_SIZE(1); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{Allocate(sizeofPool())}); } SECTION("should duplicate char* value") { obj["hello"] = const_cast("world"); - const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("should duplicate char* key") { obj[const_cast("hello")] = "world"; - const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + }); } SECTION("should duplicate char* key&value") { obj[const_cast("hello")] = const_cast("world"); - const size_t expectedSize = JSON_OBJECT_SIZE(1) + 2 * JSON_STRING_SIZE(5); - REQUIRE(expectedSize <= doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("should duplicate std::string value") { obj["hello"] = std::string("world"); - const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("should duplicate std::string key") { obj[std::string("hello")] = "world"; - const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + }); } SECTION("should duplicate std::string key&value") { obj[std::string("hello")] = std::string("world"); - const size_t expectedSize = JSON_OBJECT_SIZE(1) + 2 * JSON_STRING_SIZE(5); - REQUIRE(expectedSize <= doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + Allocate(sizeofString("world")), + }); } SECTION("should duplicate a non-static JsonString key") { obj[JsonString("hello", JsonString::Copied)] = "world"; - const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Allocate(sizeofPool()), + }); } SECTION("should not duplicate a static JsonString key") { obj[JsonString("hello", JsonString::Linked)] = "world"; - const size_t expectedSize = JSON_OBJECT_SIZE(1); - REQUIRE(expectedSize == doc.memoryUsage()); + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + }); } SECTION("should ignore null key") { @@ -224,7 +243,7 @@ TEST_CASE("JsonObject::operator[]") { #endif SECTION("chain") { - obj.createNestedObject("hello")["world"] = 123; + obj["hello"]["world"] = 123; REQUIRE(123 == obj["hello"]["world"].as()); REQUIRE(true == obj["hello"]["world"].is()); diff --git a/third-party/ArduinoJson/extras/tests/JsonObject/unbound.cpp b/third-party/ArduinoJson/extras/tests/JsonObject/unbound.cpp new file mode 100644 index 0000000..cb2b687 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObject/unbound.cpp @@ -0,0 +1,27 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +using namespace Catch::Matchers; + +TEST_CASE("Unbound JsonObject") { + JsonObject obj; + + SECTION("retrieve member") { + REQUIRE(obj["key"].isNull()); + } + + SECTION("add member") { + obj["hello"] = "world"; + REQUIRE(0 == obj.size()); + } + + SECTION("serialize") { + char buffer[32]; + serializeJson(obj, buffer, sizeof(buffer)); + REQUIRE_THAT(buffer, Equals("null")); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonObjectConst/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonObjectConst/CMakeLists.txt new file mode 100644 index 0000000..dadb910 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObjectConst/CMakeLists.txt @@ -0,0 +1,20 @@ +# ArduinoJson - https://arduinojson.org +# Copyright © 2014-2024, Benoit BLANCHON +# MIT License + +add_executable(JsonObjectConstTests + containsKey.cpp + equals.cpp + isNull.cpp + iterator.cpp + nesting.cpp + size.cpp + subscript.cpp +) + +add_test(JsonObjectConst JsonObjectConstTests) + +set_tests_properties(JsonObjectConst + PROPERTIES + LABELS "Catch" +) diff --git a/third-party/ArduinoJson/extras/tests/JsonObjectConst/containsKey.cpp b/third-party/ArduinoJson/extras/tests/JsonObjectConst/containsKey.cpp new file mode 100644 index 0000000..3b63941 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObjectConst/containsKey.cpp @@ -0,0 +1,32 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonObjectConst::containsKey()") { + JsonDocument doc; + doc["hello"] = 42; + auto obj = doc.as(); + + SECTION("supports const char*") { + REQUIRE(false == obj.containsKey("world")); + REQUIRE(true == obj.containsKey("hello")); + } + + SECTION("supports std::string") { + REQUIRE(false == obj.containsKey(std::string("world"))); + REQUIRE(true == obj.containsKey(std::string("hello"))); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("supports VLA") { + size_t i = 16; + char vla[i]; + strcpy(vla, "hello"); + + REQUIRE(true == obj.containsKey(vla)); + } +#endif +} diff --git a/third-party/ArduinoJson/extras/tests/JsonObjectConst/equals.cpp b/third-party/ArduinoJson/extras/tests/JsonObjectConst/equals.cpp new file mode 100644 index 0000000..0efa3cf --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObjectConst/equals.cpp @@ -0,0 +1,65 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonObjectConst::operator==()") { + JsonDocument doc1; + JsonObjectConst obj1 = doc1.to(); + + JsonDocument doc2; + JsonObjectConst obj2 = doc2.to(); + + SECTION("should return false when objs differ") { + doc1["hello"] = "coucou"; + doc2["world"] = 1; + + REQUIRE_FALSE(obj1 == obj2); + } + + SECTION("should return false when LHS has more elements") { + doc1["hello"] = "coucou"; + doc1["world"] = 666; + doc2["hello"] = "coucou"; + + REQUIRE_FALSE(obj1 == obj2); + } + + SECTION("should return false when RKS has more elements") { + doc1["hello"] = "coucou"; + doc2["hello"] = "coucou"; + doc2["world"] = 666; + + REQUIRE_FALSE(obj1 == obj2); + } + + SECTION("should return true when objs equal") { + doc1["hello"] = "world"; + doc1["anwser"] = 42; + // insert in different order + doc2["anwser"] = 42; + doc2["hello"] = "world"; + + REQUIRE(obj1 == obj2); + } + + SECTION("should return false when RHS is null") { + JsonObjectConst null; + + REQUIRE_FALSE(obj1 == null); + } + + SECTION("should return false when LHS is null") { + JsonObjectConst null; + + REQUIRE_FALSE(null == obj2); + } + + SECTION("should return true when both are null") { + JsonObjectConst null1, null2; + + REQUIRE(null1 == null2); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonObjectConst/isNull.cpp b/third-party/ArduinoJson/extras/tests/JsonObjectConst/isNull.cpp new file mode 100644 index 0000000..c689cce --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObjectConst/isNull.cpp @@ -0,0 +1,32 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonObjectConst::isNull()") { + SECTION("returns true") { + JsonObjectConst obj; + REQUIRE(obj.isNull() == true); + } + + SECTION("returns false") { + JsonDocument doc; + JsonObjectConst obj = doc.to(); + REQUIRE(obj.isNull() == false); + } +} + +TEST_CASE("JsonObjectConst::operator bool()") { + SECTION("returns false") { + JsonObjectConst obj; + REQUIRE(static_cast(obj) == false); + } + + SECTION("returns true") { + JsonDocument doc; + JsonObjectConst obj = doc.to(); + REQUIRE(static_cast(obj) == true); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonObjectConst/iterator.cpp b/third-party/ArduinoJson/extras/tests/JsonObjectConst/iterator.cpp new file mode 100644 index 0000000..0ad911e --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObjectConst/iterator.cpp @@ -0,0 +1,39 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonObjectConst::begin()/end()") { + JsonDocument doc; + JsonObjectConst obj = doc.to(); + doc["ab"] = 12; + doc["cd"] = 34; + + SECTION("Iteration") { + JsonObjectConst::iterator it = obj.begin(); + REQUIRE(obj.end() != it); + REQUIRE(it->key() == "ab"); + REQUIRE(12 == it->value()); + + ++it; + REQUIRE(obj.end() != it); + JsonPairConst pair = *it; + REQUIRE(pair.key() == "cd"); + REQUIRE(34 == pair.value()); + + ++it; + REQUIRE(obj.end() == it); + } + + SECTION("Dereferencing end() is safe") { + REQUIRE(obj.end()->key().isNull()); + REQUIRE(obj.end()->value().isNull()); + } + + SECTION("null JsonObjectConst") { + JsonObjectConst null; + REQUIRE(null.begin() == null.end()); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonObjectConst/nesting.cpp b/third-party/ArduinoJson/extras/tests/JsonObjectConst/nesting.cpp new file mode 100644 index 0000000..7bddd8f --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObjectConst/nesting.cpp @@ -0,0 +1,35 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonObjectConst::nesting()") { + JsonDocument doc; + JsonObjectConst obj = doc.to(); + + SECTION("return 0 if unbound") { + JsonObjectConst unbound; + REQUIRE(unbound.nesting() == 0); + } + + SECTION("returns 1 for empty object") { + REQUIRE(obj.nesting() == 1); + } + + SECTION("returns 1 for flat object") { + doc["hello"] = "world"; + REQUIRE(obj.nesting() == 1); + } + + SECTION("returns 2 with nested array") { + doc["nested"].to(); + REQUIRE(obj.nesting() == 2); + } + + SECTION("returns 2 with nested object") { + doc["nested"].to(); + REQUIRE(obj.nesting() == 2); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonObjectConst/size.cpp b/third-party/ArduinoJson/extras/tests/JsonObjectConst/size.cpp new file mode 100644 index 0000000..25de11a --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObjectConst/size.cpp @@ -0,0 +1,22 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include + +TEST_CASE("JsonObjectConst::size()") { + JsonDocument doc; + JsonObjectConst obj = doc.to(); + + SECTION("returns 0 when empty") { + REQUIRE(0 == obj.size()); + } + + SECTION("returns the number of members") { + doc["hello"] = 1; + doc["world"] = 2; + REQUIRE(2 == obj.size()); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonObjectConst/subscript.cpp b/third-party/ArduinoJson/extras/tests/JsonObjectConst/subscript.cpp new file mode 100644 index 0000000..917b54a --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonObjectConst/subscript.cpp @@ -0,0 +1,33 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include "Allocators.hpp" + +TEST_CASE("JsonObjectConst::operator[]") { + JsonDocument doc; + doc["hello"] = "world"; + JsonObjectConst obj = doc.as(); + + SECTION("supports const char*") { + REQUIRE(obj["hello"] == "world"); // issue #2019 + } + + SECTION("supports std::string") { + REQUIRE(obj[std::string("hello")] == "world"); // issue #2019 + } + +#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \ + !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR) + SECTION("supports VLA") { + size_t i = 16; + char vla[i]; + strcpy(vla, "hello"); + + REQUIRE(std::string("world") == obj[vla]); + } +#endif +} diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonSerializer/CMakeLists.txt index 0ec4937..8a6b19f 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(JsonSerializerTests diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/CustomWriter.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/CustomWriter.cpp index a84657a..002aa57 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/CustomWriter.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/CustomWriter.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -30,7 +30,7 @@ class CustomWriter { }; TEST_CASE("CustomWriter") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); array.add(4); array.add(2); diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonArray.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonArray.cpp index 1fad69d..b4bf838 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonArray.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonArray.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -15,7 +15,7 @@ static void check(JsonArray array, std::string expected) { } TEST_CASE("serializeJson(JsonArray)") { - StaticJsonDocument doc; + JsonDocument doc; JsonArray array = doc.to(); SECTION("Empty") { @@ -41,14 +41,6 @@ TEST_CASE("serializeJson(JsonArray)") { check(array, "[\"hello\",\"world\"]"); } - SECTION("OneStringOverCapacity") { - array.add("hello"); - array.add("world"); - array.add("lost"); - - check(array, "[\"hello\",\"world\"]"); - } - SECTION("One double") { array.add(3.1415927); check(array, "[3.1415927]"); @@ -80,14 +72,6 @@ TEST_CASE("serializeJson(JsonArray)") { check(array, "[{\"key\":\"value\"}]"); } - SECTION("OneIntegerOverCapacity") { - array.add(1); - array.add(2); - array.add(3); - - check(array, "[1,2]"); - } - SECTION("OneTrue") { array.add(true); @@ -107,22 +91,14 @@ TEST_CASE("serializeJson(JsonArray)") { check(array, "[false,true]"); } - SECTION("OneBooleanOverCapacity") { - array.add(false); - array.add(true); - array.add(false); - - check(array, "[false,true]"); - } - SECTION("OneEmptyNestedArray") { - array.createNestedArray(); + array.add(); check(array, "[[]]"); } SECTION("OneEmptyNestedHash") { - array.createNestedObject(); + array.add(); check(array, "[{}]"); } diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonArrayPretty.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonArrayPretty.cpp index 9abeb01..ede368c 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonArrayPretty.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonArrayPretty.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -15,7 +15,7 @@ static void checkArray(JsonArray array, std::string expected) { } TEST_CASE("serializeJsonPretty(JsonArray)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); SECTION("Empty") { @@ -43,8 +43,8 @@ TEST_CASE("serializeJsonPretty(JsonArray)") { } SECTION("EmptyNestedArrays") { - array.createNestedArray(); - array.createNestedArray(); + array.add(); + array.add(); checkArray(array, "[\r\n" @@ -54,11 +54,11 @@ TEST_CASE("serializeJsonPretty(JsonArray)") { } SECTION("NestedArrays") { - JsonArray nested1 = array.createNestedArray(); + JsonArray nested1 = array.add(); nested1.add(1); nested1.add(2); - JsonObject nested2 = array.createNestedObject(); + JsonObject nested2 = array.add(); nested2["key"] = 3; checkArray(array, diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonObject.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonObject.cpp index 9ba2114..7078886 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonObject.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonObject.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -20,7 +20,7 @@ static void checkObject(const JsonObject obj, const std::string& expected) { } TEST_CASE("serializeJson(JsonObject)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); SECTION("EmptyObject") { @@ -96,10 +96,10 @@ TEST_CASE("serializeJson(JsonObject)") { } SECTION("ThreeNestedArrays") { - DynamicJsonDocument b(4096); - DynamicJsonDocument c(4096); + JsonDocument b; + JsonDocument c; - obj.createNestedArray("a"); + obj["a"].to(); obj["b"] = b.to(); obj["c"] = c.to(); @@ -107,10 +107,10 @@ TEST_CASE("serializeJson(JsonObject)") { } SECTION("ThreeNestedObjects") { - DynamicJsonDocument b(4096); - DynamicJsonDocument c(4096); + JsonDocument b; + JsonDocument c; - obj.createNestedObject("a"); + obj["a"].to(); obj["b"] = b.to(); obj["c"] = c.to(); diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonObjectPretty.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonObjectPretty.cpp index 4e8d113..01d7377 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonObjectPretty.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonObjectPretty.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -19,7 +19,7 @@ static void checkObjectPretty(const JsonObject obj, } TEST_CASE("serializeJsonPretty(JsonObject)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); SECTION("EmptyObject") { @@ -47,8 +47,8 @@ TEST_CASE("serializeJsonPretty(JsonObject)") { } SECTION("EmptyNestedContainers") { - obj.createNestedObject("key1"); - obj.createNestedArray("key2"); + obj["key1"].to(); + obj["key2"].to(); checkObjectPretty(obj, "{\r\n" @@ -58,10 +58,10 @@ TEST_CASE("serializeJsonPretty(JsonObject)") { } SECTION("NestedContainers") { - JsonObject nested1 = obj.createNestedObject("key1"); + JsonObject nested1 = obj["key1"].to(); nested1["a"] = 1; - JsonArray nested2 = obj.createNestedArray("key2"); + JsonArray nested2 = obj["key2"].to(); nested2.add(2); checkObjectPretty(obj, diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonVariant.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonVariant.cpp index 81553d3..694cbb0 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonVariant.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/JsonVariant.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,7 +8,7 @@ template void check(T value, const std::string& expected) { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc.to().set(value); char buffer[256] = ""; size_t returnValue = serializeJson(doc, buffer, sizeof(buffer)); diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/misc.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/misc.cpp index 59c09eb..46d7da5 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/misc.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/misc.cpp @@ -3,7 +3,7 @@ #include TEST_CASE("serializeJson(MemberProxy)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "{\"hello\":42}"); JsonObject obj = doc.as(); std::string result; @@ -14,7 +14,7 @@ TEST_CASE("serializeJson(MemberProxy)") { } TEST_CASE("serializeJson(ElementProxy)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "[42]"); JsonArray arr = doc.as(); std::string result; @@ -25,7 +25,7 @@ TEST_CASE("serializeJson(ElementProxy)") { } TEST_CASE("serializeJson(JsonVariantSubscript)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "[42]"); JsonVariant var = doc.as(); std::string result; diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/std_stream.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/std_stream.cpp index 411f479..5fd89b9 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/std_stream.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/std_stream.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,7 +7,7 @@ #include TEST_CASE("operator<<(std::ostream)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; std::ostringstream os; SECTION("JsonVariant containing false") { diff --git a/third-party/ArduinoJson/extras/tests/JsonSerializer/std_string.cpp b/third-party/ArduinoJson/extras/tests/JsonSerializer/std_string.cpp index af0d809..e70ed28 100644 --- a/third-party/ArduinoJson/extras/tests/JsonSerializer/std_string.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonSerializer/std_string.cpp @@ -1,25 +1,25 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("serialize JsonArray to std::string") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray array = doc.to(); array.add(4); array.add(2); SECTION("serializeJson()") { - std::string json; + std::string json = "erase me"; serializeJson(array, json); REQUIRE("[4,2]" == json); } SECTION("serializeJsonPretty") { - std::string json; + std::string json = "erase me"; serializeJsonPretty(array, json); REQUIRE("[\r\n 4,\r\n 2\r\n]" == json); @@ -27,19 +27,19 @@ TEST_CASE("serialize JsonArray to std::string") { } TEST_CASE("serialize JsonObject to std::string") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); obj["key"] = "value"; SECTION("object") { - std::string json; + std::string json = "erase me"; serializeJson(doc, json); REQUIRE("{\"key\":\"value\"}" == json); } SECTION("serializeJsonPretty") { - std::string json; + std::string json = "erase me"; serializeJsonPretty(doc, json); REQUIRE("{\r\n \"key\": \"value\"\r\n}" == json); @@ -47,11 +47,10 @@ TEST_CASE("serialize JsonObject to std::string") { } TEST_CASE("serialize an std::string containing a NUL") { - StaticJsonDocument<256> doc; + JsonDocument doc; doc.set(std::string("hello\0world", 11)); - CHECK(doc.memoryUsage() == 12); - std::string json; + std::string json = "erase me"; serializeJson(doc, json); CHECK("\"hello\\u0000world\"" == json); } diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonVariant/CMakeLists.txt index d43a971..e14e548 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(JsonVariantTests @@ -10,10 +10,8 @@ add_executable(JsonVariantTests containsKey.cpp converters.cpp copy.cpp - createNested.cpp is.cpp isnull.cpp - memoryUsage.cpp misc.cpp nesting.cpp nullptr.cpp @@ -21,7 +19,6 @@ add_executable(JsonVariantTests overflow.cpp remove.cpp set.cpp - shallowCopy.cpp size.cpp stl_containers.cpp subscript.cpp diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/add.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/add.cpp index 6907ae3..71e53dc 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/add.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/add.cpp @@ -1,13 +1,13 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include #include -TEST_CASE("JsonVariant::add()") { - DynamicJsonDocument doc(4096); +TEST_CASE("JsonVariant::add(T)") { + JsonDocument doc; JsonVariant var = doc.to(); SECTION("add integer to new variant") { @@ -44,3 +44,27 @@ TEST_CASE("JsonVariant::add()") { REQUIRE(var.as() == "{\"val\":123}"); } } + +TEST_CASE("JsonVariant::add()") { + JsonDocument doc; + JsonVariant var = doc.to(); + + SECTION("JsonArray") { + JsonArray array = var.add(); + array.add(1); + array.add(2); + REQUIRE(doc.as() == "[[1,2]]"); + } + + SECTION("JsonObject") { + JsonObject object = var.add(); + object["hello"] = "world"; + REQUIRE(doc.as() == "[{\"hello\":\"world\"}]"); + } + + SECTION("JsonVariant") { + JsonVariant variant = var.add(); + variant.set(42); + REQUIRE(doc.as() == "[42]"); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/as.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/as.cpp index 01e263e..cacf895 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/as.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/as.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -15,7 +15,7 @@ enum MY_ENUM { ONE = 1, TWO = 2 }; TEST_CASE("JsonVariant::as()") { static const char* null = 0; - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); SECTION("not set") { @@ -251,17 +251,6 @@ TEST_CASE("JsonVariant::as()") { } #endif - SECTION("should work on JsonVariantConst") { - variant.set("hello"); - - JsonVariantConst cvar = variant; - - REQUIRE(cvar.as() == true); - REQUIRE(cvar.as() == 0L); - REQUIRE(cvar.as() == std::string("hello")); - REQUIRE(cvar.as() == std::string("hello")); - } - SECTION("as()") { variant.set(1); diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/clear.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/clear.cpp index d516ca6..b36a52e 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/clear.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/clear.cpp @@ -1,13 +1,16 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include #include +#include "Allocators.hpp" + TEST_CASE("JsonVariant::clear()") { - DynamicJsonDocument doc(4096); + SpyingAllocator spy; + JsonDocument doc(&spy); JsonVariant var = doc.to(); SECTION("size goes back to zero") { @@ -23,4 +26,14 @@ TEST_CASE("JsonVariant::clear()") { REQUIRE(var.isNull() == true); } + + SECTION("releases owned string") { + var.set(std::string("hello")); + var.clear(); + + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofString("hello")), + Deallocate(sizeofString("hello")), + }); + } } diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/compare.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/compare.cpp index 1922df0..3061cdd 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/compare.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/compare.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -9,8 +9,8 @@ // Here, we're just filling the holes TEST_CASE("Compare JsonVariant with value") { - StaticJsonDocument<256> doc; - JsonVariant a = doc.add(); + JsonDocument doc; + JsonVariant a = doc.add(); SECTION("null vs (char*)0") { char* b = 0; @@ -37,9 +37,9 @@ TEST_CASE("Compare JsonVariant with value") { } TEST_CASE("Compare JsonVariant with JsonVariant") { - StaticJsonDocument<256> doc; - JsonVariant a = doc.add(); - JsonVariant b = doc.add(); + JsonDocument doc; + JsonVariant a = doc.add(); + JsonVariant b = doc.add(); SECTION("'abc' vs 'abc'") { a.set("abc"); diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/containsKey.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/containsKey.cpp index d003d11..45af06d 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/containsKey.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/containsKey.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,7 +7,7 @@ #include TEST_CASE("JsonVariant::containsKey()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant var = doc.to(); SECTION("containsKey(const char*)") { @@ -24,19 +24,3 @@ TEST_CASE("JsonVariant::containsKey()") { REQUIRE(var.containsKey(std::string("world")) == false); } } - -TEST_CASE("JsonVariantConst::containsKey()") { - DynamicJsonDocument doc(4096); - doc["hello"] = "world"; - JsonVariantConst cvar = doc.as(); - - SECTION("containsKey(const char*) returns true") { - REQUIRE(cvar.containsKey("hello") == true); - REQUIRE(cvar.containsKey("world") == false); - } - - SECTION("containsKey(std::string) returns true") { - REQUIRE(cvar.containsKey(std::string("hello")) == true); - REQUIRE(cvar.containsKey(std::string("world")) == false); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/converters.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/converters.cpp index cd4e7c2..259c8ac 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/converters.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/converters.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -32,7 +32,7 @@ bool canConvertFromJson(JsonVariantConst src, const Date&) { } // namespace TEST_CASE("Custom converter with overloading") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("convert JSON to Date") { doc["date"]["day"] = 2; @@ -107,7 +107,7 @@ struct Converter { } // namespace ArduinoJson TEST_CASE("Custom converter with specialization") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("convert JSON to Complex") { doc["value"]["real"] = 2; @@ -152,16 +152,3 @@ TEST_CASE("ConverterNeedsWriteableRef") { CHECK(ConverterNeedsWriteableRef::value == true); CHECK(ConverterNeedsWriteableRef::value == false); } - -namespace ArduinoJson { -void convertToJson(char c, JsonVariant var) { - char buf[] = {c, 0}; - var.set(buf); -} -} // namespace ArduinoJson - -TEST_CASE("Convert char to string") { // issue #1922 - StaticJsonDocument<64> doc; - doc.set('a'); - REQUIRE(doc.as() == "a"); -} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/copy.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/copy.cpp index 0d96bf9..1904f57 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/copy.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/copy.cpp @@ -1,19 +1,22 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" TEST_CASE("JsonVariant::set(JsonVariant)") { - DynamicJsonDocument doc1(4096); - DynamicJsonDocument doc2(4096); + KillswitchAllocator killswitch; + SpyingAllocator spyingAllocator(&killswitch); + JsonDocument doc1(&spyingAllocator); + JsonDocument doc2(&spyingAllocator); JsonVariant var1 = doc1.to(); JsonVariant var2 = doc2.to(); SECTION("stores JsonArray by copy") { JsonArray arr = doc2.to(); - JsonObject obj = arr.createNestedObject(); + JsonObject obj = arr.add(); obj["hello"] = "world"; var1.set(arr); @@ -24,7 +27,7 @@ TEST_CASE("JsonVariant::set(JsonVariant)") { SECTION("stores JsonObject by copy") { JsonObject obj = doc2.to(); - JsonArray arr = obj.createNestedArray("value"); + JsonArray arr = obj["value"].to(); arr.add(42); var1.set(obj); @@ -35,53 +38,95 @@ TEST_CASE("JsonVariant::set(JsonVariant)") { SECTION("stores const char* by reference") { var1.set("hello!!"); + spyingAllocator.clearLog(); + var2.set(var1); - REQUIRE(doc1.memoryUsage() == 0); - REQUIRE(doc2.memoryUsage() == 0); + REQUIRE(spyingAllocator.log() == AllocatorLog{}); } SECTION("stores char* by copy") { char str[] = "hello!!"; + var1.set(str); + spyingAllocator.clearLog(); + var2.set(var1); + + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello!!")), + }); + } + + SECTION("fails gracefully if string allocation fails") { + char str[] = "hello!!"; var1.set(str); + killswitch.on(); + spyingAllocator.clearLog(); + var2.set(var1); - REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7)); - REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); + REQUIRE(doc2.overflowed() == true); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + AllocateFail(sizeofString("hello!!")), + }); } SECTION("stores std::string by copy") { var1.set(std::string("hello!!")); + spyingAllocator.clearLog(); + var2.set(var1); - REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7)); - REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello!!")), + }); } - SECTION("stores Serialized by reference") { - var1.set(serialized("hello!!", 8)); + SECTION("stores Serialized by copy") { + var1.set(serialized("hello!!", 7)); + spyingAllocator.clearLog(); + var2.set(var1); - REQUIRE(doc1.memoryUsage() == 0); - REQUIRE(doc2.memoryUsage() == 0); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello!!")), + }); } SECTION("stores Serialized by copy") { char str[] = "hello!!"; var1.set(serialized(str, 7)); + spyingAllocator.clearLog(); + var2.set(var1); - REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7)); - REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello!!")), + }); } SECTION("stores Serialized by copy") { var1.set(serialized(std::string("hello!!"))); + spyingAllocator.clearLog(); + + var2.set(var1); + + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofString("hello!!")), + }); + } + + SECTION("fails gracefully if raw string allocation fails") { + var1.set(serialized(std::string("hello!!"))); + killswitch.on(); + spyingAllocator.clearLog(); + var2.set(var1); - REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7)); - REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); + REQUIRE(doc2.overflowed() == true); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + AllocateFail(sizeofString("hello!!")), + }); } SECTION("destination is unbound") { diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/is.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/is.cpp index 6a414a4..4d07034 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/is.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/is.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,7 +8,7 @@ enum MYENUM2 { ONE = 1, TWO = 2 }; TEST_CASE("JsonVariant::is()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); SECTION("unbound") { @@ -162,158 +162,3 @@ TEST_CASE("JsonVariant::is()") { CHECK(variant.is() == true); } } - -TEST_CASE("JsonVariantConst::is()") { - DynamicJsonDocument doc(4096); - JsonVariant variant = doc.to(); - JsonVariantConst cvariant = variant; - - SECTION("unbound") { - cvariant = JsonVariantConst(); - - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("null") { - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("true") { - variant.set(true); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("false") { - variant.set(false); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("int") { - variant.set(42); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("double") { - variant.set(4.2); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("const char*") { - variant.set("4.2"); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("JsonArray") { - variant.to(); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("JsonObject") { - variant.to(); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/isnull.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/isnull.cpp index bb9de71..75617e9 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/isnull.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/isnull.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonVariant::isNull()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); SECTION("returns true when Undefined") { @@ -20,7 +20,7 @@ TEST_CASE("JsonVariant::isNull()") { } SECTION("returns false when EmptyArray") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonArray array = doc2.to(); variant.set(array); @@ -28,7 +28,7 @@ TEST_CASE("JsonVariant::isNull()") { } SECTION("returns false when EmptyObject") { - DynamicJsonDocument doc2(4096); + JsonDocument doc2; JsonObject obj = doc2.to(); variant.set(obj); @@ -69,25 +69,4 @@ TEST_CASE("JsonVariant::isNull()") { variant.set(serialized(static_cast(0))); REQUIRE(variant.isNull() == true); } - - SECTION("returns true for a shallow null copy") { - StaticJsonDocument<128> doc2; - variant.shallowCopy(doc2); - CHECK(variant.isNull() == true); - } - - SECTION("returns false for a shallow array copy") { - StaticJsonDocument<128> doc2; - doc2[0] = 42; - variant.shallowCopy(doc2); - CHECK(variant.isNull() == false); - } - - SECTION("works with JsonVariantConst") { - variant.set(42); - - JsonVariantConst cvar = variant; - - REQUIRE(cvar.isNull() == false); - } } diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/misc.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/misc.cpp index 7089f64..4b39cf8 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/misc.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/misc.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -10,6 +10,11 @@ TEST_CASE("VariantData") { true); } +TEST_CASE("StringNode") { + REQUIRE(std::is_standard_layout::value == + true); +} + TEST_CASE("JsonVariant from JsonArray") { SECTION("JsonArray is null") { JsonArray arr; @@ -18,7 +23,7 @@ TEST_CASE("JsonVariant from JsonArray") { } SECTION("JsonArray is not null") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray arr = doc.to(); arr.add(12); arr.add(34); @@ -40,7 +45,7 @@ TEST_CASE("JsonVariant from JsonObject") { } SECTION("JsonObject is not null") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); obj["a"] = 12; obj["b"] = 34; diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/nesting.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/nesting.cpp index 1028a28..f2a703f 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/nesting.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/nesting.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonVariant::nesting()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant var = doc.to(); SECTION("return 0 if uninitialized") { diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/nullptr.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/nullptr.cpp index e26d930..434ba5c 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/nullptr.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/nullptr.cpp @@ -3,7 +3,7 @@ #include TEST_CASE("nullptr") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); SECTION("JsonVariant == nullptr") { diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/or.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/or.cpp index 01ec470..937a0cf 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/or.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/or.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonVariant::operator|()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc["value"].to(); SECTION("null") { diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/overflow.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/overflow.cpp index 1123e98..744805f 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/overflow.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/overflow.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,7 +7,7 @@ template void shouldBeOk(TIn value) { - StaticJsonDocument<1> doc; + JsonDocument doc; JsonVariant var = doc.to(); var.set(value); REQUIRE(var.as() == TOut(value)); @@ -15,7 +15,7 @@ void shouldBeOk(TIn value) { template void shouldOverflow(TIn value) { - StaticJsonDocument<1> doc; + JsonDocument doc; JsonVariant var = doc.to(); var.set(value); REQUIRE(var.as() == 0); diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/remove.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/remove.cpp index 0835bf0..3412bc0 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/remove.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/remove.cpp @@ -1,40 +1,83 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include #include -TEST_CASE("JsonVariant::remove()") { - DynamicJsonDocument doc(4096); - JsonVariant var = doc.to(); +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; + +TEST_CASE("JsonVariant::remove(int)") { + SpyingAllocator spy; + JsonDocument doc(&spy); - SECTION("remove(int)") { - var.add(1); - var.add(2); - var.add(3); + SECTION("release top level strings") { + doc.add(std::string("hello")); + doc.add(std::string("hello")); + doc.add(std::string("world")); + JsonVariant var = doc.as(); + REQUIRE(var.as() == "[\"hello\",\"hello\",\"world\"]"); + + spy.clearLog(); var.remove(1); + REQUIRE(var.as() == "[\"hello\",\"world\"]"); + REQUIRE(spy.log() == AllocatorLog{}); - REQUIRE(var.as() == "[1,3]"); + spy.clearLog(); + var.remove(1); + REQUIRE(var.as() == "[\"hello\"]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("world")), + }); + + spy.clearLog(); + var.remove(0); + REQUIRE(var.as() == "[]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("hello")), + }); } - SECTION("remove(const char *)") { - var["a"] = 1; - var["b"] = 2; + SECTION("release strings in nested array") { + doc[0][0] = std::string("hello"); + + JsonVariant var = doc.as(); + REQUIRE(var.as() == "[[\"hello\"]]"); - var.remove("a"); + spy.clearLog(); + var.remove(0); - REQUIRE(var.as() == "{\"b\":2}"); + REQUIRE(var.as() == "[]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("hello")), + }); } +} - SECTION("remove(std::string)") { - var["a"] = 1; - var["b"] = 2; +TEST_CASE("JsonVariant::remove(const char *)") { + JsonDocument doc; + JsonVariant var = doc.to(); - var.remove(std::string("b")); + var["a"] = 1; + var["b"] = 2; - REQUIRE(var.as() == "{\"a\":1}"); - } + var.remove("a"); + + REQUIRE(var.as() == "{\"b\":2}"); +} + +TEST_CASE("JsonVariant::remove(std::string)") { + JsonDocument doc; + JsonVariant var = doc.to(); + + var["a"] = 1; + var["b"] = 2; + + var.remove(std::string("b")); + + REQUIRE(var.as() == "{\"a\":1}"); } diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/set.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/set.cpp index 4743afb..ff02d4a 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/set.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/set.cpp @@ -1,14 +1,18 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofObject; + enum ErrorCode { ERROR_01 = 1, ERROR_10 = 10 }; TEST_CASE("JsonVariant::set() when there is enough memory") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); SECTION("const char*") { @@ -128,7 +132,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") { } TEST_CASE("JsonVariant::set() with not enough memory") { - StaticJsonDocument<1> doc; + JsonDocument doc(FailingAllocator::instance()); JsonVariant v = doc.to(); @@ -155,11 +159,11 @@ TEST_CASE("JsonVariant::set() with not enough memory") { } } -TEST_CASE("JsonVariant::set(DynamicJsonDocument)") { - DynamicJsonDocument doc1(1024); +TEST_CASE("JsonVariant::set(JsonDocument)") { + JsonDocument doc1; doc1["hello"] = "world"; - DynamicJsonDocument doc2(1024); + JsonDocument doc2; JsonVariant v = doc2.to(); // Should copy the doc @@ -170,3 +174,48 @@ TEST_CASE("JsonVariant::set(DynamicJsonDocument)") { serializeJson(doc2, json); REQUIRE(json == "{\"hello\":\"world\"}"); } + +TEST_CASE("JsonVariant::set() releases the previous value") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc["hello"] = std::string("world"); + spy.clearLog(); + + JsonVariant v = doc["hello"]; + + SECTION("int") { + v.set(42); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("world")), + }); + } + + SECTION("bool") { + v.set(false); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("world")), + }); + } + + SECTION("const char*") { + v.set("hello"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("world")), + }); + } + + SECTION("float") { + v.set(1.2); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("world")), + }); + } + + SECTION("Serialized") { + v.set(serialized("[]")); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("world")), + Allocate(sizeofString("[]")), + }); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/size.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/size.cpp index 3a4ec46..2f8e8a7 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/size.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/size.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonVariant::size()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); SECTION("unbound reference") { diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/stl_containers.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/stl_containers.cpp index d6b9b60..05d1020 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/stl_containers.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/stl_containers.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -69,13 +69,13 @@ TEST_CASE("vector") { SECTION("toJson") { std::vector v = {1, 2}; - StaticJsonDocument<128> doc; + JsonDocument doc; doc.set(v); REQUIRE(doc.as() == "[1,2]"); } SECTION("fromJson") { - StaticJsonDocument<128> doc; + JsonDocument doc; doc.add(1); doc.add(2); @@ -86,7 +86,7 @@ TEST_CASE("vector") { } SECTION("checkJson") { - StaticJsonDocument<128> doc; + JsonDocument doc; CHECK(doc.is>() == false); doc.add(1); @@ -106,13 +106,13 @@ TEST_CASE("array") { v[0] = 1; v[1] = 2; - StaticJsonDocument<128> doc; + JsonDocument doc; doc.set(v); REQUIRE(doc.as() == "[1,2]"); } SECTION("fromJson") { - StaticJsonDocument<128> doc; + JsonDocument doc; doc.add(1); doc.add(2); @@ -123,7 +123,7 @@ TEST_CASE("array") { } SECTION("checkJson") { - StaticJsonDocument<128> doc; + JsonDocument doc; CHECK(doc.is() == false); doc.add(1); diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/subscript.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/subscript.cpp index 93f759b..9f2e912 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/subscript.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/subscript.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("JsonVariant::operator[]") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant var = doc.to(); SECTION("The JsonVariant is null") { @@ -50,7 +50,7 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("set value in a nested object") { - array.createNestedObject(); + array.add(); var[0]["hello"] = "world"; @@ -130,75 +130,3 @@ TEST_CASE("JsonVariant::operator[]") { } #endif } - -TEST_CASE("JsonVariantConst::operator[]") { - DynamicJsonDocument doc(4096); - JsonVariant var = doc.to(); - JsonVariantConst cvar = var; - - SECTION("The JsonVariant is null") { - REQUIRE(0 == cvar.size()); - REQUIRE(cvar["0"].isNull()); - REQUIRE(cvar[0].isNull()); - } - - SECTION("The JsonVariant is a string") { - var.set("hello world"); - REQUIRE(0 == cvar.size()); - REQUIRE(cvar["0"].isNull()); - REQUIRE(cvar[0].isNull()); - } - - SECTION("The JsonVariant is a JsonArray") { - JsonArray array = var.to(); - - SECTION("get value") { - array.add("element at index 0"); - array.add("element at index 1"); - - REQUIRE(2 == cvar.size()); - REQUIRE(std::string("element at index 0") == cvar[0]); - REQUIRE(std::string("element at index 1") == cvar[1]); - REQUIRE(std::string("element at index 0") == - var[static_cast(0)]); // issue #381 - REQUIRE(cvar[666].isNull()); - REQUIRE(cvar[3].isNull()); - REQUIRE(cvar["0"].isNull()); - } - } - - SECTION("The JsonVariant is a JsonObject") { - JsonObject object = var.to(); - - SECTION("get value") { - object["a"] = "element at key \"a\""; - object["b"] = "element at key \"b\""; - - REQUIRE(2 == cvar.size()); - REQUIRE(std::string("element at key \"a\"") == cvar["a"]); - REQUIRE(std::string("element at key \"b\"") == cvar["b"]); - REQUIRE(cvar["c"].isNull()); - REQUIRE(cvar[0].isNull()); - } - } - - SECTION("Auto promote null JsonVariant to JsonObject") { - var["hello"] = "world"; - - REQUIRE(var.is() == true); - } - - SECTION("Don't auto promote non-null JsonVariant to JsonObject") { - var.set(42); - var["hello"] = "world"; - - REQUIRE(var.is() == false); - } - - SECTION("Don't auto promote null JsonVariant to JsonObject when reading") { - const char* value = var["hello"]; - - REQUIRE(var.is() == false); - REQUIRE(value == 0); - } -} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/types.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/types.cpp index 4224299..eb0ee62 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/types.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/types.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -9,7 +9,7 @@ template void checkValue(T expected) { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); variant.set(expected); @@ -24,7 +24,7 @@ void checkReference(T& expected) { template void checkNumericType() { - DynamicJsonDocument docMin(4096), docMax(4096); + JsonDocument docMin, docMax; JsonVariant variantMin = docMin.to(); JsonVariant variantMax = docMax.to(); @@ -129,7 +129,7 @@ TEST_CASE("JsonVariant set()/get()") { #endif SECTION("CanStoreObject") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject object = doc.to(); checkValue(object); @@ -137,9 +137,16 @@ TEST_CASE("JsonVariant set()/get()") { } TEST_CASE("volatile") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); + SECTION("volatile bool") { // issue #2029 + volatile bool f = true; + variant.set(f); + CHECK(variant.is() == true); + CHECK(variant.as() == true); + } + SECTION("volatile int") { volatile int f = 42; variant.set(f); diff --git a/third-party/ArduinoJson/extras/tests/JsonVariant/unbound.cpp b/third-party/ArduinoJson/extras/tests/JsonVariant/unbound.cpp index 9020323..fa761a8 100644 --- a/third-party/ArduinoJson/extras/tests/JsonVariant/unbound.cpp +++ b/third-party/ArduinoJson/extras/tests/JsonVariant/unbound.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -44,6 +44,7 @@ TEST_CASE("Unbound JsonVariant") { CHECK_FALSE(variant.set(42L)); CHECK_FALSE(variant.set(42U)); CHECK_FALSE(variant.set(serialized("42"))); + CHECK_FALSE(variant.set(serialized(std::string("42")))); CHECK_FALSE(variant.set(true)); } @@ -63,4 +64,13 @@ TEST_CASE("Unbound JsonVariant") { CHECK_FALSE(variant["key"].set(1)); CHECK_FALSE(variant[std::string("key")].set(1)); } + + SECTION("containsKey()") { + CHECK_FALSE(variant.containsKey("hello")); + } + + SECTION("remove()") { + variant.remove(0); + variant.remove("hello"); + } } diff --git a/third-party/ArduinoJson/extras/tests/JsonVariantConst/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/JsonVariantConst/CMakeLists.txt new file mode 100644 index 0000000..d0dc65e --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonVariantConst/CMakeLists.txt @@ -0,0 +1,20 @@ +# ArduinoJson - https://arduinojson.org +# Copyright © 2014-2024, Benoit BLANCHON +# MIT License + +add_executable(JsonVariantConstTests + as.cpp + containsKey.cpp + is.cpp + isnull.cpp + nesting.cpp + size.cpp + subscript.cpp +) + +add_test(JsonVariantConst JsonVariantConstTests) + +set_tests_properties(JsonVariantConst + PROPERTIES + LABELS "Catch" +) diff --git a/third-party/ArduinoJson/extras/tests/JsonVariantConst/as.cpp b/third-party/ArduinoJson/extras/tests/JsonVariantConst/as.cpp new file mode 100644 index 0000000..6b86f15 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonVariantConst/as.cpp @@ -0,0 +1,19 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include + +TEST_CASE("JsonVariantConst::as()") { + JsonDocument doc; + JsonVariantConst var = doc.to(); + + doc.set("hello"); + + REQUIRE(var.as() == true); + REQUIRE(var.as() == 0L); + REQUIRE(var.as() == std::string("hello")); + REQUIRE(var.as() == std::string("hello")); +} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariantConst/containsKey.cpp b/third-party/ArduinoJson/extras/tests/JsonVariantConst/containsKey.cpp new file mode 100644 index 0000000..7ab9630 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonVariantConst/containsKey.cpp @@ -0,0 +1,33 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include + +TEST_CASE("JsonVariantConst::containsKey()") { + JsonDocument doc; + doc["hello"] = "world"; + JsonVariantConst var = doc.as(); + + SECTION("support const char*") { + REQUIRE(var.containsKey("hello") == true); + REQUIRE(var.containsKey("world") == false); + } + + SECTION("support std::string") { + REQUIRE(var.containsKey(std::string("hello")) == true); + REQUIRE(var.containsKey(std::string("world")) == false); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("supports VLA") { + size_t i = 16; + char vla[i]; + strcpy(vla, "hello"); + + REQUIRE(true == var.containsKey(vla)); + } +#endif +} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariantConst/is.cpp b/third-party/ArduinoJson/extras/tests/JsonVariantConst/is.cpp new file mode 100644 index 0000000..24f9326 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonVariantConst/is.cpp @@ -0,0 +1,162 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +enum MYENUM2 { ONE = 1, TWO = 2 }; + +TEST_CASE("JsonVariantConst::is()") { + JsonDocument doc; + JsonVariantConst var = doc.to(); + + SECTION("unbound") { + var = JsonVariantConst(); + + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } + + SECTION("null") { + CHECK(var.is() == true); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } + + SECTION("true") { + doc.set(true); + + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } + + SECTION("false") { + doc.set(false); + + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } + + SECTION("int") { + doc.set(42); + + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } + + SECTION("double") { + doc.set(4.2); + + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } + + SECTION("const char*") { + doc.set("4.2"); + + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } + + SECTION("JsonArray") { + doc.to(); + + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } + + SECTION("JsonObject") { + doc.to(); + + CHECK(var.is() == true); + CHECK(var.is() == true); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + CHECK(var.is() == false); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariantConst/isnull.cpp b/third-party/ArduinoJson/extras/tests/JsonVariantConst/isnull.cpp new file mode 100644 index 0000000..14572c7 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonVariantConst/isnull.cpp @@ -0,0 +1,21 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonVariantConst::isNull()") { + JsonDocument doc; + JsonVariantConst variant = doc.to(); + + SECTION("returns true when undefined") { + REQUIRE(variant.isNull() == true); + } + + SECTION("returns false if value is integer") { + doc.set(42); + + REQUIRE(variant.isNull() == false); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariantConst/nesting.cpp b/third-party/ArduinoJson/extras/tests/JsonVariantConst/nesting.cpp new file mode 100644 index 0000000..827f766 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonVariantConst/nesting.cpp @@ -0,0 +1,31 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonVariantConst::nesting()") { + JsonDocument doc; + JsonVariantConst var = doc.to(); + + SECTION("return 0 if unbound") { + JsonVariantConst unbound; + REQUIRE(unbound.nesting() == 0); + } + + SECTION("returns 0 for string") { + doc.set("hello"); + REQUIRE(var.nesting() == 0); + } + + SECTION("returns 1 for empty object") { + doc.to(); + REQUIRE(var.nesting() == 1); + } + + SECTION("returns 1 for empty array") { + doc.to(); + REQUIRE(var.nesting() == 1); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariantConst/size.cpp b/third-party/ArduinoJson/extras/tests/JsonVariantConst/size.cpp new file mode 100644 index 0000000..c047951 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonVariantConst/size.cpp @@ -0,0 +1,36 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonVariantConst::size()") { + JsonDocument doc; + JsonVariantConst variant = doc.to(); + + SECTION("unbound reference") { + JsonVariantConst unbound; + + CHECK(unbound.size() == 0); + } + + SECTION("int") { + doc.set(42); + + CHECK(variant.size() == 0); + } + + SECTION("string") { + doc.set("hello"); + + CHECK(variant.size() == 0); + } + + SECTION("object") { + doc["a"] = 1; + doc["b"] = 2; + + CHECK(variant.size() == 2); + } +} diff --git a/third-party/ArduinoJson/extras/tests/JsonVariantConst/subscript.cpp b/third-party/ArduinoJson/extras/tests/JsonVariantConst/subscript.cpp new file mode 100644 index 0000000..70a733b --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/JsonVariantConst/subscript.cpp @@ -0,0 +1,68 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +TEST_CASE("JsonVariantConst::operator[]") { + JsonDocument doc; + JsonVariantConst var = doc.to(); + + SECTION("null") { + REQUIRE(0 == var.size()); + REQUIRE(var["0"].isNull()); + REQUIRE(var[0].isNull()); + } + + SECTION("string") { + doc.set("hello world"); + REQUIRE(0 == var.size()); + REQUIRE(var["0"].isNull()); + REQUIRE(var[0].isNull()); + } + + SECTION("array") { + JsonArray array = doc.to(); + array.add("A"); + array.add("B"); + + REQUIRE(std::string("A") == var[0]); + REQUIRE(std::string("B") == var[1]); + REQUIRE(std::string("A") == + var[static_cast(0)]); // issue #381 + REQUIRE(var[666].isNull()); + REQUIRE(var[3].isNull()); + REQUIRE(var["0"].isNull()); + } + + SECTION("object") { + JsonObject object = doc.to(); + object["a"] = "A"; + object["b"] = "B"; + + SECTION("supports const char*") { + REQUIRE(std::string("A") == var["a"]); + REQUIRE(std::string("B") == var["b"]); + REQUIRE(var["c"].isNull()); + REQUIRE(var[0].isNull()); + } + + SECTION("supports std::string") { + REQUIRE(std::string("A") == var[std::string("a")]); + REQUIRE(std::string("B") == var[std::string("b")]); + REQUIRE(var[std::string("c")].isNull()); + } + +#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \ + !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR) + SECTION("supports VLA") { + size_t i = 16; + char vla[i]; + strcpy(vla, "a"); + + REQUIRE(std::string("A") == var[vla]); + } +#endif + } +} diff --git a/third-party/ArduinoJson/extras/tests/Misc/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/Misc/CMakeLists.txt index 5655a08..2fdc613 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/Misc/CMakeLists.txt @@ -1,11 +1,12 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(MiscTests arithmeticCompare.cpp conflicts.cpp FloatParts.cpp + issue1967.cpp JsonString.cpp NoArduinoHeader.cpp printable.cpp diff --git a/third-party/ArduinoJson/extras/tests/Misc/FloatParts.cpp b/third-party/ArduinoJson/extras/tests/Misc/FloatParts.cpp index 8e3d82e..e75a88d 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/FloatParts.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/FloatParts.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Misc/JsonString.cpp b/third-party/ArduinoJson/extras/tests/Misc/JsonString.cpp index c3dca17..6b9ac5e 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/JsonString.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/JsonString.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Misc/NoArduinoHeader.cpp b/third-party/ArduinoJson/extras/tests/Misc/NoArduinoHeader.cpp index 4b0218b..b589127 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/NoArduinoHeader.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/NoArduinoHeader.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINO 1 diff --git a/third-party/ArduinoJson/extras/tests/Misc/Readers.cpp b/third-party/ArduinoJson/extras/tests/Misc/Readers.cpp index 0b8f4d5..ffb6355 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/Readers.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/Readers.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Misc/StringAdapters.cpp b/third-party/ArduinoJson/extras/tests/Misc/StringAdapters.cpp index 1c77e08..3e5c2b6 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/StringAdapters.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/StringAdapters.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Misc/StringWriter.cpp b/third-party/ArduinoJson/extras/tests/Misc/StringWriter.cpp index 81cb88e..f18e21e 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/StringWriter.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/StringWriter.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -139,9 +139,9 @@ TEST_CASE("Writer") { } TEST_CASE("serializeJson(doc, String)") { - StaticJsonDocument<1024> doc; + JsonDocument doc; doc["hello"] = "world"; - ::String output; + ::String output = "erase me"; SECTION("sufficient capacity") { serializeJson(doc, output); diff --git a/third-party/ArduinoJson/extras/tests/Misc/TypeTraits.cpp b/third-party/ArduinoJson/extras/tests/Misc/TypeTraits.cpp index 10b6168..7beb465 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/TypeTraits.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/TypeTraits.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -193,9 +193,7 @@ TEST_CASE("Polyfills/type_traits") { CHECK(is_convertible, JsonVariantConst>::value == true); CHECK(is_convertible::value == true); - CHECK(is_convertible::value == true); - CHECK(is_convertible, JsonVariantConst>::value == - true); + CHECK(is_convertible::value == true); } SECTION("is_class") { @@ -214,3 +212,8 @@ TEST_CASE("Polyfills/type_traits") { CHECK(is_enum::value == false); } } + +TEST_CASE("is_std_string") { + REQUIRE(is_std_string::value == true); + REQUIRE(is_std_string::value == false); +} diff --git a/third-party/ArduinoJson/extras/tests/Misc/Utf16.cpp b/third-party/ArduinoJson/extras/tests/Misc/Utf16.cpp index 3a59591..4b19fdb 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/Utf16.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/Utf16.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Misc/Utf8.cpp b/third-party/ArduinoJson/extras/tests/Misc/Utf8.cpp index 0c62033..3a60281 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/Utf8.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/Utf8.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -10,9 +10,8 @@ using namespace ArduinoJson::detail; static void testCodepoint(uint32_t codepoint, std::string expected) { - char buffer[4096]; - MemoryPool pool(buffer, 4096); - StringCopier str(&pool); + ResourceManager resources; + StringBuilder str(&resources); str.startString(); CAPTURE(codepoint); diff --git a/third-party/ArduinoJson/extras/tests/Misc/arithmeticCompare.cpp b/third-party/ArduinoJson/extras/tests/Misc/arithmeticCompare.cpp index 2d51754..a879500 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/arithmeticCompare.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/arithmeticCompare.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Misc/conflicts.cpp b/third-party/ArduinoJson/extras/tests/Misc/conflicts.cpp index 75c6c11..d265f34 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/conflicts.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/conflicts.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License // Include any header that might use the conflicting macros @@ -56,7 +56,7 @@ #define _current // issue #1914 -#define V6 6 +#define V7 7 // catch.hpp mutes several warnings, this file also allows to detect them #include "ArduinoJson.h" diff --git a/third-party/ArduinoJson/extras/tests/Misc/custom_string.hpp b/third-party/ArduinoJson/extras/tests/Misc/custom_string.hpp index 4a6a5a7..cabd21b 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/custom_string.hpp +++ b/third-party/ArduinoJson/extras/tests/Misc/custom_string.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/extras/tests/Misc/issue1967.cpp b/third-party/ArduinoJson/extras/tests/Misc/issue1967.cpp new file mode 100644 index 0000000..833fcf0 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/Misc/issue1967.cpp @@ -0,0 +1,13 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +// we expect ArduinoJson.h to include +#define ARDUINOJSON_ENABLE_STD_STRING 1 + +// but we don't want it to included accidentally +#undef ARDUINO +#define ARDUINOJSON_ENABLE_STD_STREAM 0 +#define ARDUINOJSON_ENABLE_STRING_VIEW 0 + +#include diff --git a/third-party/ArduinoJson/extras/tests/Misc/printable.cpp b/third-party/ArduinoJson/extras/tests/Misc/printable.cpp index 09c23ad..6062cce 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/printable.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/printable.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,6 +8,10 @@ #define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1 #include +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; + struct PrintOneCharacterAtATime { static size_t printStringTo(const std::string& s, Print& p) { size_t result = 0; @@ -48,8 +52,9 @@ struct PrintableString : public Printable { TEST_CASE("Printable") { SECTION("Doesn't overflow") { - StaticJsonDocument<8> doc; - const char* value = "example"; // == 7 chars + SpyingAllocator spy; + JsonDocument doc(&spy); + const char* value = "example"; doc.set(666); // to make sure we override the value @@ -59,8 +64,11 @@ TEST_CASE("Printable") { CHECK(doc.as() == value); CHECK(printable.totalBytesWritten() == 7); CHECK(doc.overflowed() == false); - CHECK(doc.memoryUsage() == 8); - CHECK(doc.as().memoryUsage() == 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("example")), + }); } SECTION("Via Print::write(const char* size_t)") { @@ -69,58 +77,90 @@ TEST_CASE("Printable") { CHECK(doc.as() == value); CHECK(printable.totalBytesWritten() == 7); CHECK(doc.overflowed() == false); - CHECK(doc.memoryUsage() == 8); - CHECK(doc.as().memoryUsage() == 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("example")), + }); } } - SECTION("Overflows early") { - StaticJsonDocument<8> doc; - const char* value = "hello world"; // > 8 chars + SECTION("First allocation fails") { + SpyingAllocator spy(FailingAllocator::instance()); + JsonDocument doc(&spy); + const char* value = "hello world"; doc.set(666); // to make sure we override the value SECTION("Via Print::write(char)") { PrintableString printable(value); - CHECK(doc.set(printable) == false); + + bool success = doc.set(printable); + + CHECK(success == false); CHECK(doc.isNull()); - CHECK(printable.totalBytesWritten() == 8); + CHECK(printable.totalBytesWritten() == 0); CHECK(doc.overflowed() == true); - CHECK(doc.memoryUsage() == 0); + CHECK(spy.log() == AllocatorLog{ + AllocateFail(sizeofStringBuffer()), + }); } SECTION("Via Print::write(const char*, size_t)") { PrintableString printable(value); - CHECK(doc.set(printable) == false); + + bool success = doc.set(printable); + + CHECK(success == false); CHECK(doc.isNull()); CHECK(printable.totalBytesWritten() == 0); CHECK(doc.overflowed() == true); - CHECK(doc.memoryUsage() == 0); + CHECK(spy.log() == AllocatorLog{ + AllocateFail(sizeofStringBuffer()), + }); } } - SECTION("Overflows adding terminator") { - StaticJsonDocument<8> doc; - const char* value = "overflow"; // == 8 chars + SECTION("Reallocation fails") { + TimebombAllocator timebomb(1); + SpyingAllocator spy(&timebomb); + JsonDocument doc(&spy); + const char* value = "Lorem ipsum dolor sit amet, cons"; // > 31 chars doc.set(666); // to make sure we override the value SECTION("Via Print::write(char)") { PrintableString printable(value); - CHECK(doc.set(printable) == false); + + bool success = doc.set(printable); + + CHECK(success == false); CHECK(doc.isNull()); - CHECK(printable.totalBytesWritten() == 8); + CHECK(printable.totalBytesWritten() == 31); CHECK(doc.overflowed() == true); - CHECK(doc.memoryUsage() == 0); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + ReallocateFail(sizeofStringBuffer(), sizeofStringBuffer(2)), + Deallocate(sizeofStringBuffer()), + }); } SECTION("Via Print::write(const char*, size_t)") { PrintableString printable(value); - CHECK(doc.set(printable) == false); + + bool success = doc.set(printable); + + CHECK(success == false); CHECK(doc.isNull()); - CHECK(printable.totalBytesWritten() == 0); + CHECK(printable.totalBytesWritten() == 31); CHECK(doc.overflowed() == true); - CHECK(doc.memoryUsage() == 0); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + ReallocateFail(sizeofStringBuffer(), sizeofStringBuffer(2)), + Deallocate(sizeofStringBuffer()), + }); } } @@ -133,12 +173,20 @@ TEST_CASE("Printable") { } SECTION("String deduplication") { - StaticJsonDocument<128> doc; + SpyingAllocator spy; + JsonDocument doc(&spy); doc.add(PrintableString("Hello World!")); doc.add(PrintableString("Hello World!")); REQUIRE(doc.size() == 2); CHECK(doc[0] == "Hello World!"); CHECK(doc[1] == "Hello World!"); - CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 13); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("Hello World!")), + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + }); } } diff --git a/third-party/ArduinoJson/extras/tests/Misc/unsigned_char.cpp b/third-party/ArduinoJson/extras/tests/Misc/unsigned_char.cpp index d3ee492..d7f1134 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/unsigned_char.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/unsigned_char.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -13,7 +13,7 @@ TEST_CASE("unsigned char[]") { SECTION("deserializeJson()") { unsigned char input[] = "{\"a\":42}"; - StaticJsonDocument doc; + JsonDocument doc; DeserializationError err = deserializeJson(doc, input); REQUIRE(err == DeserializationError::Ok); @@ -22,7 +22,7 @@ TEST_CASE("unsigned char[]") { SECTION("deserializeMsgPack()") { unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world"; - StaticJsonDocument doc; + JsonDocument doc; DeserializationError err = deserializeMsgPack(doc, input); REQUIRE(err == DeserializationError::Ok); @@ -30,7 +30,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeMsgPack(unsigned char[])") { unsigned char buffer[32]; - StaticJsonDocument doc; + JsonDocument doc; doc["hello"] = "world"; size_t n = serializeMsgPack(doc, buffer); @@ -41,7 +41,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeMsgPack(unsigned char*)") { unsigned char buffer[32]; - StaticJsonDocument doc; + JsonDocument doc; doc["hello"] = "world"; size_t n = serializeMsgPack(doc, buffer, sizeof(buffer)); @@ -52,7 +52,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeJson(unsigned char[])") { unsigned char buffer[32]; - StaticJsonDocument doc; + JsonDocument doc; doc["hello"] = "world"; size_t n = serializeJson(doc, buffer); @@ -63,7 +63,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeJson(unsigned char*)") { unsigned char buffer[32]; - StaticJsonDocument doc; + JsonDocument doc; doc["hello"] = "world"; size_t n = serializeJson(doc, buffer, sizeof(buffer)); @@ -74,7 +74,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeJsonPretty(unsigned char[])") { unsigned char buffer[32]; - StaticJsonDocument doc; + JsonDocument doc; doc["hello"] = "world"; size_t n = serializeJsonPretty(doc, buffer); @@ -84,7 +84,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeJsonPretty(unsigned char*)") { unsigned char buffer[32]; - StaticJsonDocument doc; + JsonDocument doc; doc["hello"] = "world"; size_t n = serializeJsonPretty(doc, buffer, sizeof(buffer)); @@ -93,7 +93,7 @@ TEST_CASE("unsigned char[]") { } SECTION("JsonVariant") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("set") { unsigned char value[] = "42"; @@ -156,7 +156,7 @@ TEST_CASE("unsigned char[]") { SECTION("operator[]") { unsigned char key[] = "hello"; - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); obj[key] = "world"; @@ -166,7 +166,7 @@ TEST_CASE("unsigned char[]") { SECTION("JsonObject::operator[] const") { unsigned char key[] = "hello"; - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "{\"hello\":\"world\"}"); JsonObject obj = doc.as(); @@ -177,7 +177,7 @@ TEST_CASE("unsigned char[]") { SECTION("containsKey()") { unsigned char key[] = "hello"; - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "{\"hello\":\"world\"}"); JsonObject obj = doc.as(); REQUIRE(true == obj.containsKey(key)); @@ -186,36 +186,20 @@ TEST_CASE("unsigned char[]") { SECTION("remove()") { unsigned char key[] = "hello"; - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "{\"hello\":\"world\"}"); JsonObject obj = doc.as(); obj.remove(key); REQUIRE(0 == obj.size()); } - - SECTION("createNestedArray()") { - unsigned char key[] = "hello"; - - DynamicJsonDocument doc(4096); - JsonObject obj = doc.to(); - obj.createNestedArray(key); - } - - SECTION("createNestedObject()") { - unsigned char key[] = "hello"; - - DynamicJsonDocument doc(4096); - JsonObject obj = doc.to(); - obj.createNestedObject(key); - } } SECTION("MemberProxy") { SECTION("operator=") { // issue #416 unsigned char value[] = "world"; - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); obj["hello"] = value; @@ -225,7 +209,7 @@ TEST_CASE("unsigned char[]") { SECTION("set()") { unsigned char value[] = "world"; - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject obj = doc.to(); obj["hello"].set(value); @@ -237,7 +221,7 @@ TEST_CASE("unsigned char[]") { SECTION("add()") { unsigned char value[] = "world"; - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray arr = doc.to(); arr.add(value); @@ -249,7 +233,7 @@ TEST_CASE("unsigned char[]") { SECTION("set()") { unsigned char value[] = "world"; - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray arr = doc.to(); arr.add("hello"); arr[0].set(value); @@ -260,7 +244,7 @@ TEST_CASE("unsigned char[]") { SECTION("operator=") { unsigned char value[] = "world"; - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonArray arr = doc.to(); arr.add("hello"); arr[0] = value; diff --git a/third-party/ArduinoJson/extras/tests/Misc/version.cpp b/third-party/ArduinoJson/extras/tests/Misc/version.cpp index a91f159..2256fd2 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/version.cpp +++ b/third-party/ArduinoJson/extras/tests/Misc/version.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Misc/weird_strcmp.hpp b/third-party/ArduinoJson/extras/tests/Misc/weird_strcmp.hpp index 5463d7e..c0e5c6c 100644 --- a/third-party/ArduinoJson/extras/tests/Misc/weird_strcmp.hpp +++ b/third-party/ArduinoJson/extras/tests/Misc/weird_strcmp.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/MixedConfiguration/CMakeLists.txt index c2c9dc5..17ea007 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(MixedConfigurationTests @@ -14,8 +14,6 @@ add_executable(MixedConfigurationTests enable_nan_0.cpp enable_nan_1.cpp enable_progmem_1.cpp - enable_string_deduplication_0.cpp - enable_string_deduplication_1.cpp issue1707.cpp use_double_0.cpp use_double_1.cpp diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/decode_unicode_0.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/decode_unicode_0.cpp index b5dc1f1..91b03bb 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/decode_unicode_0.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/decode_unicode_0.cpp @@ -4,7 +4,7 @@ #include TEST_CASE("ARDUINOJSON_DECODE_UNICODE == 0") { - DynamicJsonDocument doc(2048); + JsonDocument doc; DeserializationError err = deserializeJson(doc, "\"\\uD834\\uDD1E\""); REQUIRE(err == DeserializationError::Ok); diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/decode_unicode_1.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/decode_unicode_1.cpp index 2b5b652..0568ab5 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/decode_unicode_1.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/decode_unicode_1.cpp @@ -4,7 +4,7 @@ #include TEST_CASE("ARDUINOJSON_DECODE_UNICODE == 1") { - DynamicJsonDocument doc(2048); + JsonDocument doc; DeserializationError err = deserializeJson(doc, "\"\\uD834\\uDD1E\""); REQUIRE(err == DeserializationError::Ok); diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_comments_0.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_comments_0.cpp index a3ada5e..bffbe7a 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_comments_0.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_comments_0.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_ENABLE_COMMENTS 0 @@ -8,7 +8,7 @@ #include TEST_CASE("Comments should produce InvalidInput") { - DynamicJsonDocument doc(2048); + JsonDocument doc; const char* testCases[] = { "/*COMMENT*/ [\"hello\"]", diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_comments_1.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_comments_1.cpp index 5e0831c..db9c263 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_comments_1.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_comments_1.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_ENABLE_COMMENTS 1 @@ -8,7 +8,7 @@ #include TEST_CASE("Comments in arrays") { - DynamicJsonDocument doc(2048); + JsonDocument doc; SECTION("Block comments") { SECTION("Before opening bracket") { @@ -161,7 +161,7 @@ TEST_CASE("Comments in arrays") { } TEST_CASE("Comments in objects") { - DynamicJsonDocument doc(2048); + JsonDocument doc; SECTION("Block comments") { SECTION("Before opening brace") { @@ -371,7 +371,7 @@ TEST_CASE("Comments in objects") { } TEST_CASE("Comments alone") { - DynamicJsonDocument doc(2048); + JsonDocument doc; SECTION("Just a trailing comment with no line break") { DeserializationError err = deserializeJson(doc, "// comment"); diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_infinity_0.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_infinity_0.cpp index 521fb84..41566e2 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_infinity_0.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_infinity_0.cpp @@ -5,7 +5,7 @@ #include static void assertParseFails(const char* json) { - DynamicJsonDocument doc(4096); + JsonDocument doc; DeserializationError err = deserializeJson(doc, json); REQUIRE(err == DeserializationError::InvalidInput); @@ -20,7 +20,7 @@ static void assertJsonEquals(const JsonDocument& doc, TEST_CASE("ARDUINOJSON_ENABLE_INFINITY == 0") { SECTION("serializeJson()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc.add(std::numeric_limits::infinity()); doc.add(-std::numeric_limits::infinity()); diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_infinity_1.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_infinity_1.cpp index 28a3461..99ab3fe 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_infinity_1.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_infinity_1.cpp @@ -9,7 +9,7 @@ using ArduinoJson::detail::isinf; } // namespace my TEST_CASE("ARDUINOJSON_ENABLE_INFINITY == 1") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("serializeJson()") { doc.add(std::numeric_limits::infinity()); diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_nan_0.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_nan_0.cpp index e015a0d..7491e4a 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_nan_0.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_nan_0.cpp @@ -5,7 +5,7 @@ #include TEST_CASE("ARDUINOJSON_ENABLE_NAN == 0") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject root = doc.to(); SECTION("serializeJson()") { diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_nan_1.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_nan_1.cpp index f9ae04a..20d0874 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_nan_1.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_nan_1.cpp @@ -9,7 +9,7 @@ using ArduinoJson::detail::isnan; } // namespace my TEST_CASE("ARDUINOJSON_ENABLE_NAN == 1") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject root = doc.to(); SECTION("serializeJson()") { diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_progmem_1.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_progmem_1.cpp index 2cc683d..3dc869c 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_progmem_1.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_progmem_1.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_ENABLE_PROGMEM 1 @@ -8,7 +8,7 @@ #include TEST_CASE("Flash strings") { - DynamicJsonDocument doc(2048); + JsonDocument doc; SECTION("deserializeJson()") { DeserializationError err = deserializeJson(doc, F("{'hello':'world'}")); diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/issue1707.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/issue1707.cpp index f8ca566..5dc3c61 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/issue1707.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/issue1707.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINO @@ -10,7 +10,7 @@ #include TEST_CASE("Issue1707") { - StaticJsonDocument<128> doc; + JsonDocument doc; DeserializationError err = deserializeJson(doc, F("{\"hello\":12}")); REQUIRE(err == DeserializationError::Ok); diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_double_0.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_double_0.cpp index f38ee1f..8752890 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_double_0.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_double_0.cpp @@ -4,7 +4,7 @@ #include TEST_CASE("ARDUINOJSON_USE_DOUBLE == 0") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject root = doc.to(); root["pi"] = 3.14; diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_double_1.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_double_1.cpp index ff4a0e3..15c4849 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_double_1.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_double_1.cpp @@ -4,7 +4,7 @@ #include TEST_CASE("ARDUINOJSON_USE_DOUBLE == 1") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject root = doc.to(); root["pi"] = 3.14; diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_long_long_0.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_long_long_0.cpp index f467aab..4c7f0ad 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_long_long_0.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_long_long_0.cpp @@ -4,7 +4,7 @@ #include TEST_CASE("ARDUINOJSON_USE_LONG_LONG == 0") { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc["A"] = 42; doc["B"] = 84; diff --git a/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_long_long_1.cpp b/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_long_long_1.cpp index 5127a55..a2c4fd8 100644 --- a/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_long_long_1.cpp +++ b/third-party/ArduinoJson/extras/tests/MixedConfiguration/use_long_long_1.cpp @@ -4,7 +4,7 @@ #include TEST_CASE("ARDUINOJSON_USE_LONG_LONG == 1") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject root = doc.to(); root["A"] = 123456789123456789; diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/CMakeLists.txt index a544207..61dc8b9 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/CMakeLists.txt @@ -1,19 +1,17 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(MsgPackDeserializerTests deserializeArray.cpp deserializeObject.cpp - deserializeStaticVariant.cpp deserializeVariant.cpp + destination_types.cpp doubleToFloat.cpp + errors.cpp filter.cpp - incompleteInput.cpp input_types.cpp - misc.cpp nestingLimit.cpp - notSupported.cpp ) add_test(MsgPackDeserializer MsgPackDeserializerTests) diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeArray.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeArray.cpp index 356a9fe..053c765 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeArray.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeArray.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("deserialize MsgPack array") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("fixarray") { SECTION("empty") { diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeObject.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeObject.cpp index 4aeb553..675329e 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeObject.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeObject.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("deserialize MsgPack object") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("fixmap") { SECTION("empty") { diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeVariant.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeVariant.cpp index 87f38d6..0136177 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeVariant.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/deserializeVariant.cpp @@ -1,13 +1,15 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include -template -static void check(const char* input, U expected) { - DynamicJsonDocument doc(4096); +#include "Allocators.hpp" + +template +static void checkValue(const char* input, T expected) { + JsonDocument doc; DeserializationError error = deserializeMsgPack(doc, input); @@ -16,132 +18,224 @@ static void check(const char* input, U expected) { REQUIRE(doc.as() == expected); } -#if ARDUINOJSON_USE_LONG_LONG == 0 -static void checkNotSupported(const char* input) { - DynamicJsonDocument doc(4096); - DeserializationError error = deserializeMsgPack(doc, input); - REQUIRE(error == DeserializationError::Ok); - REQUIRE(doc.isNull()); -} -#endif - -static void checkIsNull(const char* input) { - DynamicJsonDocument doc(4096); +static void checkError(size_t timebombCountDown, const char* input, + DeserializationError expected) { + TimebombAllocator timebomb(timebombCountDown); + JsonDocument doc(&timebomb); DeserializationError error = deserializeMsgPack(doc, input); - REQUIRE(error == DeserializationError::Ok); - REQUIRE(doc.as().isNull()); + CAPTURE(input); + REQUIRE(error == expected); } TEST_CASE("deserialize MsgPack value") { SECTION("nil") { - checkIsNull("\xc0"); + checkValue("\xc0", nullptr); } SECTION("bool") { - check("\xc2", false); - check("\xc3", true); + checkValue("\xc2", false); + checkValue("\xc3", true); } SECTION("positive fixint") { - check("\x00", 0); - check("\x7F", 127); + checkValue("\x00", 0); + checkValue("\x7F", 127); } SECTION("negative fixint") { - check("\xe0", -32); - check("\xff", -1); + checkValue("\xe0", -32); + checkValue("\xff", -1); } SECTION("uint 8") { - check("\xcc\x00", 0); - check("\xcc\xff", 255); + checkValue("\xcc\x00", 0); + checkValue("\xcc\xff", 255); } SECTION("uint 16") { - check("\xcd\x00\x00", 0); - check("\xcd\xFF\xFF", 65535); - check("\xcd\x30\x39", 12345); + checkValue("\xcd\x00\x00", 0); + checkValue("\xcd\xFF\xFF", 65535); + checkValue("\xcd\x30\x39", 12345); } SECTION("uint 32") { - check("\xCE\x00\x00\x00\x00", 0x00000000U); - check("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU); - check("\xCE\x12\x34\x56\x78", 0x12345678U); + checkValue("\xCE\x00\x00\x00\x00", 0x00000000U); + checkValue("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU); + checkValue("\xCE\x12\x34\x56\x78", 0x12345678U); } SECTION("uint 64") { #if ARDUINOJSON_USE_LONG_LONG - check("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U); - check("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 0xFFFFFFFFFFFFFFFFU); - check("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", - 0x123456789ABCDEF0U); + checkValue("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U); + checkValue("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + 0xFFFFFFFFFFFFFFFFU); + checkValue("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", + 0x123456789ABCDEF0U); #else - checkNotSupported("\xCF\x00\x00\x00\x00\x00\x00\x00\x00"); - checkNotSupported("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); - checkNotSupported("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0"); + checkValue("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", nullptr); + checkValue("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr); + checkValue("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr); #endif } SECTION("int 8") { - check("\xd0\x00", 0); - check("\xd0\xff", -1); + checkValue("\xd0\x00", 0); + checkValue("\xd0\xff", -1); } SECTION("int 16") { - check("\xD1\x00\x00", 0); - check("\xD1\xFF\xFF", -1); - check("\xD1\xCF\xC7", -12345); + checkValue("\xD1\x00\x00", 0); + checkValue("\xD1\xFF\xFF", -1); + checkValue("\xD1\xCF\xC7", -12345); } SECTION("int 32") { - check("\xD2\x00\x00\x00\x00", 0); - check("\xD2\xFF\xFF\xFF\xFF", -1); - check("\xD2\xB6\x69\xFD\x2E", -1234567890); + checkValue("\xD2\x00\x00\x00\x00", 0); + checkValue("\xD2\xFF\xFF\xFF\xFF", -1); + checkValue("\xD2\xB6\x69\xFD\x2E", -1234567890); } SECTION("int 64") { #if ARDUINOJSON_USE_LONG_LONG - check("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", int64_t(0U)); - check("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - int64_t(0xFFFFFFFFFFFFFFFFU)); - check("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", - int64_t(0x123456789ABCDEF0)); + checkValue("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", int64_t(0U)); + checkValue("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + int64_t(0xFFFFFFFFFFFFFFFFU)); + checkValue("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", + int64_t(0x123456789ABCDEF0)); #else - checkNotSupported("\xD3\x00\x00\x00\x00\x00\x00\x00\x00"); - checkNotSupported("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); - checkNotSupported("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0"); + checkValue("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", nullptr); + checkValue("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr); + checkValue("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr); #endif } SECTION("float 32") { - check("\xCA\x00\x00\x00\x00", 0.0f); - check("\xCA\x40\x48\xF5\xC3", 3.14f); + checkValue("\xCA\x00\x00\x00\x00", 0.0f); + checkValue("\xCA\x40\x48\xF5\xC3", 3.14f); } SECTION("float 64") { - check("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0); - check("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415); + checkValue("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0); + checkValue("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415); + } + + SECTION("fixstr") { + checkValue("\xA0", std::string("")); + checkValue("\xABhello world", std::string("hello world")); + checkValue("\xBFhello world hello world hello !", + std::string("hello world hello world hello !")); + } + + SECTION("str 8") { + checkValue("\xd9\x05hello", std::string("hello")); + } + + SECTION("str 16") { + checkValue("\xda\x00\x05hello", std::string("hello")); + } + + SECTION("str 32") { + checkValue("\xdb\x00\x00\x00\x05hello", std::string("hello")); + } +} + +TEST_CASE("deserializeMsgPack() under memory constaints") { + SECTION("single values always fit") { + checkError(0, "\xc0", DeserializationError::Ok); // nil + checkError(0, "\xc2", DeserializationError::Ok); // false + checkError(0, "\xc3", DeserializationError::Ok); // true + checkError(0, "\xcc\x00", DeserializationError::Ok); // uint 8 + checkError(0, "\xcd\x30\x39", DeserializationError::Ok); // uint 16 + checkError(0, "\xCE\x12\x34\x56\x78", + DeserializationError::Ok); // uint 32 } SECTION("fixstr") { - check("\xA0", std::string("")); - check("\xABhello world", std::string("hello world")); - check("\xBFhello world hello world hello !", - std::string("hello world hello world hello !")); + checkError(2, "\xA7ZZZZZZZ", DeserializationError::Ok); + checkError(0, "\xA7ZZZZZZZ", DeserializationError::NoMemory); } SECTION("str 8") { - check("\xd9\x05hello", std::string("hello")); + checkError(2, "\xD9\x07ZZZZZZZ", DeserializationError::Ok); + checkError(0, "\xD9\x07ZZZZZZZ", DeserializationError::NoMemory); } SECTION("str 16") { - check("\xda\x00\x05hello", std::string("hello")); + checkError(2, "\xDA\x00\x07ZZZZZZZ", DeserializationError::Ok); + checkError(0, "\xDA\x00\x07ZZZZZZZ", DeserializationError::NoMemory); } SECTION("str 32") { - check("\xdb\x00\x00\x00\x05hello", std::string("hello")); + checkError(2, "\xDB\x00\x00\x00\x07ZZZZZZZ", DeserializationError::Ok); + checkError(0, "\xDB\x00\x00\x00\x07ZZZZZZZ", + DeserializationError::NoMemory); + } + + SECTION("fixarray") { + checkError(0, "\x90", DeserializationError::Ok); // [] + checkError(0, "\x91\x01", + DeserializationError::NoMemory); // [1] + checkError(1, "\x91\x01", + DeserializationError::Ok); // [1] + } + + SECTION("array 16") { + checkError(0, "\xDC\x00\x00", DeserializationError::Ok); + checkError(0, "\xDC\x00\x01\x01", DeserializationError::NoMemory); + checkError(1, "\xDC\x00\x01\x01", DeserializationError::Ok); + } + + SECTION("array 32") { + checkError(0, "\xDD\x00\x00\x00\x00", DeserializationError::Ok); + checkError(0, "\xDD\x00\x00\x00\x01\x01", DeserializationError::NoMemory); + checkError(1, "\xDD\x00\x00\x00\x01\x01", DeserializationError::Ok); + } + + SECTION("fixmap") { + SECTION("{}") { + checkError(0, "\x80", DeserializationError::Ok); + } + SECTION("{H:1}") { + checkError(0, "\x81\xA1H\x01", DeserializationError::NoMemory); + checkError(3, "\x81\xA1H\x01", DeserializationError::Ok); + } + SECTION("{H:1,W:2}") { + checkError(3, "\x82\xA1H\x01\xA1W\x02", DeserializationError::NoMemory); + checkError(5, "\x82\xA1H\x01\xA1W\x02", DeserializationError::Ok); + } + } + + SECTION("map 16") { + SECTION("{}") { + checkError(0, "\xDE\x00\x00", DeserializationError::Ok); + } + SECTION("{H:1}") { + checkError(2, "\xDE\x00\x01\xA1H\x01", DeserializationError::NoMemory); + checkError(3, "\xDE\x00\x01\xA1H\x01", DeserializationError::Ok); + } + SECTION("{H:1,W:2}") { + checkError(3, "\xDE\x00\x02\xA1H\x01\xA1W\x02", + DeserializationError::NoMemory); + checkError(5, "\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok); + } + } + + SECTION("map 32") { + SECTION("{}") { + checkError(0, "\xDF\x00\x00\x00\x00", DeserializationError::Ok); + } + SECTION("{H:1}") { + checkError(2, "\xDF\x00\x00\x00\x01\xA1H\x01", + DeserializationError::NoMemory); + checkError(3, "\xDF\x00\x00\x00\x01\xA1H\x01", DeserializationError::Ok); + } + SECTION("{H:1,W:2}") { + checkError(3, "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", + DeserializationError::NoMemory); + checkError(5, "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", + DeserializationError::Ok); + } } } diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/destination_types.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/destination_types.cpp new file mode 100644 index 0000000..d8b9db1 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/destination_types.cpp @@ -0,0 +1,108 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include + +#include +#include + +#include "Allocators.hpp" + +using ArduinoJson::detail::sizeofArray; +using ArduinoJson::detail::sizeofObject; + +TEST_CASE("deserializeMsgPack(JsonDocument&)") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc.add(std::string("hello")); + spy.clearLog(); + + auto err = deserializeMsgPack(doc, "\x91\x2A"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "[42]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofPool()), + Deallocate(sizeofString("hello")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofArray(1)), + }); +} + +TEST_CASE("deserializeMsgPack(JsonVariant)") { + SECTION("variant is bound") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc.add(std::string("hello")); + spy.clearLog(); + + JsonVariant variant = doc[0]; + + auto err = deserializeMsgPack(variant, "\x91\x2A"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "[[42]]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("hello")), + }); + } + + SECTION("variant is unbound") { + JsonVariant variant; + + auto err = deserializeMsgPack(variant, "\x91\x2A"); + + REQUIRE(err == DeserializationError::NoMemory); + } +} + +TEST_CASE("deserializeMsgPack(ElementProxy)") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc.add(std::string("hello")); + spy.clearLog(); + + SECTION("element already exists") { + auto err = deserializeMsgPack(doc[0], "\x91\x2A"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "[[42]]"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("hello")), + }); + } + + SECTION("element must be created exists") { + auto err = deserializeMsgPack(doc[1], "\x91\x2A"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "[\"hello\",[42]]"); + REQUIRE(spy.log() == AllocatorLog{}); + } +} + +TEST_CASE("deserializeMsgPack(MemberProxy)") { + SpyingAllocator spy; + JsonDocument doc(&spy); + doc[std::string("hello")] = std::string("world"); + spy.clearLog(); + + SECTION("member already exists") { + auto err = deserializeMsgPack(doc["hello"], "\x91\x2A"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "{\"hello\":[42]}"); + REQUIRE(spy.log() == AllocatorLog{ + Deallocate(sizeofString("world")), + }); + } + + SECTION("member must be created") { + auto err = deserializeMsgPack(doc["value"], "\x91\x2A"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "{\"hello\":\"world\",\"value\":[42]}"); + REQUIRE(spy.log() == AllocatorLog{}); + } +} diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/doubleToFloat.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/doubleToFloat.cpp index fb2c25d..b0e2948 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/doubleToFloat.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/doubleToFloat.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/errors.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/errors.cpp new file mode 100644 index 0000000..d81d489 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/errors.cpp @@ -0,0 +1,265 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include + +TEST_CASE("deserializeMsgPack() returns InvalidInput") { + JsonDocument doc; + + SECTION("integer as key") { + auto err = deserializeMsgPack(doc, "\x81\x01\xA1H", 3); + REQUIRE(err == DeserializationError::InvalidInput); + } +} + +TEST_CASE("deserializeMsgPack() returns EmptyInput") { + JsonDocument doc; + + SECTION("from sized buffer") { + auto err = deserializeMsgPack(doc, "", 0); + + REQUIRE(err == DeserializationError::EmptyInput); + } + + SECTION("from stream") { + std::istringstream input(""); + + auto err = deserializeMsgPack(doc, input); + + REQUIRE(err == DeserializationError::EmptyInput); + } +} + +static void testIncompleteInput(const char* input, size_t len) { + JsonDocument doc; + REQUIRE(deserializeMsgPack(doc, input, len) == DeserializationError::Ok); + + while (--len) { + REQUIRE(deserializeMsgPack(doc, input, len) == + DeserializationError::IncompleteInput); + } +} + +TEST_CASE("deserializeMsgPack() returns IncompleteInput") { + SECTION("empty input") { + testIncompleteInput("\x00", 1); + } + + SECTION("fixarray") { + testIncompleteInput("\x91\x01", 2); + } + + SECTION("array 16") { + testIncompleteInput("\xDC\x00\x01\x01", 4); + } + + SECTION("array 32") { + testIncompleteInput("\xDD\x00\x00\x00\x01\x01", 6); + } + + SECTION("fixmap") { + testIncompleteInput("\x81\xA3one\x01", 6); + } + + SECTION("map 16") { + testIncompleteInput("\xDE\x00\x01\xA3one\x01", 8); + } + + SECTION("map 32") { + testIncompleteInput("\xDF\x00\x00\x00\x01\xA3one\x01", 10); + testIncompleteInput("\xDF\x00\x00\x00\x01\xd9\x03one\x01", 11); + } + + SECTION("uint 8") { + testIncompleteInput("\xcc\x01", 2); + } + + SECTION("uint 16") { + testIncompleteInput("\xcd\x00\x01", 3); + } + + SECTION("uint 32") { + testIncompleteInput("\xCE\x00\x00\x00\x01", 5); + } + +#if ARDUINOJSON_USE_LONG_LONG + SECTION("uint 64") { + testIncompleteInput("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 9); + } +#endif + + SECTION("int 8") { + testIncompleteInput("\xD0\x01", 2); + } + + SECTION("int 16") { + testIncompleteInput("\xD1\x00\x01", 3); + } + + SECTION("int 32") { + testIncompleteInput("\xD2\x00\x00\x00\x01", 5); + } + +#if ARDUINOJSON_USE_LONG_LONG + SECTION("int 64") { + testIncompleteInput("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", 9); + } +#endif + + SECTION("float 32") { + testIncompleteInput("\xCA\x40\x48\xF5\xC3", 5); + } + + SECTION("float 64") { + testIncompleteInput("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 9); + } + + SECTION("fixstr") { + testIncompleteInput("\xABhello world", 12); + } + + SECTION("str 8") { + testIncompleteInput("\xd9\x05hello", 7); + } + + SECTION("str 16") { + testIncompleteInput("\xda\x00\x05hello", 8); + } + + SECTION("str 32") { + testIncompleteInput("\xdb\x00\x00\x00\x05hello", 10); + } + + SECTION("bin 8") { + testIncompleteInput("\xc4\x01X", 3); + } + + SECTION("bin 16") { + testIncompleteInput("\xc5\x00\x01X", 4); + } + + SECTION("bin 32") { + testIncompleteInput("\xc6\x00\x00\x00\x01X", 6); + } + + SECTION("ext 8") { + testIncompleteInput("\xc7\x01\x01\x01", 4); + } + + SECTION("ext 16") { + testIncompleteInput("\xc8\x00\x01\x01\x01", 5); + } + + SECTION("ext 32") { + testIncompleteInput("\xc9\x00\x00\x00\x01\x01\x01", 7); + } + + SECTION("fixext 1") { + testIncompleteInput("\xd4\x01\x01", 3); + } + + SECTION("fixext 2") { + testIncompleteInput("\xd5\x01\x01\x02", 4); + } + + SECTION("fixext 4") { + testIncompleteInput("\xd6\x01\x01\x02\x03\x04", 6); + } + + SECTION("fixext 8") { + testIncompleteInput("\xd7\x01\x01\x02\x03\x04\x05\x06\x07\x08", 10); + } + + SECTION("fixext 16") { + testIncompleteInput( + "\xd8\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E" + "\x0F\x10", + 18); + } +} + +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(); +} + +TEST_CASE("deserializeMsgPack() replaces unsupported types by null") { + SECTION("bin 8") { + REQUIRE(msgPackToJson("\x92\xc4\x01X\x2A", 5) == "[null,42]"); + } + + SECTION("bin 16") { + REQUIRE(msgPackToJson("\x92\xc5\x00\x01X\x2A", 6) == "[null,42]"); + } + + SECTION("bin 32") { + REQUIRE(msgPackToJson("\x92\xc6\x00\x00\x00\x01X\x2A", 8) == "[null,42]"); + } + + 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 is string length overflows") { + JsonDocument doc; + auto maxLength = ArduinoJson::detail::StringNode::maxLength; + + SECTION("max length should succeed") { + auto len = maxLength; + std::string prefix = {'\xdb', char(len >> 24), char(len >> 16), + char(len >> 8), char(len)}; + + auto err = deserializeMsgPack(doc, prefix + std::string(len, 'a')); + REQUIRE(err == DeserializationError::Ok); + } + + SECTION("one above max length should fail") { + auto len = maxLength + 1; + std::string prefix = {'\xdb', char(len >> 24), char(len >> 16), + char(len >> 8), char(len)}; + + auto err = deserializeMsgPack(doc, prefix + std::string(len, 'a')); + REQUIRE(err == DeserializationError::NoMemory); + } +} diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/filter.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/filter.cpp index 78700db..c119822 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/filter.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/filter.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,13 +7,16 @@ #include +#include "Allocators.hpp" + using namespace ArduinoJson::detail; TEST_CASE("deserializeMsgPack() filter") { - StaticJsonDocument<4096> doc; + SpyingAllocator spy; + JsonDocument doc(&spy); DeserializationError error; - StaticJsonDocument<200> filter; + JsonDocument filter; DeserializationOption::Filter filterOpt(filter); SECTION("root is fixmap") { @@ -26,7 +29,10 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::IncompleteInput); CHECK(doc.as() == "{}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + CHECK(spy.log() == AllocatorLog{ + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + }); } SECTION("input truncated after inside skipped uint 8") { @@ -35,7 +41,10 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::IncompleteInput); CHECK(doc.as() == "{}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + CHECK(spy.log() == AllocatorLog{ + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + }); } SECTION("input truncated after before skipped string size") { @@ -43,7 +52,10 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::IncompleteInput); CHECK(doc.as() == "{}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + CHECK(spy.log() == AllocatorLog{ + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + }); } SECTION("input truncated after before skipped ext size") { @@ -51,7 +63,10 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::IncompleteInput); CHECK(doc.as() == "{}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + CHECK(spy.log() == AllocatorLog{ + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + }); } SECTION("skip nil") { @@ -60,7 +75,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("reject 0xc1") { @@ -68,6 +89,10 @@ TEST_CASE("deserializeMsgPack() filter") { filterOpt); CHECK(error == DeserializationError::InvalidInput); + CHECK(spy.log() == AllocatorLog{ + Allocate(sizeofStringBuffer()), + Deallocate(sizeofStringBuffer()), + }); } SECTION("skip false") { @@ -76,7 +101,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip true") { @@ -85,7 +116,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip positive fixint") { @@ -94,7 +131,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip negative fixint") { @@ -103,7 +146,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip uint 8") { @@ -112,7 +161,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip int 8") { @@ -121,7 +176,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip uint 16") { @@ -130,7 +191,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip int 16") { @@ -139,7 +206,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip uint 32") { @@ -149,7 +222,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip int 32") { @@ -159,7 +238,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip uint 64") { @@ -170,7 +255,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip int 64") { @@ -181,7 +272,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip float 32") { @@ -191,7 +288,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip float 64") { @@ -202,7 +305,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip fixstr") { @@ -211,7 +320,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip str 8") { @@ -220,7 +335,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip str 16") { @@ -229,7 +350,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip str 32") { @@ -239,7 +366,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip bin 8") { @@ -248,7 +381,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip bin 16") { @@ -257,7 +396,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip bin 32") { @@ -267,7 +412,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip fixarray") { @@ -276,7 +427,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip array 16") { @@ -286,7 +443,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip array 32") { @@ -299,7 +462,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip fixmap") { @@ -309,7 +478,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip map 16") { @@ -321,7 +496,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip map 32") { @@ -335,7 +516,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip fixext 1") { @@ -347,7 +534,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip fixext 2") { @@ -359,7 +552,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip fixext 4") { @@ -371,7 +570,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip fixext 8") { @@ -383,7 +588,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip fixext 16") { @@ -397,7 +608,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip ext 8") { @@ -409,7 +626,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip ext 16") { @@ -421,7 +644,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } SECTION("skip ext 32") { @@ -433,7 +662,13 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofObject(1)), + }); } } @@ -454,8 +689,18 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":[{\"measure\":2},{\"measure\":4}],\"include\":42}"); - CHECK(doc.memoryUsage() == - JSON_ARRAY_SIZE(2) + 2 * JSON_OBJECT_SIZE(2) + 24); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("measure")), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2) + sizeofArray(2) + + 2 * sizeofObject(1)), + }); } SECTION("include array 16") { @@ -470,8 +715,18 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":[{\"measure\":2},{\"measure\":4}],\"include\":42}"); - CHECK(doc.memoryUsage() == - JSON_ARRAY_SIZE(2) + 2 * JSON_OBJECT_SIZE(2) + 24); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("measure")), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2) + sizeofArray(2) + + 2 * sizeofObject(1)), + }); } SECTION("include array 32") { @@ -486,8 +741,18 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":[{\"measure\":2},{\"measure\":4}],\"include\":42}"); - CHECK(doc.memoryUsage() == - JSON_ARRAY_SIZE(2) + 2 * JSON_OBJECT_SIZE(2) + 24); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("measure")), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2) + sizeofArray(2) + + 2 * sizeofObject(1)), + }); } SECTION("skip null") { @@ -496,7 +761,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip false") { @@ -505,7 +778,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip true") { @@ -514,7 +795,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip positive fixint") { @@ -523,7 +812,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip negative fixint") { @@ -532,7 +829,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip uint 8") { @@ -541,7 +846,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip uint 16") { @@ -550,7 +863,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip uint 32") { @@ -560,7 +881,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip uint 64") { @@ -571,7 +900,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip int 8") { @@ -580,7 +917,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip int 16") { @@ -589,7 +934,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip int 32") { @@ -599,7 +952,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip int 64") { @@ -610,7 +971,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip float 32") { @@ -620,7 +989,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip float 64") { @@ -631,7 +1008,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip fixstr") { @@ -640,7 +1025,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip str 8") { @@ -662,7 +1055,15 @@ TEST_CASE("deserializeMsgPack() filter") { doc, "\x82\xA7onlyarr\xdb\x00\x00\x00\x05hello\xA7include\x2A", filterOpt); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip fixmap") { @@ -672,7 +1073,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip map 16") { @@ -684,7 +1093,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip map 32") { @@ -698,7 +1115,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyarr\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } } } @@ -713,7 +1138,7 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "[]"); - CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); + CHECK(spy.log() == AllocatorLog()); } } @@ -726,7 +1151,10 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "[1,2,3]"); - CHECK(doc.memoryUsage() == JSON_ARRAY_SIZE(3)); + CHECK(spy.log() == AllocatorLog{ + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeofArray(3)), + }); } } } @@ -747,8 +1175,17 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":{\"measure\":2},\"include\":42}"); - CHECK(doc.memoryUsage() == - JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(1) + 24); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyobj")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("measure")), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2) + sizeofObject(1)), + }); } SECTION("include map 16") { @@ -761,8 +1198,17 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":{\"measure\":2},\"include\":42}"); - CHECK(doc.memoryUsage() == - JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(1) + 24); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyobj")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("measure")), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2) + sizeofObject(1)), + }); } SECTION("include map 32") { @@ -776,8 +1222,17 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":{\"measure\":2},\"include\":42}"); - CHECK(doc.memoryUsage() == - JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(1) + 24); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyobj")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("measure")), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2) + sizeofObject(1)), + }); } SECTION("skip null") { @@ -786,7 +1241,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip false") { @@ -795,7 +1258,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip true") { @@ -804,7 +1275,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip positive fixint") { @@ -813,7 +1292,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip negative fixint") { @@ -822,7 +1309,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip uint 8") { @@ -831,7 +1326,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip uint 16") { @@ -840,7 +1343,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip uint 32") { @@ -849,7 +1360,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip uint 64") { @@ -860,7 +1379,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip int 8") { @@ -869,7 +1396,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip int 16") { @@ -878,7 +1413,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip int 32") { @@ -887,7 +1430,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip int 64") { @@ -898,7 +1449,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip float 32") { @@ -907,7 +1466,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip float 64") { @@ -918,7 +1485,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip fixstr") { @@ -927,7 +1502,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip str 8") { @@ -949,7 +1532,15 @@ TEST_CASE("deserializeMsgPack() filter") { doc, "\x82\xA7onlyobj\xdb\x00\x00\x00\x05hello\xA7include\x2A", filterOpt); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip fixarray") { @@ -958,7 +1549,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip array 16") { @@ -969,7 +1568,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } SECTION("skip array 32") { @@ -981,7 +1588,15 @@ TEST_CASE("deserializeMsgPack() filter") { CHECK(error == DeserializationError::Ok); CHECK(doc.as() == "{\"onlyobj\":null,\"include\":42}"); - CHECK(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16); + CHECK(spy.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")), + Allocate(sizeofPool()), + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("include")), + Reallocate(sizeofPool(), sizeofObject(2)), + }); } } @@ -1032,10 +1647,10 @@ TEST_CASE("deserializeMsgPack() filter") { TEST_CASE("Zero-copy mode") { // issue #1697 char input[] = "\x82\xA7include\x01\xA6ignore\x02"; - StaticJsonDocument<256> filter; + JsonDocument filter; filter["include"] = true; - StaticJsonDocument<256> doc; + JsonDocument doc; DeserializationError err = deserializeMsgPack(doc, input, 18, DeserializationOption::Filter(filter)); @@ -1044,8 +1659,8 @@ TEST_CASE("Zero-copy mode") { // issue #1697 } TEST_CASE("Overloads") { - StaticJsonDocument<256> doc; - StaticJsonDocument<256> filter; + JsonDocument doc; + JsonDocument filter; using namespace DeserializationOption; diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/input_types.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/input_types.cpp index 783aaa2..5417d9c 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/input_types.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/input_types.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -7,8 +7,10 @@ #include "CustomReader.hpp" +using ArduinoJson::detail::sizeofObject; + TEST_CASE("deserializeMsgPack(const std::string&)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("should accept const string") { const std::string input("\x92\x01\x02"); @@ -48,7 +50,7 @@ TEST_CASE("deserializeMsgPack(const std::string&)") { } TEST_CASE("deserializeMsgPack(std::istream&)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("should accept a zero in input") { std::istringstream input(std::string("\x92\x00\x02", 3)); @@ -76,7 +78,7 @@ TEST_CASE("deserializeMsgPack(VLA)") { char vla[i]; memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15); - StaticJsonDocument doc; + JsonDocument doc; DeserializationError err = deserializeMsgPack(doc, vla); REQUIRE(err == DeserializationError::Ok); @@ -84,7 +86,7 @@ TEST_CASE("deserializeMsgPack(VLA)") { #endif TEST_CASE("deserializeMsgPack(CustomReader)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; CustomReader reader("\x92\xA5Hello\xA5world"); DeserializationError err = deserializeMsgPack(doc, reader); diff --git a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/nestingLimit.cpp b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/nestingLimit.cpp index 2936415..206600c 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/nestingLimit.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackDeserializer/nestingLimit.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -12,7 +12,7 @@ REQUIRE(DeserializationError::TooDeep == expression); TEST_CASE("JsonDeserializer nesting") { - DynamicJsonDocument doc(4096); + JsonDocument doc; SECTION("Input = const char*") { SECTION("limit = 0") { diff --git a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/CMakeLists.txt index 2f3d8cc..25b0384 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(MsgPackSerializerTests diff --git a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/destination_types.cpp b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/destination_types.cpp index 8b0dffa..569d5f7 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/destination_types.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/destination_types.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("serialize MsgPack to various destination types") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject object = doc.to(); object["hello"] = "world"; const char* expected_result = "\x81\xA5hello\xA5world"; diff --git a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/measure.cpp b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/measure.cpp index a6a4fc9..e1480e2 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/measure.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/measure.cpp @@ -1,12 +1,12 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include TEST_CASE("measureMsgPack()") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject object = doc.to(); object["hello"] = "world"; diff --git a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/misc.cpp b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/misc.cpp index 4753dbf..bea9b24 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/misc.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/misc.cpp @@ -4,7 +4,7 @@ template void check(T value, const std::string& expected) { - DynamicJsonDocument doc(4096); + JsonDocument doc; doc.to().set(value); char buffer[256] = ""; size_t returnValue = serializeMsgPack(doc, buffer, sizeof(buffer)); @@ -13,7 +13,7 @@ void check(T value, const std::string& expected) { } TEST_CASE("serializeMsgPack(MemberProxy)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "{\"hello\":42}"); JsonObject obj = doc.as(); std::string result; @@ -24,7 +24,7 @@ TEST_CASE("serializeMsgPack(MemberProxy)") { } TEST_CASE("serializeMsgPack(ElementProxy)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "[42]"); JsonArray arr = doc.as(); std::string result; @@ -35,7 +35,7 @@ TEST_CASE("serializeMsgPack(ElementProxy)") { } TEST_CASE("serializeMsgPack(JsonVariantSubscript)") { - DynamicJsonDocument doc(4096); + JsonDocument doc; deserializeJson(doc, "[42]"); JsonVariant var = doc.as(); std::string result; diff --git a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeArray.cpp b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeArray.cpp index a8ec639..2310085 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeArray.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeArray.cpp @@ -1,7 +1,9 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License +#define ARDUINOJSON_SLOT_ID_SIZE 4 // required to reach 65536 elements + #include #include @@ -26,7 +28,7 @@ static void check(const JsonArray array, const std::string& expected) { } TEST_CASE("serialize MsgPack array") { - DynamicJsonDocument doc(JSON_ARRAY_SIZE(65536)); + JsonDocument doc; JsonArray array = doc.to(); SECTION("empty") { @@ -53,6 +55,7 @@ TEST_CASE("serialize MsgPack array") { const char* nil = 0; for (int i = 0; i < 65536; i++) array.add(nil); + REQUIRE(array.size() == 65536); check(array, std::string("\xDD\x00\x01\x00\x00", 5) + std::string(65536, '\xc0')); diff --git a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeObject.cpp b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeObject.cpp index 8817307..127a683 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeObject.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeObject.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -28,7 +28,7 @@ static void check(const JsonObject object, const char (&expected_data)[N]) { //} TEST_CASE("serialize MsgPack object") { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonObject object = doc.to(); SECTION("empty") { diff --git a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeVariant.cpp b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeVariant.cpp index b8a021f..65ce0bc 100644 --- a/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeVariant.cpp +++ b/third-party/ArduinoJson/extras/tests/MsgPackSerializer/serializeVariant.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include @@ -8,7 +8,7 @@ template static void checkVariant(T value, const char* expected_data, size_t expected_len) { - DynamicJsonDocument doc(4096); + JsonDocument doc; JsonVariant variant = doc.to(); variant.set(value); std::string expected(expected_data, expected_data + expected_len); diff --git a/third-party/ArduinoJson/extras/tests/Numbers/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/Numbers/CMakeLists.txt index 48cf8c0..c3d6dc0 100644 --- a/third-party/ArduinoJson/extras/tests/Numbers/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/Numbers/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(NumbersTests diff --git a/third-party/ArduinoJson/extras/tests/Numbers/convertNumber.cpp b/third-party/ArduinoJson/extras/tests/Numbers/convertNumber.cpp index ca0cc5e..7a2ae53 100644 --- a/third-party/ArduinoJson/extras/tests/Numbers/convertNumber.cpp +++ b/third-party/ArduinoJson/extras/tests/Numbers/convertNumber.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Numbers/parseDouble.cpp b/third-party/ArduinoJson/extras/tests/Numbers/parseDouble.cpp index 301aa0c..cd84ca4 100644 --- a/third-party/ArduinoJson/extras/tests/Numbers/parseDouble.cpp +++ b/third-party/ArduinoJson/extras/tests/Numbers/parseDouble.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_USE_DOUBLE 1 diff --git a/third-party/ArduinoJson/extras/tests/Numbers/parseFloat.cpp b/third-party/ArduinoJson/extras/tests/Numbers/parseFloat.cpp index 4e9c1d4..4a42f44 100644 --- a/third-party/ArduinoJson/extras/tests/Numbers/parseFloat.cpp +++ b/third-party/ArduinoJson/extras/tests/Numbers/parseFloat.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #define ARDUINOJSON_USE_DOUBLE 0 diff --git a/third-party/ArduinoJson/extras/tests/Numbers/parseInteger.cpp b/third-party/ArduinoJson/extras/tests/Numbers/parseInteger.cpp index 880da76..2180304 100644 --- a/third-party/ArduinoJson/extras/tests/Numbers/parseInteger.cpp +++ b/third-party/ArduinoJson/extras/tests/Numbers/parseInteger.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/Numbers/parseNumber.cpp b/third-party/ArduinoJson/extras/tests/Numbers/parseNumber.cpp index 48163c1..ba9412f 100644 --- a/third-party/ArduinoJson/extras/tests/Numbers/parseNumber.cpp +++ b/third-party/ArduinoJson/extras/tests/Numbers/parseNumber.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/ResourceManager/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/ResourceManager/CMakeLists.txt new file mode 100644 index 0000000..9214f5b --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/ResourceManager/CMakeLists.txt @@ -0,0 +1,25 @@ +# ArduinoJson - https://arduinojson.org +# Copyright © 2014-2024, Benoit BLANCHON +# MIT License + +add_executable(ResourceManagerTests + allocVariant.cpp + clear.cpp + saveString.cpp + shrinkToFit.cpp + size.cpp + StringBuilder.cpp + swap.cpp +) + +add_compile_definitions(ResourceManagerTests + ARDUINOJSON_SLOT_ID_SIZE=1 # require less RAM for overflow tests + ARDUINOJSON_POOL_CAPACITY=16 +) + +add_test(ResourceManager ResourceManagerTests) + +set_tests_properties(ResourceManager + PROPERTIES + LABELS "Catch" +) diff --git a/third-party/ArduinoJson/extras/tests/ResourceManager/StringBuilder.cpp b/third-party/ArduinoJson/extras/tests/ResourceManager/StringBuilder.cpp new file mode 100644 index 0000000..b649afe --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/ResourceManager/StringBuilder.cpp @@ -0,0 +1,143 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include + +#include "Allocators.hpp" + +using namespace ArduinoJson::detail; + +TEST_CASE("StringBuilder") { + KillswitchAllocator killswitch; + SpyingAllocator spyingAllocator(&killswitch); + ResourceManager resources(&spyingAllocator); + + SECTION("Empty string") { + StringBuilder str(&resources); + + str.startString(); + str.save(); + + REQUIRE(resources.size() == sizeofString("")); + REQUIRE(resources.overflowed() == false); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + Reallocate(sizeofStringBuffer(), sizeofString("")), + }); + } + + SECTION("Short string fits in first allocation") { + StringBuilder str(&resources); + + str.startString(); + str.append("hello"); + + REQUIRE(str.isValid() == true); + REQUIRE(str.str() == "hello"); + REQUIRE(resources.overflowed() == false); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + Allocate(sizeofStringBuffer()), + }); + } + + SECTION("Long string needs reallocation") { + StringBuilder str(&resources); + const char* lorem = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " + "eiusmod tempor incididunt ut labore et dolore magna aliqua."; + + str.startString(); + str.append(lorem); + + REQUIRE(str.isValid() == true); + REQUIRE(str.str() == lorem); + REQUIRE(resources.overflowed() == false); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer(1)), + Reallocate(sizeofStringBuffer(1), sizeofStringBuffer(2)), + Reallocate(sizeofStringBuffer(2), sizeofStringBuffer(3)), + }); + } + + SECTION("Realloc fails") { + StringBuilder str(&resources); + + str.startString(); + killswitch.on(); + str.append( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " + "eiusmod tempor incididunt ut labore et dolore magna aliqua."); + + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofStringBuffer()), + ReallocateFail(sizeofStringBuffer(), sizeofStringBuffer(2)), + Deallocate(sizeofStringBuffer()), + }); + REQUIRE(str.isValid() == false); + REQUIRE(resources.overflowed() == true); + } + + SECTION("Initial allocation fails") { + StringBuilder str(&resources); + + killswitch.on(); + str.startString(); + + REQUIRE(str.isValid() == false); + REQUIRE(resources.overflowed() == true); + REQUIRE(spyingAllocator.log() == AllocatorLog{ + AllocateFail(sizeofStringBuffer()), + }); + } +} + +static StringNode* addStringToPool(ResourceManager& resources, const char* s) { + StringBuilder str(&resources); + str.startString(); + str.append(s); + return str.save(); +} + +TEST_CASE("StringBuilder::save() deduplicates strings") { + ResourceManager resources; + + SECTION("Basic") { + auto s1 = addStringToPool(resources, "hello"); + auto s2 = addStringToPool(resources, "world"); + auto s3 = addStringToPool(resources, "hello"); + + REQUIRE(s1 == s3); + REQUIRE(s2 != s3); + REQUIRE(s1->references == 2); + REQUIRE(s2->references == 1); + REQUIRE(s3->references == 2); + REQUIRE(resources.size() == sizeofString("hello") + sizeofString("world")); + } + + SECTION("Requires terminator") { + auto s1 = addStringToPool(resources, "hello world"); + auto s2 = addStringToPool(resources, "hello"); + + REQUIRE(s2 != s1); + REQUIRE(s1->references == 1); + REQUIRE(s2->references == 1); + REQUIRE(resources.size() == + sizeofString("hello world") + sizeofString("hello")); + } + + SECTION("Don't overrun") { + auto s1 = addStringToPool(resources, "hello world"); + auto s2 = addStringToPool(resources, "wor"); + + REQUIRE(s2 != s1); + REQUIRE(s1->references == 1); + REQUIRE(s2->references == 1); + REQUIRE(resources.size() == + sizeofString("hello world") + sizeofString("wor")); + } +} diff --git a/third-party/ArduinoJson/extras/tests/ResourceManager/allocVariant.cpp b/third-party/ArduinoJson/extras/tests/ResourceManager/allocVariant.cpp new file mode 100644 index 0000000..d884a28 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/ResourceManager/allocVariant.cpp @@ -0,0 +1,94 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include +#include + +#include "Allocators.hpp" + +using namespace ArduinoJson::detail; + +TEST_CASE("ResourceManager::allocSlot()") { + SECTION("Returns different pointer") { + ResourceManager resources; + + VariantSlot* s1 = resources.allocSlot(); + REQUIRE(s1 != 0); + VariantSlot* s2 = resources.allocSlot(); + REQUIRE(s2 != 0); + + REQUIRE(s1 != s2); + } + + SECTION("Returns the same slot after calling freeSlot()") { + ResourceManager resources; + + auto s1 = resources.allocSlot(); + auto s2 = resources.allocSlot(); + resources.freeSlot(s1); + resources.freeSlot(s2); + auto s3 = resources.allocSlot(); + auto s4 = resources.allocSlot(); + auto s5 = resources.allocSlot(); + + REQUIRE(s2.id() != s1.id()); + REQUIRE(s3.id() == s2.id()); + REQUIRE(s4.id() == s1.id()); + REQUIRE(s5.id() != s1.id()); + REQUIRE(s5.id() != s2.id()); + } + + SECTION("Returns aligned pointers") { + ResourceManager resources; + + REQUIRE(isAligned(resources.allocSlot().operator VariantSlot*())); + REQUIRE(isAligned(resources.allocSlot().operator VariantSlot*())); + } + + SECTION("Returns null if pool list allocation fails") { + ResourceManager resources(FailingAllocator::instance()); + + auto variant = resources.allocSlot(); + REQUIRE(variant.id() == NULL_SLOT); + REQUIRE(static_cast(variant) == nullptr); + } + + SECTION("Returns null if pool allocation fails") { + ResourceManager resources(FailingAllocator::instance()); + + resources.allocSlot(); + + auto variant = resources.allocSlot(); + REQUIRE(variant.id() == NULL_SLOT); + REQUIRE(static_cast(variant) == nullptr); + } + + SECTION("Try overflow pool counter") { + ResourceManager resources; + + // this test assumes SlotId is 8-bit; otherwise it consumes a lot of memory + // tyhe GitHub Workflow gets killed + REQUIRE(NULL_SLOT == 255); + + // fill all the pools + for (SlotId i = 0; i < NULL_SLOT; i++) { + auto slot = resources.allocSlot(); + REQUIRE(slot.id() == i); // or != NULL_SLOT + REQUIRE(static_cast(slot) != nullptr); + } + + REQUIRE(resources.overflowed() == false); + + // now all allocations should fail + for (int i = 0; i < 10; i++) { + auto slot = resources.allocSlot(); + REQUIRE(slot.id() == NULL_SLOT); + REQUIRE(static_cast(slot) == nullptr); + } + + REQUIRE(resources.overflowed() == true); + } +} diff --git a/third-party/ArduinoJson/extras/tests/ResourceManager/clear.cpp b/third-party/ArduinoJson/extras/tests/ResourceManager/clear.cpp new file mode 100644 index 0000000..30afd90 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/ResourceManager/clear.cpp @@ -0,0 +1,30 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include +#include + +using namespace ArduinoJson::detail; + +TEST_CASE("ResourceManager::clear()") { + ResourceManager resources; + + SECTION("Discards allocated variants") { + resources.allocSlot(); + + resources.clear(); + REQUIRE(resources.size() == 0); + } + + SECTION("Discards allocated strings") { + resources.saveString(adaptString("123456789")); + REQUIRE(resources.size() == sizeofString(9)); + + resources.clear(); + + REQUIRE(resources.size() == 0); + } +} diff --git a/third-party/ArduinoJson/extras/tests/ResourceManager/saveString.cpp b/third-party/ArduinoJson/extras/tests/ResourceManager/saveString.cpp new file mode 100644 index 0000000..88c242f --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/ResourceManager/saveString.cpp @@ -0,0 +1,70 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include + +#include "Allocators.hpp" + +using namespace ArduinoJson::detail; + +static StringNode* saveString(ResourceManager& resources, const char* s) { + return resources.saveString(adaptString(s)); +} + +static StringNode* saveString(ResourceManager& resources, const char* s, + size_t n) { + return resources.saveString(adaptString(s, n)); +} + +TEST_CASE("ResourceManager::saveString()") { + ResourceManager resources; + + SECTION("Duplicates different strings") { + auto a = saveString(resources, "hello"); + auto b = saveString(resources, "world"); + REQUIRE(+a->data != +b->data); + REQUIRE(a->length == 5); + REQUIRE(b->length == 5); + REQUIRE(a->references == 1); + REQUIRE(b->references == 1); + REQUIRE(resources.size() == sizeofString("hello") + sizeofString("world")); + } + + SECTION("Deduplicates identical strings") { + auto a = saveString(resources, "hello"); + auto b = saveString(resources, "hello"); + REQUIRE(a == b); + REQUIRE(a->length == 5); + REQUIRE(a->references == 2); + REQUIRE(resources.size() == sizeofString("hello")); + } + + SECTION("Deduplicates identical strings that contain NUL") { + auto a = saveString(resources, "hello\0world", 11); + auto b = saveString(resources, "hello\0world", 11); + REQUIRE(a == b); + REQUIRE(a->length == 11); + REQUIRE(a->references == 2); + REQUIRE(resources.size() == sizeofString("hello world")); + } + + SECTION("Don't stop on first NUL") { + auto a = saveString(resources, "hello"); + auto b = saveString(resources, "hello\0world", 11); + REQUIRE(a != b); + REQUIRE(a->length == 5); + REQUIRE(b->length == 11); + REQUIRE(a->references == 1); + REQUIRE(b->references == 1); + REQUIRE(resources.size() == + sizeofString("hello") + sizeofString("hello world")); + } + + SECTION("Returns NULL when allocation fails") { + ResourceManager pool2(FailingAllocator::instance()); + REQUIRE(saveString(pool2, "a") == nullptr); + } +} diff --git a/third-party/ArduinoJson/extras/tests/ResourceManager/shrinkToFit.cpp b/third-party/ArduinoJson/extras/tests/ResourceManager/shrinkToFit.cpp new file mode 100644 index 0000000..7419770 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/ResourceManager/shrinkToFit.cpp @@ -0,0 +1,57 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include + +#include "Allocators.hpp" + +using namespace ArduinoJson::detail; + +TEST_CASE("ResourceManager::shrinkToFit()") { + SpyingAllocator spyingAllocator; + ResourceManager resources(&spyingAllocator); + + SECTION("empty") { + resources.shrinkToFit(); + + REQUIRE(spyingAllocator.log() == AllocatorLog{}); + } + + SECTION("only one pool") { + resources.allocSlot(); + + resources.shrinkToFit(); + + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofPool()), + Reallocate(sizeofPool(), sizeof(VariantSlot)), + }); + } + + SECTION("more pools than initial count") { + for (size_t i = 0; + i < ARDUINOJSON_POOL_CAPACITY * ARDUINOJSON_INITIAL_POOL_COUNT + 1; + i++) + resources.allocSlot(); + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Allocate(sizeofPool()) * ARDUINOJSON_INITIAL_POOL_COUNT, + Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)), + Allocate(sizeofPool()), + }); + + spyingAllocator.clearLog(); + resources.shrinkToFit(); + + REQUIRE(spyingAllocator.log() == + AllocatorLog{ + Reallocate(sizeofPool(), sizeof(VariantSlot)), + Reallocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2), + sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT + 1)), + }); + } +} diff --git a/third-party/ArduinoJson/extras/tests/ResourceManager/size.cpp b/third-party/ArduinoJson/extras/tests/ResourceManager/size.cpp new file mode 100644 index 0000000..6b09b17 --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/ResourceManager/size.cpp @@ -0,0 +1,31 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include + +#include "Allocators.hpp" + +using namespace ArduinoJson::detail; + +TEST_CASE("ResourceManager::size()") { + TimebombAllocator timebomb(0); + ResourceManager resources(&timebomb); + + SECTION("Initial size is 0") { + REQUIRE(0 == resources.size()); + } + + SECTION("Doesn't grow when allocation of second pool fails") { + timebomb.setCountdown(1); + for (size_t i = 0; i < ARDUINOJSON_POOL_CAPACITY; i++) + resources.allocSlot(); + size_t size = resources.size(); + + resources.allocSlot(); + + REQUIRE(size == resources.size()); + } +} diff --git a/third-party/ArduinoJson/extras/tests/ResourceManager/swap.cpp b/third-party/ArduinoJson/extras/tests/ResourceManager/swap.cpp new file mode 100644 index 0000000..4fdb45c --- /dev/null +++ b/third-party/ArduinoJson/extras/tests/ResourceManager/swap.cpp @@ -0,0 +1,96 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#include +#include +#include +#include + +#include "Allocators.hpp" + +using namespace ArduinoJson::detail; + +static void fullPreallocatedPools(ResourceManager& resources) { + for (int i = 0; + i < ARDUINOJSON_INITIAL_POOL_COUNT * ARDUINOJSON_POOL_CAPACITY; i++) + resources.allocSlot(); +} + +TEST_CASE("ResourceManager::swap()") { + SECTION("Both using preallocated pool list") { + SpyingAllocator spy; + ResourceManager a(&spy); + ResourceManager b(&spy); + + auto a1 = a.allocSlot(); + auto b1 = b.allocSlot(); + + swap(a, b); + + REQUIRE(a1->data() == b.getSlot(a1.id())->data()); + REQUIRE(b1->data() == a.getSlot(b1.id())->data()); + + REQUIRE(spy.log() == AllocatorLog{ + Allocate(sizeofPool()) * 2, + }); + } + + SECTION("Only left using preallocated pool list") { + SpyingAllocator spy; + ResourceManager a(&spy); + ResourceManager b(&spy); + fullPreallocatedPools(b); + + auto a1 = a.allocSlot(); + auto b1 = b.allocSlot(); + swap(a, b); + + REQUIRE(a1->data() == b.getSlot(a1.id())->data()); + REQUIRE(b1->data() == a.getSlot(b1.id())->data()); + + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofPool()) * (ARDUINOJSON_INITIAL_POOL_COUNT + 1), + Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)), + Allocate(sizeofPool()), + }); + } + + SECTION("Only right using preallocated pool list") { + SpyingAllocator spy; + ResourceManager a(&spy); + fullPreallocatedPools(a); + ResourceManager b(&spy); + + auto a1 = a.allocSlot(); + auto b1 = b.allocSlot(); + swap(a, b); + + REQUIRE(a1->data() == b.getSlot(a1.id())->data()); + REQUIRE(b1->data() == a.getSlot(b1.id())->data()); + + REQUIRE(spy.log() == + AllocatorLog{ + Allocate(sizeofPool()) * ARDUINOJSON_INITIAL_POOL_COUNT, + Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)), + Allocate(sizeofPool()) * 2, + }); + } + + SECTION("None is using preallocated pool list") { + SpyingAllocator spy; + ResourceManager a(&spy); + fullPreallocatedPools(a); + ResourceManager b(&spy); + fullPreallocatedPools(b); + + auto a1 = a.allocSlot(); + auto b1 = b.allocSlot(); + + swap(a, b); + + REQUIRE(a1->data() == b.getSlot(a1.id())->data()); + REQUIRE(b1->data() == a.getSlot(b1.id())->data()); + } +} diff --git a/third-party/ArduinoJson/extras/tests/TextFormatter/CMakeLists.txt b/third-party/ArduinoJson/extras/tests/TextFormatter/CMakeLists.txt index 2bc4a89..3b3b5bb 100644 --- a/third-party/ArduinoJson/extras/tests/TextFormatter/CMakeLists.txt +++ b/third-party/ArduinoJson/extras/tests/TextFormatter/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - https://arduinojson.org -# Copyright © 2014-2023, Benoit BLANCHON +# Copyright © 2014-2024, Benoit BLANCHON # MIT License add_executable(TextFormatterTests diff --git a/third-party/ArduinoJson/extras/tests/TextFormatter/writeFloat.cpp b/third-party/ArduinoJson/extras/tests/TextFormatter/writeFloat.cpp index 8e4bd7e..a787712 100644 --- a/third-party/ArduinoJson/extras/tests/TextFormatter/writeFloat.cpp +++ b/third-party/ArduinoJson/extras/tests/TextFormatter/writeFloat.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/TextFormatter/writeInteger.cpp b/third-party/ArduinoJson/extras/tests/TextFormatter/writeInteger.cpp index 20cbd29..1906750 100644 --- a/third-party/ArduinoJson/extras/tests/TextFormatter/writeInteger.cpp +++ b/third-party/ArduinoJson/extras/tests/TextFormatter/writeInteger.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/extras/tests/TextFormatter/writeString.cpp b/third-party/ArduinoJson/extras/tests/TextFormatter/writeString.cpp index 2be9191..2d3d096 100644 --- a/third-party/ArduinoJson/extras/tests/TextFormatter/writeString.cpp +++ b/third-party/ArduinoJson/extras/tests/TextFormatter/writeString.cpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #include diff --git a/third-party/ArduinoJson/idf_component.yml b/third-party/ArduinoJson/idf_component.yml index 51be472..5baab07 100644 --- a/third-party/ArduinoJson/idf_component.yml +++ b/third-party/ArduinoJson/idf_component.yml @@ -1,9 +1,9 @@ -version: "6.21.3" +version: "7.0.3" description: >- A simple and efficient JSON library for embedded C++. - ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, and more. - It is the most popular Arduino library on GitHub ❤❤❤❤❤. - Check out arduinojson.org for a comprehensive documentation. + ⭐ 6463 stars on GitHub! + Supports serialization, deserialization, MessagePack, streams, filtering, and more. + Fully tested and documented. url: https://arduinojson.org/ files: exclude: diff --git a/third-party/ArduinoJson/keywords.txt b/third-party/ArduinoJson/keywords.txt index 3dff06b..05d113d 100644 --- a/third-party/ArduinoJson/keywords.txt +++ b/third-party/ArduinoJson/keywords.txt @@ -1,8 +1,3 @@ -# Macros -JSON_ARRAY_SIZE KEYWORD2 -JSON_OBJECT_SIZE KEYWORD2 -JSON_STRING_SIZE KEYWORD2 - # Free functions deserializeJson KEYWORD2 deserializeMsgPack KEYWORD2 @@ -17,15 +12,13 @@ measureMsgPack KEYWORD2 # Methods add KEYWORD2 as KEYWORD2 -createNestedArray KEYWORD2 -createNestedObject KEYWORD2 get KEYWORD2 set KEYWORD2 to KEYWORD2 # Type names DeserializationError KEYWORD1 DATA_TYPE -DynamicJsonDocument KEYWORD1 DATA_TYPE +JsonDocument KEYWORD1 DATA_TYPE JsonArray KEYWORD1 DATA_TYPE JsonArrayConst KEYWORD1 DATA_TYPE JsonDocument KEYWORD1 DATA_TYPE @@ -37,4 +30,3 @@ JsonString KEYWORD1 DATA_TYPE JsonUInt KEYWORD1 DATA_TYPE JsonVariant KEYWORD1 DATA_TYPE JsonVariantConst KEYWORD1 DATA_TYPE -StaticJsonDocument KEYWORD1 DATA_TYPE diff --git a/third-party/ArduinoJson/library.json b/third-party/ArduinoJson/library.json index 9b5d7df..c66ecfc 100644 --- a/third-party/ArduinoJson/library.json +++ b/third-party/ArduinoJson/library.json @@ -1,22 +1,20 @@ { "name": "ArduinoJson", "keywords": "json, rest, http, web", - "description": "A simple and efficient JSON library for embedded C++. ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation.", + "description": "A simple and efficient JSON library for embedded C++. ⭐ 6463 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", "repository": { "type": "git", "url": "https://github.com/bblanchon/ArduinoJson.git" }, - "version": "6.21.3", + "version": "7.0.3", "authors": { "name": "Benoit Blanchon", "url": "https://blog.benoitblanchon.fr" }, - "exclude": [ - ".devcontainer", - ".github", - "extras" - ], + "export": { + "include": ["src", "examples", "LICENSE.txt", "ArduinoJson.h"] + }, "frameworks": "*", "platforms": "*", "build": { diff --git a/third-party/ArduinoJson/library.properties b/third-party/ArduinoJson/library.properties index 6a285cf..6c28398 100644 --- a/third-party/ArduinoJson/library.properties +++ b/third-party/ArduinoJson/library.properties @@ -1,9 +1,9 @@ name=ArduinoJson -version=6.21.3 +version=7.0.3 author=Benoit Blanchon maintainer=Benoit Blanchon sentence=A simple and efficient JSON library for embedded C++. -paragraph=ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation. +paragraph=⭐ 6463 stars on GitHub! Supports serialization, deserialization, MessagePack, streams, filtering, and more. Fully tested and documented. category=Data Processing url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties architectures=* diff --git a/third-party/ArduinoJson/src/ArduinoJson.h b/third-party/ArduinoJson/src/ArduinoJson.h index c9ac0ca..fec64c3 100644 --- a/third-party/ArduinoJson/src/ArduinoJson.h +++ b/third-party/ArduinoJson/src/ArduinoJson.h @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson.hpp b/third-party/ArduinoJson/src/ArduinoJson.hpp index 2d1b0be..c210ed2 100644 --- a/third-party/ArduinoJson/src/ArduinoJson.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -30,18 +30,19 @@ #include "ArduinoJson/Object/JsonObject.hpp" #include "ArduinoJson/Variant/JsonVariantConst.hpp" -#include "ArduinoJson/Document/DynamicJsonDocument.hpp" -#include "ArduinoJson/Document/StaticJsonDocument.hpp" +#include "ArduinoJson/Document/JsonDocument.hpp" +#include "ArduinoJson/Array/ArrayImpl.hpp" #include "ArduinoJson/Array/ElementProxy.hpp" -#include "ArduinoJson/Array/JsonArrayImpl.hpp" #include "ArduinoJson/Array/Utilities.hpp" #include "ArduinoJson/Collection/CollectionImpl.hpp" -#include "ArduinoJson/Object/JsonObjectImpl.hpp" +#include "ArduinoJson/Memory/VariantPoolImpl.hpp" #include "ArduinoJson/Object/MemberProxy.hpp" +#include "ArduinoJson/Object/ObjectImpl.hpp" #include "ArduinoJson/Variant/ConverterImpl.hpp" +#include "ArduinoJson/Variant/JsonVariantCopier.hpp" #include "ArduinoJson/Variant/VariantCompare.hpp" -#include "ArduinoJson/Variant/VariantImpl.hpp" +#include "ArduinoJson/Variant/VariantRefBaseImpl.hpp" #include "ArduinoJson/Json/JsonDeserializer.hpp" #include "ArduinoJson/Json/JsonSerializer.hpp" diff --git a/third-party/ArduinoJson/src/ArduinoJson/Array/ArrayData.hpp b/third-party/ArduinoJson/src/ArduinoJson/Array/ArrayData.hpp new file mode 100644 index 0000000..93a65d5 --- /dev/null +++ b/third-party/ArduinoJson/src/ArduinoJson/Array/ArrayData.hpp @@ -0,0 +1,57 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#pragma once + +#include + +ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE + +class ArrayData : public CollectionData { + public: + VariantData* addElement(ResourceManager* resources) { + return addSlot(resources).data(); + } + + static VariantData* addElement(ArrayData* array, ResourceManager* resources) { + if (!array) + return nullptr; + return array->addElement(resources); + } + + VariantData* getOrAddElement(size_t index, ResourceManager* resources); + + VariantData* getElement(size_t index, const ResourceManager* resources) const; + + static VariantData* getElement(const ArrayData* array, size_t index, + const ResourceManager* resources) { + if (!array) + return nullptr; + return array->getElement(index, resources); + } + + void removeElement(size_t index, ResourceManager* resources); + + static void removeElement(ArrayData* array, size_t index, + ResourceManager* resources) { + if (!array) + return; + array->removeElement(index, resources); + } + + bool copyFrom(const ArrayData& src, ResourceManager* resources); + + static bool copy(ArrayData* dst, const ArrayData* src, + ResourceManager* resources) { + if (!dst || !src) + return false; + + return dst->copyFrom(*src, resources); + } + + private: + iterator at(size_t index, const ResourceManager* resources) const; +}; + +ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/third-party/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp b/third-party/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp new file mode 100644 index 0000000..595e847 --- /dev/null +++ b/third-party/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp @@ -0,0 +1,50 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2024, Benoit BLANCHON +// MIT License + +#pragma once + +#include +#include + +ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE + +inline ArrayData::iterator ArrayData::at( + size_t index, const ResourceManager* resources) const { + auto it = createIterator(resources); + while (!it.done() && index) { + it.next(resources); + --index; + } + return it; +} + +inline VariantData* ArrayData::getOrAddElement(size_t index, + ResourceManager* resources) { + auto it = createIterator(resources); + while (!it.done() && index > 0) { + it.next(resources); + index--; + } + if (it.done()) + index++; + VariantData* element = it.data(); + while (index > 0) { + element = addElement(resources); + if (!element) + return nullptr; + index--; + } + return element; +} + +inline VariantData* ArrayData::getElement( + size_t index, const ResourceManager* resources) const { + return at(index, resources).data(); +} + +inline void ArrayData::removeElement(size_t index, ResourceManager* resources) { + remove(at(index, resources), resources); +} + +ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/third-party/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp b/third-party/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp index d6e9aa5..f36b68e 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -9,7 +9,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE // A proxy class to get or set an element of an array. -// https://arduinojson.org/v6/api/jsonarray/subscript/ +// https://arduinojson.org/v7/api/jsonarray/subscript/ template class ElementProxy : public VariantRefBase>, public VariantOperators> { @@ -22,35 +22,40 @@ class ElementProxy : public VariantRefBase>, ElementProxy(const ElementProxy& src) : upstream_(src.upstream_), index_(src.index_) {} - FORCE_INLINE ElementProxy& operator=(const ElementProxy& src) { + ElementProxy& operator=(const ElementProxy& src) { this->set(src); return *this; } template - FORCE_INLINE ElementProxy& operator=(const T& src) { + ElementProxy& operator=(const T& src) { this->set(src); return *this; } template - FORCE_INLINE ElementProxy& operator=(T* src) { + ElementProxy& operator=(T* src) { this->set(src); return *this; } private: - FORCE_INLINE MemoryPool* getPool() const { - return VariantAttorney::getPool(upstream_); + ResourceManager* getResourceManager() const { + return VariantAttorney::getResourceManager(upstream_); } FORCE_INLINE VariantData* getData() const { - return variantGetElement(VariantAttorney::getData(upstream_), index_); + return VariantData::getElement( + VariantAttorney::getData(upstream_), index_, + VariantAttorney::getResourceManager(upstream_)); } - FORCE_INLINE VariantData* getOrCreateData() const { - return variantGetOrAddElement(VariantAttorney::getOrCreateData(upstream_), - index_, VariantAttorney::getPool(upstream_)); + VariantData* getOrCreateData() const { + auto data = VariantAttorney::getOrCreateData(upstream_); + if (!data) + return nullptr; + return data->getOrAddElement( + index_, VariantAttorney::getResourceManager(upstream_)); } TUpstream upstream_; diff --git a/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp b/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp index d208e41..2923363 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -12,7 +12,7 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE class JsonObject; // A reference to an array in a JsonDocument -// https://arduinojson.org/v6/api/jsonarray/ +// https://arduinojson.org/v7/api/jsonarray/ class JsonArray : public detail::VariantOperators { friend class detail::VariantAttorney; @@ -20,192 +20,177 @@ class JsonArray : public detail::VariantOperators { typedef JsonArrayIterator iterator; // Constructs an unbound reference. - FORCE_INLINE JsonArray() : data_(0), pool_(0) {} + JsonArray() : data_(0), resources_(0) {} // INTERNAL USE ONLY - FORCE_INLINE JsonArray(detail::MemoryPool* pool, detail::CollectionData* data) - : data_(data), pool_(pool) {} + JsonArray(detail::ArrayData* data, detail::ResourceManager* resources) + : data_(data), resources_(resources) {} // Returns a JsonVariant pointing to the array. - // https://arduinojson.org/v6/api/jsonvariant/ + // https://arduinojson.org/v7/api/jsonvariant/ operator JsonVariant() { void* data = data_; // prevent warning cast-align - return JsonVariant(pool_, reinterpret_cast(data)); + return JsonVariant(reinterpret_cast(data), + resources_); } // Returns a read-only reference to the array. - // https://arduinojson.org/v6/api/jsonarrayconst/ + // https://arduinojson.org/v7/api/jsonarrayconst/ operator JsonArrayConst() const { - return JsonArrayConst(data_); + return JsonArrayConst(data_, resources_); + } + + // Appends a new (empty) element to the array. + // Returns a reference to the new element. + // https://arduinojson.org/v7/api/jsonarray/add/ + template + typename detail::enable_if::value, T>::type + add() const { + return add().to(); } // Appends a new (null) element to the array. // Returns a reference to the new element. - // https://arduinojson.org/v6/api/jsonarray/add/ - JsonVariant add() const { - if (!data_) - return JsonVariant(); - return JsonVariant(pool_, data_->addElement(pool_)); + // https://arduinojson.org/v7/api/jsonarray/add/ + template + typename detail::enable_if::value, T>::type + add() const { + return JsonVariant(detail::ArrayData::addElement(data_, resources_), + resources_); } // Appends a value to the array. - // https://arduinojson.org/v6/api/jsonarray/add/ + // https://arduinojson.org/v7/api/jsonarray/add/ template - FORCE_INLINE bool add(const T& value) const { - return add().set(value); + bool add(const T& value) const { + return add().set(value); } // Appends a value to the array. - // https://arduinojson.org/v6/api/jsonarray/add/ + // https://arduinojson.org/v7/api/jsonarray/add/ template - FORCE_INLINE bool add(T* value) const { - return add().set(value); + bool add(T* value) const { + return add().set(value); } // Returns an iterator to the first element of the array. - // https://arduinojson.org/v6/api/jsonarray/begin/ - FORCE_INLINE iterator begin() const { + // https://arduinojson.org/v7/api/jsonarray/begin/ + iterator begin() const { if (!data_) return iterator(); - return iterator(pool_, data_->head()); + return iterator(data_->createIterator(resources_), resources_); } // Returns an iterator following the last element of the array. - // https://arduinojson.org/v6/api/jsonarray/end/ - FORCE_INLINE iterator end() const { + // https://arduinojson.org/v7/api/jsonarray/end/ + iterator end() const { return iterator(); } // Copies an array. - // https://arduinojson.org/v6/api/jsonarray/set/ - FORCE_INLINE bool set(JsonArrayConst src) const { - if (!data_ || !src.data_) + // https://arduinojson.org/v7/api/jsonarray/set/ + bool set(JsonArrayConst src) const { + if (!data_) return false; - return data_->copyFrom(*src.data_, pool_); - } - // Compares the content of two arrays. - FORCE_INLINE bool operator==(JsonArray rhs) const { - return JsonArrayConst(data_) == JsonArrayConst(rhs.data_); + clear(); + for (auto element : src) { + if (!add(element)) + return false; + } + + return true; } // Removes the element at the specified iterator. - // ⚠️ Doesn't release the memory associated with the removed element. - // https://arduinojson.org/v6/api/jsonarray/remove/ - FORCE_INLINE void remove(iterator it) const { - if (!data_) - return; - data_->removeSlot(it.slot_); + // https://arduinojson.org/v7/api/jsonarray/remove/ + void remove(iterator it) const { + detail::ArrayData::remove(data_, it.iterator_, resources_); } // Removes the element at the specified index. - // ⚠️ Doesn't release the memory associated with the removed element. - // https://arduinojson.org/v6/api/jsonarray/remove/ - FORCE_INLINE void remove(size_t index) const { - if (!data_) - return; - data_->removeElement(index); + // https://arduinojson.org/v7/api/jsonarray/remove/ + void remove(size_t index) const { + detail::ArrayData::removeElement(data_, index, resources_); } // Removes all the elements of the array. - // ⚠️ Doesn't release the memory associated with the removed elements. - // https://arduinojson.org/v6/api/jsonarray/clear/ + // https://arduinojson.org/v7/api/jsonarray/clear/ void clear() const { - if (!data_) - return; - data_->clear(); + detail::ArrayData::clear(data_, resources_); } // Gets or sets the element at the specified index. - // https://arduinojson.org/v6/api/jsonarray/subscript/ - FORCE_INLINE detail::ElementProxy operator[](size_t index) const { + // https://arduinojson.org/v7/api/jsonarray/subscript/ + detail::ElementProxy operator[](size_t index) const { return {*this, index}; } - // Creates an object and appends it to the array. - // https://arduinojson.org/v6/api/jsonarray/createnestedobject/ - FORCE_INLINE JsonObject createNestedObject() const; - - // Creates an array and appends it to the array. - // https://arduinojson.org/v6/api/jsonarray/createnestedarray/ - FORCE_INLINE JsonArray createNestedArray() const { - return add().to(); - } - operator JsonVariantConst() const { - return JsonVariantConst(collectionToVariant(data_)); + return JsonVariantConst(collectionToVariant(data_), resources_); } // Returns true if the reference is unbound. - // https://arduinojson.org/v6/api/jsonarray/isnull/ - FORCE_INLINE bool isNull() const { + // https://arduinojson.org/v7/api/jsonarray/isnull/ + bool isNull() const { return data_ == 0; } // Returns true if the reference is bound. - // https://arduinojson.org/v6/api/jsonarray/isnull/ - FORCE_INLINE operator bool() const { + // https://arduinojson.org/v7/api/jsonarray/isnull/ + operator bool() const { return data_ != 0; } - // Returns the number of bytes occupied by the array. - // https://arduinojson.org/v6/api/jsonarray/memoryusage/ - FORCE_INLINE size_t memoryUsage() const { - return data_ ? data_->memoryUsage() : 0; - } - // Returns the depth (nesting level) of the array. - // https://arduinojson.org/v6/api/jsonarray/nesting/ - FORCE_INLINE size_t nesting() const { - return variantNesting(collectionToVariant(data_)); + // https://arduinojson.org/v7/api/jsonarray/nesting/ + size_t nesting() const { + return detail::VariantData::nesting(collectionToVariant(data_), resources_); } // Returns the number of elements in the array. - // https://arduinojson.org/v6/api/jsonarray/size/ - FORCE_INLINE size_t size() const { - return data_ ? data_->size() : 0; + // https://arduinojson.org/v7/api/jsonarray/size/ + size_t size() const { + return data_ ? data_->size(resources_) : 0; } - private: - detail::MemoryPool* getPool() const { - return pool_; + // DEPRECATED: use add() instead + ARDUINOJSON_DEPRECATED("use add() instead") + JsonVariant add() const { + return add(); } - detail::VariantData* getData() const { - return collectionToVariant(data_); + // DEPRECATED: use add() instead + ARDUINOJSON_DEPRECATED("use add() instead") + JsonArray createNestedArray() const { + return add(); } - detail::VariantData* getOrCreateData() const { - return collectionToVariant(data_); - } + // DEPRECATED: use add() instead + ARDUINOJSON_DEPRECATED("use add() instead") + JsonObject createNestedObject() const; - detail::CollectionData* data_; - detail::MemoryPool* pool_; -}; - -template <> -struct Converter : private detail::VariantAttorney { - static void toJson(JsonVariantConst src, JsonVariant dst) { - variantCopyFrom(getData(dst), getData(src), getPool(dst)); + // DEPRECATED: always returns zero + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; } - static JsonArray fromJson(JsonVariant src) { - auto data = getData(src); - auto pool = getPool(src); - return JsonArray(pool, data != 0 ? data->asArray() : 0); + private: + detail::ResourceManager* getResourceManager() const { + return resources_; } - static detail::InvalidConversion fromJson( - JsonVariantConst); - - static bool checkJson(JsonVariantConst) { - return false; + detail::VariantData* getData() const { + return collectionToVariant(data_); } - static bool checkJson(JsonVariant src) { - auto data = getData(src); - return data && data->isArray(); + detail::VariantData* getOrCreateData() const { + return collectionToVariant(data_); } + + detail::ArrayData* data_; + detail::ResourceManager* resources_; }; ARDUINOJSON_END_PUBLIC_NAMESPACE diff --git a/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp b/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp index 6a6463c..6c0d7db 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -13,7 +13,7 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE class JsonObject; // A read-only reference to an array in a JsonDocument -// https://arduinojson.org/v6/api/jsonarrayconst/ +// https://arduinojson.org/v7/api/jsonarrayconst/ class JsonArrayConst : public detail::VariantOperators { friend class JsonArray; friend class detail::VariantAttorney; @@ -22,89 +22,66 @@ class JsonArrayConst : public detail::VariantOperators { typedef JsonArrayConstIterator iterator; // Returns an iterator to the first element of the array. - // https://arduinojson.org/v6/api/jsonarrayconst/begin/ - FORCE_INLINE iterator begin() const { + // https://arduinojson.org/v7/api/jsonarrayconst/begin/ + iterator begin() const { if (!data_) return iterator(); - return iterator(data_->head()); + return iterator(data_->createIterator(resources_), resources_); } // Returns an iterator to the element following the last element of the array. - // https://arduinojson.org/v6/api/jsonarrayconst/end/ - FORCE_INLINE iterator end() const { + // https://arduinojson.org/v7/api/jsonarrayconst/end/ + iterator end() const { return iterator(); } // Creates an unbound reference. - FORCE_INLINE JsonArrayConst() : data_(0) {} + JsonArrayConst() : data_(0) {} // INTERNAL USE ONLY - FORCE_INLINE JsonArrayConst(const detail::CollectionData* data) - : data_(data) {} - - // Compares the content of two arrays. - // Returns true if the two arrays are equal. - FORCE_INLINE bool operator==(JsonArrayConst rhs) const { - if (data_ == rhs.data_) - return true; - if (!data_ || !rhs.data_) - return false; - - iterator it1 = begin(); - iterator it2 = rhs.begin(); - - for (;;) { - bool end1 = it1 == end(); - bool end2 = it2 == rhs.end(); - if (end1 && end2) - return true; - if (end1 || end2) - return false; - if (*it1 != *it2) - return false; - ++it1; - ++it2; - } - } + JsonArrayConst(const detail::ArrayData* data, + const detail::ResourceManager* resources) + : data_(data), resources_(resources) {} // Returns the element at the specified index. - // https://arduinojson.org/v6/api/jsonarrayconst/subscript/ - FORCE_INLINE JsonVariantConst operator[](size_t index) const { - return JsonVariantConst(data_ ? data_->getElement(index) : 0); + // https://arduinojson.org/v7/api/jsonarrayconst/subscript/ + JsonVariantConst operator[](size_t index) const { + return JsonVariantConst( + detail::ArrayData::getElement(data_, index, resources_), resources_); } operator JsonVariantConst() const { - return JsonVariantConst(collectionToVariant(data_)); + return JsonVariantConst(getData(), resources_); } // Returns true if the reference is unbound. - // https://arduinojson.org/v6/api/jsonarrayconst/isnull/ - FORCE_INLINE bool isNull() const { + // https://arduinojson.org/v7/api/jsonarrayconst/isnull/ + bool isNull() const { return data_ == 0; } // Returns true if the reference is bound. - // https://arduinojson.org/v6/api/jsonarrayconst/isnull/ - FORCE_INLINE operator bool() const { + // https://arduinojson.org/v7/api/jsonarrayconst/isnull/ + operator bool() const { return data_ != 0; } - // Returns the number of bytes occupied by the array. - // https://arduinojson.org/v6/api/jsonarrayconst/memoryusage/ - FORCE_INLINE size_t memoryUsage() const { - return data_ ? data_->memoryUsage() : 0; - } - // Returns the depth (nesting level) of the array. - // https://arduinojson.org/v6/api/jsonarrayconst/nesting/ - FORCE_INLINE size_t nesting() const { - return variantNesting(collectionToVariant(data_)); + // https://arduinojson.org/v7/api/jsonarrayconst/nesting/ + size_t nesting() const { + return detail::VariantData::nesting(getData(), resources_); } // Returns the number of elements in the array. - // https://arduinojson.org/v6/api/jsonarrayconst/size/ - FORCE_INLINE size_t size() const { - return data_ ? data_->size() : 0; + // https://arduinojson.org/v7/api/jsonarrayconst/size/ + size_t size() const { + return data_ ? data_->size(resources_) : 0; + } + + // DEPRECATED: always returns zero + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; } private: @@ -112,24 +89,31 @@ class JsonArrayConst : public detail::VariantOperators { return collectionToVariant(data_); } - const detail::CollectionData* data_; + const detail::ArrayData* data_; + const detail::ResourceManager* resources_; }; -template <> -struct Converter : private detail::VariantAttorney { - static void toJson(JsonVariantConst src, JsonVariant dst) { - variantCopyFrom(getData(dst), getData(src), getPool(dst)); - } +// Compares the content of two arrays. +// Returns true if the two arrays are equal. +inline bool operator==(JsonArrayConst lhs, JsonArrayConst rhs) { + if (!lhs && !rhs) + return true; + if (!lhs || !rhs) + return false; - static JsonArrayConst fromJson(JsonVariantConst src) { - auto data = getData(src); - return data ? data->asArray() : 0; - } + auto a = lhs.begin(); + auto b = rhs.begin(); - static bool checkJson(JsonVariantConst src) { - auto data = getData(src); - return data && data->isArray(); + for (;;) { + if (a == b) // same pointer or both null + return true; + if (a == lhs.end() || b == rhs.end()) + return false; + if (*a != *b) + return false; + ++a; + ++b; } -}; +} ARDUINOJSON_END_PUBLIC_NAMESPACE diff --git a/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayIterator.hpp b/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayIterator.hpp index d9048b2..70bb28f 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayIterator.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayIterator.hpp @@ -1,121 +1,96 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once #include -#include ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE -class VariantPtr { +template +class Ptr { public: - VariantPtr(detail::MemoryPool* pool, detail::VariantData* data) - : variant_(pool, data) {} + Ptr(T value) : value_(value) {} - JsonVariant* operator->() { - return &variant_; + T* operator->() { + return &value_; } - JsonVariant& operator*() { - return variant_; + T& operator*() { + return value_; } private: - JsonVariant variant_; + T value_; }; class JsonArrayIterator { friend class JsonArray; public: - JsonArrayIterator() : slot_(0) {} - explicit JsonArrayIterator(detail::MemoryPool* pool, - detail::VariantSlot* slot) - : pool_(pool), slot_(slot) {} + JsonArrayIterator() {} + explicit JsonArrayIterator(detail::ArrayData::iterator iterator, + detail::ResourceManager* resources) + : iterator_(iterator), resources_(resources) {} - JsonVariant operator*() const { - return JsonVariant(pool_, slot_->data()); + JsonVariant operator*() { + return JsonVariant(iterator_.data(), resources_); } - VariantPtr operator->() { - return VariantPtr(pool_, slot_->data()); + Ptr operator->() { + return operator*(); } bool operator==(const JsonArrayIterator& other) const { - return slot_ == other.slot_; + return iterator_ == other.iterator_; } bool operator!=(const JsonArrayIterator& other) const { - return slot_ != other.slot_; + return iterator_ != other.iterator_; } JsonArrayIterator& operator++() { - slot_ = slot_->next(); - return *this; - } - - JsonArrayIterator& operator+=(size_t distance) { - slot_ = slot_->next(distance); + iterator_.next(resources_); return *this; } private: - detail::MemoryPool* pool_; - detail::VariantSlot* slot_; -}; - -class VariantConstPtr { - public: - VariantConstPtr(const detail::VariantData* data) : variant_(data) {} - - JsonVariantConst* operator->() { - return &variant_; - } - - JsonVariantConst& operator*() { - return variant_; - } - - private: - JsonVariantConst variant_; + detail::ArrayData::iterator iterator_; + detail::ResourceManager* resources_; }; class JsonArrayConstIterator { friend class JsonArray; public: - JsonArrayConstIterator() : slot_(0) {} - explicit JsonArrayConstIterator(const detail::VariantSlot* slot) - : slot_(slot) {} + JsonArrayConstIterator() {} + explicit JsonArrayConstIterator(detail::ArrayData::iterator iterator, + const detail::ResourceManager* resources) + : iterator_(iterator), resources_(resources) {} JsonVariantConst operator*() const { - return JsonVariantConst(slot_->data()); + return JsonVariantConst(iterator_.data(), resources_); } - VariantConstPtr operator->() { - return VariantConstPtr(slot_->data()); + Ptr operator->() { + return operator*(); } bool operator==(const JsonArrayConstIterator& other) const { - return slot_ == other.slot_; + return iterator_ == other.iterator_; } bool operator!=(const JsonArrayConstIterator& other) const { - return slot_ != other.slot_; + return iterator_ != other.iterator_; } JsonArrayConstIterator& operator++() { - slot_ = slot_->next(); - return *this; - } - - JsonArrayConstIterator& operator+=(size_t distance) { - slot_ = slot_->next(distance); + iterator_.next(resources_); return *this; } private: - const detail::VariantSlot* slot_; + detail::ArrayData::iterator iterator_; + const detail::ResourceManager* resources_; }; ARDUINOJSON_END_PUBLIC_NAMESPACE diff --git a/third-party/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp b/third-party/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp index 398e11d..ff589ce 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -18,7 +18,7 @@ copyArray(const T& src, JsonVariant dst) { } // Copies values from an array to a JsonArray or a JsonVariant. -// https://arduinojson.org/v6/api/misc/copyarray/ +// https://arduinojson.org/v7/api/misc/copyarray/ template inline typename detail::enable_if< !detail::is_base_of::value, bool>::type @@ -27,14 +27,14 @@ copyArray(T (&src)[N], const TDestination& dst) { } // Copies values from an array to a JsonArray or a JsonVariant. -// https://arduinojson.org/v6/api/misc/copyarray/ +// https://arduinojson.org/v7/api/misc/copyarray/ template inline typename detail::enable_if< !detail::is_base_of::value, bool>::type copyArray(const T* src, size_t len, const TDestination& dst) { bool ok = true; for (size_t i = 0; i < len; i++) { - ok &= copyArray(src[i], dst.add()); + ok &= copyArray(src[i], dst.template add()); } return ok; } @@ -47,14 +47,14 @@ inline bool copyArray(const char* src, size_t, const TDestination& dst) { } // Copies values from an array to a JsonDocument. -// https://arduinojson.org/v6/api/misc/copyarray/ +// https://arduinojson.org/v7/api/misc/copyarray/ template inline bool copyArray(const T& src, JsonDocument& dst) { return copyArray(src, dst.to()); } // Copies an array to a JsonDocument. -// https://arduinojson.org/v6/api/misc/copyarray/ +// https://arduinojson.org/v7/api/misc/copyarray/ template inline bool copyArray(const T* src, size_t len, JsonDocument& dst) { return copyArray(src, len, dst.to()); @@ -70,14 +70,14 @@ copyArray(JsonVariantConst src, T& dst) { } // Copies values from a JsonArray or JsonVariant to an array. -// https://arduinojson.org/v6/api/misc/copyarray/ +// https://arduinojson.org/v7/api/misc/copyarray/ template inline size_t copyArray(JsonArrayConst src, T (&dst)[N]) { return copyArray(src, dst, N); } // Copies values from a JsonArray or JsonVariant to an array. -// https://arduinojson.org/v6/api/misc/copyarray/ +// https://arduinojson.org/v7/api/misc/copyarray/ template inline size_t copyArray(JsonArrayConst src, T* dst, size_t len) { size_t i = 0; @@ -101,7 +101,7 @@ inline size_t copyArray(JsonVariantConst src, char (&dst)[N]) { } // Copies values from a JsonDocument to an array. -// https://arduinojson.org/v6/api/misc/copyarray/ +// https://arduinojson.org/v7/api/misc/copyarray/ template inline typename detail::enable_if< detail::is_array::value && diff --git a/third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp b/third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp index 090c98b..07fe7e0 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -11,74 +11,112 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE -class MemoryPool; class VariantData; class VariantSlot; -class CollectionData { - VariantSlot* head_; - VariantSlot* tail_; +class CollectionIterator { + friend class CollectionData; public: - // Must be a POD! - // - no constructor - // - no destructor - // - no virtual - // - no inheritance + CollectionIterator() : slot_(nullptr), currentId_(NULL_SLOT) {} + + void next(const ResourceManager* resources); + + bool done() const { + return slot_ == nullptr; + } + + bool operator==(const CollectionIterator& other) const { + return slot_ == other.slot_; + } + + bool operator!=(const CollectionIterator& other) const { + return slot_ != other.slot_; + } + + VariantData* operator->() { + ARDUINOJSON_ASSERT(slot_ != nullptr); + return data(); + } + + VariantData& operator*() { + ARDUINOJSON_ASSERT(slot_ != nullptr); + return *data(); + } + + const VariantData& operator*() const { + ARDUINOJSON_ASSERT(slot_ != nullptr); + return *data(); + } - // Array only + const char* key() const; + bool ownsKey() const; - VariantData* addElement(MemoryPool* pool); + void setKey(StringNode*); + void setKey(const char*); - VariantData* getElement(size_t index) const; + VariantData* data() { + return reinterpret_cast(slot_); + } - VariantData* getOrAddElement(size_t index, MemoryPool* pool); + const VariantData* data() const { + return reinterpret_cast(slot_); + } - void removeElement(size_t index); + private: + CollectionIterator(VariantSlot* slot, SlotId slotId); - // Object only + VariantSlot* slot_; + SlotId currentId_, nextId_; +}; - template - VariantData* addMember(TAdaptedString key, MemoryPool* pool); +class CollectionData { + SlotId head_ = NULL_SLOT; + SlotId tail_ = NULL_SLOT; - template - VariantData* getMember(TAdaptedString key) const; + public: + // Placement new + static void* operator new(size_t, void* p) noexcept { + return p; + } + + static void operator delete(void*, void*) noexcept {} - template - VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool); + using iterator = CollectionIterator; - template - void removeMember(TAdaptedString key) { - removeSlot(getSlot(key)); + iterator createIterator(const ResourceManager* resources) const { + return iterator(resources->getSlot(head_), head_); } - template - bool containsKey(const TAdaptedString& key) const; + size_t size(const ResourceManager*) const; + size_t nesting(const ResourceManager*) const; - // Generic + void clear(ResourceManager* resources); - void clear(); - size_t memoryUsage() const; - size_t size() const; + static void clear(CollectionData* collection, ResourceManager* resources) { + if (!collection) + return; + collection->clear(resources); + } - VariantSlot* addSlot(MemoryPool*); - void removeSlot(VariantSlot* slot); + void remove(iterator it, ResourceManager* resources); - bool copyFrom(const CollectionData& src, MemoryPool* pool); + static void remove(CollectionData* collection, iterator it, + ResourceManager* resources) { + if (collection) + return collection->remove(it, resources); + } - VariantSlot* head() const { + SlotId head() const { return head_; } - void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance); + protected: + iterator addSlot(ResourceManager*); private: - VariantSlot* getSlot(size_t index) const; - - template - VariantSlot* getSlot(TAdaptedString key) const; - - VariantSlot* getPreviousSlot(VariantSlot*) const; + SlotWithId getPreviousSlot(VariantSlot*, const ResourceManager*) const; + void releaseSlot(SlotWithId, ResourceManager*); }; inline const VariantData* collectionToVariant( diff --git a/third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp b/third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp index 134d5bd..79d9ac7 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp @@ -1,197 +1,133 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once #include -#include +#include #include +#include #include ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE -inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) { - VariantSlot* slot = pool->allocVariant(); - if (!slot) - return 0; - - if (tail_) { - ARDUINOJSON_ASSERT(pool->owns(tail_)); // Can't alter a linked array/object - tail_->setNextNotNull(slot); - tail_ = slot; - } else { - head_ = slot; - tail_ = slot; - } - - slot->clear(); - return slot; +inline CollectionIterator::CollectionIterator(VariantSlot* slot, SlotId slotId) + : slot_(slot), currentId_(slotId) { + nextId_ = slot_ ? slot_->next() : NULL_SLOT; } -inline VariantData* CollectionData::addElement(MemoryPool* pool) { - return slotData(addSlot(pool)); +inline const char* CollectionIterator::key() const { + ARDUINOJSON_ASSERT(slot_ != nullptr); + return slot_->key(); } -template -inline VariantData* CollectionData::addMember(TAdaptedString key, - MemoryPool* pool) { - VariantSlot* slot = addSlot(pool); - if (!slotSetKey(slot, key, pool)) { - removeSlot(slot); - return 0; - } - return slot->data(); +inline void CollectionIterator::setKey(const char* s) { + ARDUINOJSON_ASSERT(slot_ != nullptr); + ARDUINOJSON_ASSERT(s != nullptr); + return slot_->setKey(s); } -inline void CollectionData::clear() { - head_ = 0; - tail_ = 0; +inline void CollectionIterator::setKey(StringNode* s) { + ARDUINOJSON_ASSERT(slot_ != nullptr); + ARDUINOJSON_ASSERT(s != nullptr); + return slot_->setKey(s); } -template -inline bool CollectionData::containsKey(const TAdaptedString& key) const { - return getSlot(key) != 0; +inline bool CollectionIterator::ownsKey() const { + ARDUINOJSON_ASSERT(slot_ != nullptr); + return slot_->ownsKey(); } -inline bool CollectionData::copyFrom(const CollectionData& src, - MemoryPool* pool) { - clear(); - for (VariantSlot* s = src.head_; s; s = s->next()) { - VariantData* var; - if (s->key() != 0) { - JsonString key(s->key(), - s->ownsKey() ? JsonString::Copied : JsonString::Linked); - var = addMember(adaptString(key), pool); - } else { - var = addElement(pool); - } - if (!var) - return false; - if (!var->copyFrom(*s->data(), pool)) - return false; - } - return true; +inline void CollectionIterator::next(const ResourceManager* resources) { + ARDUINOJSON_ASSERT(currentId_ != NULL_SLOT); + slot_ = resources->getSlot(nextId_); + currentId_ = nextId_; + if (slot_) + nextId_ = slot_->next(); } -template -inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const { - if (key.isNull()) - return 0; - VariantSlot* slot = head_; - while (slot) { - if (stringEquals(key, adaptString(slot->key()))) - break; - slot = slot->next(); +inline CollectionData::iterator CollectionData::addSlot( + ResourceManager* resources) { + auto slot = resources->allocSlot(); + if (!slot) + return {}; + if (tail_ != NULL_SLOT) { + auto tail = resources->getSlot(tail_); + tail->setNext(slot.id()); + tail_ = slot.id(); + } else { + head_ = slot.id(); + tail_ = slot.id(); } - return slot; -} - -inline VariantSlot* CollectionData::getSlot(size_t index) const { - if (!head_) - return 0; - return head_->next(index); + return iterator(slot, slot.id()); } -inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const { - VariantSlot* current = head_; - while (current) { - VariantSlot* next = current->next(); - if (next == target) - return current; - current = next; +inline void CollectionData::clear(ResourceManager* resources) { + auto next = head_; + while (next != NULL_SLOT) { + auto currId = next; + auto slot = resources->getSlot(next); + next = slot->next(); + releaseSlot(SlotWithId(slot, currId), resources); } - return 0; -} - -template -inline VariantData* CollectionData::getMember(TAdaptedString key) const { - VariantSlot* slot = getSlot(key); - return slot ? slot->data() : 0; -} - -template -inline VariantData* CollectionData::getOrAddMember(TAdaptedString key, - MemoryPool* pool) { - // ignore null key - if (key.isNull()) - return 0; - // search a matching key - VariantSlot* slot = getSlot(key); - if (slot) - return slot->data(); - - return addMember(key, pool); + head_ = NULL_SLOT; + tail_ = NULL_SLOT; } -inline VariantData* CollectionData::getElement(size_t index) const { - VariantSlot* slot = getSlot(index); - return slot ? slot->data() : 0; -} - -inline VariantData* CollectionData::getOrAddElement(size_t index, - MemoryPool* pool) { - VariantSlot* slot = head_; - while (slot && index > 0) { - slot = slot->next(); - index--; - } - if (!slot) - index++; - while (index > 0) { - slot = addSlot(pool); - index--; +inline SlotWithId CollectionData::getPreviousSlot( + VariantSlot* target, const ResourceManager* resources) const { + auto prev = SlotWithId(); + auto currentId = head_; + while (currentId != NULL_SLOT) { + auto currentSlot = resources->getSlot(currentId); + if (currentSlot == target) + return prev; + prev = SlotWithId(currentSlot, currentId); + currentId = currentSlot->next(); } - return slotData(slot); + return SlotWithId(); } -inline void CollectionData::removeSlot(VariantSlot* slot) { - if (!slot) +inline void CollectionData::remove(iterator it, ResourceManager* resources) { + if (it.done()) return; - VariantSlot* prev = getPreviousSlot(slot); - VariantSlot* next = slot->next(); + auto curr = it.slot_; + auto prev = getPreviousSlot(curr, resources); + auto next = curr->next(); if (prev) prev->setNext(next); else head_ = next; - if (!next) - tail_ = prev; -} - -inline void CollectionData::removeElement(size_t index) { - removeSlot(getSlot(index)); + if (next == NULL_SLOT) + tail_ = prev.id(); + releaseSlot({it.slot_, it.currentId_}, resources); } -inline size_t CollectionData::memoryUsage() const { - size_t total = 0; - for (VariantSlot* s = head_; s; s = s->next()) { - total += sizeof(VariantSlot) + s->data()->memoryUsage(); - if (s->ownsKey()) - total += strlen(s->key()) + 1; +inline size_t CollectionData::nesting(const ResourceManager* resources) const { + size_t maxChildNesting = 0; + for (auto it = createIterator(resources); !it.done(); it.next(resources)) { + size_t childNesting = it->nesting(resources); + if (childNesting > maxChildNesting) + maxChildNesting = childNesting; } - return total; + return maxChildNesting + 1; } -inline size_t CollectionData::size() const { - return slotSize(head_); -} - -template -inline void movePointer(T*& p, ptrdiff_t offset) { - if (!p) - return; - p = reinterpret_cast( - reinterpret_cast(reinterpret_cast(p) + offset)); - ARDUINOJSON_ASSERT(isAligned(p)); +inline size_t CollectionData::size(const ResourceManager* resources) const { + size_t count = 0; + for (auto it = createIterator(resources); !it.done(); it.next(resources)) + count++; + return count; } -inline void CollectionData::movePointers(ptrdiff_t stringDistance, - ptrdiff_t variantDistance) { - movePointer(head_, variantDistance); - movePointer(tail_, variantDistance); - for (VariantSlot* slot = head_; slot; slot = slot->next()) - slot->movePointers(stringDistance, variantDistance); +inline void CollectionData::releaseSlot(SlotWithId slot, + ResourceManager* resources) { + if (slot->ownsKey()) + resources->dereferenceString(slot->key()); + slot->data()->setNull(resources); + resources->freeSlot(slot); } ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/third-party/ArduinoJson/src/ArduinoJson/Configuration.hpp b/third-party/ArduinoJson/src/ArduinoJson/Configuration.hpp index ac0ea66..12d6068 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Configuration.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Configuration.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -59,35 +59,75 @@ # define ARDUINOJSON_USE_DOUBLE 1 #endif +// Pointer size: a heuristic to set sensible defaults +#ifndef ARDUINOJSON_SIZEOF_POINTER +# if defined(__SIZEOF_POINTER__) +# define ARDUINOJSON_SIZEOF_POINTER __SIZEOF_POINTER__ +# elif defined(_WIN64) && _WIN64 +# define ARDUINOJSON_SIZEOF_POINTER 8 // 64 bits +# else +# define ARDUINOJSON_SIZEOF_POINTER 4 // assume 32 bits otherwise +# endif +#endif + // Store integral values with long (0) or long long (1) #ifndef ARDUINOJSON_USE_LONG_LONG -# if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ >= 4 || \ - defined(_MSC_VER) +# if ARDUINOJSON_SIZEOF_POINTER >= 4 // 32 & 64 bits systems # define ARDUINOJSON_USE_LONG_LONG 1 +# else +# define ARDUINOJSON_USE_LONG_LONG 0 # endif #endif -#ifndef ARDUINOJSON_USE_LONG_LONG -# define ARDUINOJSON_USE_LONG_LONG 0 -#endif // Limit nesting as the stack is likely to be small #ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT # define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10 #endif -// Number of bits to store the pointer to next node -// (saves RAM but limits the number of values in a document) -#ifndef ARDUINOJSON_SLOT_OFFSET_SIZE -# if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ <= 2 -// Address space == 16-bit => max 127 values -# define ARDUINOJSON_SLOT_OFFSET_SIZE 1 -# elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ >= 8 || \ - defined(_WIN64) && _WIN64 -// Address space == 64-bit => max 2147483647 values -# define ARDUINOJSON_SLOT_OFFSET_SIZE 4 +// Number of bytes to store the variant identifier +#ifndef ARDUINOJSON_SLOT_ID_SIZE +# if ARDUINOJSON_SIZEOF_POINTER <= 2 +# define ARDUINOJSON_SLOT_ID_SIZE 1 // up to 255 slots +# elif ARDUINOJSON_SIZEOF_POINTER == 4 +# define ARDUINOJSON_SLOT_ID_SIZE 2 // up to 65535 slots +# else +# define ARDUINOJSON_SLOT_ID_SIZE 4 // up to 4294967295 slots +# endif +#endif + +// Capacity of each variant pool (in slots) +#ifndef ARDUINOJSON_POOL_CAPACITY +# if ARDUINOJSON_SIZEOF_POINTER <= 2 +# define ARDUINOJSON_POOL_CAPACITY 16 // 128 bytes +# elif ARDUINOJSON_SIZEOF_POINTER == 4 +# define ARDUINOJSON_POOL_CAPACITY 64 // 1024 bytes # else -// Address space == 32-bit => max 32767 values -# define ARDUINOJSON_SLOT_OFFSET_SIZE 2 +# define ARDUINOJSON_POOL_CAPACITY 128 // 3072 bytes +# endif +#endif + +// Initial capacity of the pool list +#ifndef ARDUINOJSON_INITIAL_POOL_COUNT +# define ARDUINOJSON_INITIAL_POOL_COUNT 4 +#endif + +// Automatically call shrinkToFit() from deserializeXxx() +// Disabled by default on 8-bit platforms because it's not worth the increase in +// code size +#ifndef ARDUINOJSON_AUTO_SHRINK +# if ARDUINOJSON_SIZEOF_POINTER <= 2 +# define ARDUINOJSON_AUTO_SHRINK 0 +# else +# define ARDUINOJSON_AUTO_SHRINK 1 +# endif +#endif + +// Number of bytes to store the length of a string +#ifndef ARDUINOJSON_STRING_LENGTH_SIZE +# if ARDUINOJSON_SIZEOF_POINTER <= 2 +# define ARDUINOJSON_STRING_LENGTH_SIZE 1 // up to 255 characters +# else +# define ARDUINOJSON_STRING_LENGTH_SIZE 2 // up to 65535 characters # endif #endif @@ -195,10 +235,6 @@ # define ARDUINOJSON_TAB " " #endif -#ifndef ARDUINOJSON_ENABLE_STRING_DEDUPLICATION -# define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1 -#endif - #ifndef ARDUINOJSON_STRING_BUFFER_SIZE # define ARDUINOJSON_STRING_BUFFER_SIZE 32 #endif diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp index 1bfc393..fd32a55 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationOptions.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationOptions.hpp index 8400cc0..4c73934 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationOptions.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationOptions.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp index 3988302..7670556 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp @@ -1,17 +1,24 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once -#include +#include +#include ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE namespace DeserializationOption { class Filter { public: - explicit Filter(JsonVariantConst v) : variant_(v) {} +#if ARDUINOJSON_AUTO_SHRINK + explicit Filter(JsonDocument& doc) : variant_(doc) { + doc.shrinkToFit(); + } +#endif + + explicit Filter(JsonVariantConst variant) : variant_(variant) {} bool allow() const { return variant_; diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp index 6434275..d30402b 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp index 4443768..c4b5edb 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -19,7 +19,7 @@ struct Reader { int read() { // clang-format off - return source_->read(); // Error here? See https://arduinojson.org/v6/invalid-input/ + return source_->read(); // Error here? See https://arduinojson.org/v7/invalid-input/ // clang-format on } diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp index 8a87388..43c5a43 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -15,7 +15,7 @@ struct Readerread() as it ignores the timeout char c; return stream_->readBytes(&c, 1) ? static_cast(c) : -1; } diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp index 14491f4..4730be0 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp index 97714af..fa8ff23 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp index c0ca4a7..1ca46c8 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp index eff67ba..8603bb1 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp index 41e0c00..25ba636 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp index b60f1ce..ddb07b8 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once diff --git a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp index 9f4d78e..21d1876 100644 --- a/third-party/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp +++ b/third-party/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp @@ -1,5 +1,5 @@ // ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON +// Copyright © 2014-2024, Benoit BLANCHON // MIT License #pragma once @@ -8,7 +8,6 @@ #include #include #include -#include ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE @@ -23,44 +22,62 @@ struct first_or_void { using type = T; }; -template