diff --git a/CHANGELOG.md b/CHANGELOG.md index 558653c0..04ecfcd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ HEAD * 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) v6.14.1 (2020-01-27) diff --git a/examples/JsonFilterExample/JsonFilterExample.ino b/examples/JsonFilterExample/JsonFilterExample.ino index e4d69590..9de2a490 100644 --- a/examples/JsonFilterExample/JsonFilterExample.ino +++ b/examples/JsonFilterExample/JsonFilterExample.ino @@ -33,12 +33,9 @@ void setup() { "1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}"); // The filter: it contains "true" for each value we want to keep - const __FlashStringHelper* filter_json = - F("{\"list\":[{\"dt\":true,\"main\":{\"temp\":true}]}"); - - // Create the filter document StaticJsonDocument<200> filter; - deserializeJson(filter, filter_json); + filter["list"][0]["dt"] = true; + filter["list"][0]["main"]["temp"] = true; // Deserialize the document StaticJsonDocument<400> doc; diff --git a/extras/tests/ElementProxy/set.cpp b/extras/tests/ElementProxy/set.cpp index 3d741812..f597f1d3 100644 --- a/extras/tests/ElementProxy/set.cpp +++ b/extras/tests/ElementProxy/set.cpp @@ -9,7 +9,6 @@ using namespace ARDUINOJSON_NAMESPACE; TEST_CASE("ElementProxy::set()") { DynamicJsonDocument doc(4096); - doc.addElement(); ElementProxy ep = doc[0]; SECTION("set(int)") { diff --git a/extras/tests/ElementProxy/subscript.cpp b/extras/tests/ElementProxy/subscript.cpp new file mode 100644 index 00000000..70bf273a --- /dev/null +++ b/extras/tests/ElementProxy/subscript.cpp @@ -0,0 +1,25 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2020 +// MIT License + +#include +#include + +using namespace ARDUINOJSON_NAMESPACE; + +TEST_CASE("MemberProxy::operator[]") { + DynamicJsonDocument doc(4096); + ElementProxy ep = doc[1]; + + SECTION("set member") { + ep["world"] = 42; + + REQUIRE(doc.as() == "[null,{\"world\":42}]"); + } + + SECTION("set element") { + ep[2] = 42; + + REQUIRE(doc.as() == "[null,[null,null,42]]"); + } +} diff --git a/extras/tests/IntegrationTests/openweathermap.cpp b/extras/tests/IntegrationTests/openweathermap.cpp index 7117ddad..335af359 100644 --- a/extras/tests/IntegrationTests/openweathermap.cpp +++ b/extras/tests/IntegrationTests/openweathermap.cpp @@ -7,10 +7,6 @@ TEST_CASE("OpenWeatherMap") { // clang-format off - const char* filter_json ="{\"list\":[" - "{\"dt\":true,\"main\":{\"temp\":true},\"weather\":[{\"description\":true}]}" - "]}"; - const char* input_json = "{\"cod\":\"200\",\"message\":0,\"cnt\":40,\"list\":[{\"dt\":1581498000,\"main\":{\"temp\":3.23,\"feels_like\":-3.63,\"temp_min\":3.23,\"temp_max\":4.62,\"pressure\":1014,\"sea_level\":1014,\"grnd_level\":1010,\"humidity\":58,\"temp_kf\":-1.39},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":6.19,\"deg\":266},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 09:00:00\"},{\"dt\":1581508800,\"main\":{\"temp\":6.09,\"feels_like\":-1.07,\"temp_min\":6.09,\"temp_max\":7.13,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":1011,\"humidity\":48,\"temp_kf\":-1.04},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":9},\"wind\":{\"speed\":6.64,\"deg\":268},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 12:00:00\"},{\"dt\":1581519600,\"main\":{\"temp\":6.82,\"feels_like\":0.47,\"temp_min\":6.82,\"temp_max\":7.52,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":1011,\"humidity\":47,\"temp_kf\":-0.7},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],\"clouds\":{\"all\":97},\"wind\":{\"speed\":5.55,\"deg\":267},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 15:00:00\"},{\"dt\":1581530400,\"main\":{\"temp\":5.76,\"feels_like\":1.84,\"temp_min\":5.76,\"temp_max\":6.11,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":1010,\"humidity\":57,\"temp_kf\":-0.35},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":99},\"wind\":{\"speed\":2.35,\"deg\":232},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-12 18:00:00\"},{\"dt\":1581541200,\"main\":{\"temp\":5.7,\"feels_like\":1.34,\"temp_min\":5.7,\"temp_max\":5.7,\"pressure\":1012,\"sea_level\":1012,\"grnd_level\":1008,\"humidity\":71,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":3.57,\"deg\":198},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-12 21:00:00\"},{\"dt\":1581552000,\"main\":{\"temp\":5.82,\"feels_like\":1.39,\"temp_min\":5.82,\"temp_max\":5.82,\"pressure\":1009,\"sea_level\":1009,\"grnd_level\":1004,\"humidity\":86,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":4.35,\"deg\":169},\"rain\":{\"3h\":0.5},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-13 00:00:00\"},{\"dt\":1581562800,\"main\":{\"temp\":5.9,\"feels_like\":-0.85,\"temp_min\":5.9,\"temp_max\":5.9,\"pressure\":1000,\"sea_level\":1000,\"grnd_level\":997,\"humidity\":86,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":7.69,\"deg\":178},\"rain\":{\"3h\":1.75},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-13 03:00:00\"},{\"dt\":1581573600,\"main\":{\"temp\":7.52,\"feels_like\":1.74,\"temp_min\":7.52,\"temp_max\":7.52,\"pressure\":993,\"sea_level\":993,\"grnd_level\":988,\"humidity\":88,\"temp_kf\":0},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":6.84,\"deg\":184},\"rain\":{\"3h\":7.06},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-13 06:00:00\"},{\"dt\":1581584400,\"main\":{\"temp\":7.23,\"feels_like\":0.81,\"temp_min\":7.23,\"temp_max\":7.23,\"pressure\":992,\"sea_level\":992,\"grnd_level\":988,\"humidity\":69,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":49},\"wind\":{\"speed\":6.77,\"deg\":239},\"rain\":{\"3h\":0.25},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-13 09:00:00\"},{\"dt\":1581595200,\"main\":{\"temp\":7.67,\"feels_like\":2.81,\"temp_min\":7.67,\"temp_max\":7.67,\"pressure\":991,\"sea_level\":991,\"grnd_level\":987,\"humidity\":75,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":73},\"wind\":{\"speed\":4.93,\"deg\":235},\"rain\":{\"3h\":0.75},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-13 12:00:00\"},{\"dt\":1581606000,\"main\":{\"temp\":8.83,\"feels_like\":3.23,\"temp_min\":8.83,\"temp_max\":8.83,\"pressure\":993,\"sea_level\":993,\"grnd_level\":990,\"humidity\":64,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":83},\"wind\":{\"speed\":5.7,\"deg\":293},\"rain\":{\"3h\":0.38},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-13 15:00:00\"},{\"dt\":1581616800,\"main\":{\"temp\":7.42,\"feels_like\":1.77,\"temp_min\":7.42,\"temp_max\":7.42,\"pressure\":1000,\"sea_level\":1000,\"grnd_level\":996,\"humidity\":71,\"temp_kf\":0},\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":54},\"wind\":{\"speed\":5.81,\"deg\":307},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-13 18:00:00\"},{\"dt\":1581627600,\"main\":{\"temp\":5.82,\"feels_like\":0.89,\"temp_min\":5.82,\"temp_max\":5.82,\"pressure\":1007,\"sea_level\":1007,\"grnd_level\":1003,\"humidity\":79,\"temp_kf\":0},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01n\"}],\"clouds\":{\"all\":6},\"wind\":{\"speed\":4.76,\"deg\":300},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-13 21:00:00\"},{\"dt\":1581638400,\"main\":{\"temp\":5.58,\"feels_like\":2.09,\"temp_min\":5.58,\"temp_max\":5.58,\"pressure\":1011,\"sea_level\":1011,\"grnd_level\":1007,\"humidity\":81,\"temp_kf\":0},\"weather\":[{\"id\":802,\"main\":\"Clouds\",\"description\":\"scattered clouds\",\"icon\":\"03n\"}],\"clouds\":{\"all\":47},\"wind\":{\"speed\":2.73,\"deg\":326},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-14 00:00:00\"},{\"dt\":1581649200,\"main\":{\"temp\":4.27,\"feels_like\":1.72,\"temp_min\":4.27,\"temp_max\":4.27,\"pressure\":1014,\"sea_level\":1014,\"grnd_level\":1010,\"humidity\":85,\"temp_kf\":0},\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":69},\"wind\":{\"speed\":1.24,\"deg\":295},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-14 03:00:00\"},{\"dt\":1581660000,\"main\":{\"temp\":3.91,\"feels_like\":1.54,\"temp_min\":3.91,\"temp_max\":3.91,\"pressure\":1016,\"sea_level\":1016,\"grnd_level\":1012,\"humidity\":87,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":85},\"wind\":{\"speed\":0.98,\"deg\":211},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-14 06:00:00\"},{\"dt\":1581670800,\"main\":{\"temp\":4.77,\"feels_like\":0.74,\"temp_min\":4.77,\"temp_max\":4.77,\"pressure\":1017,\"sea_level\":1017,\"grnd_level\":1013,\"humidity\":78,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":3.19,\"deg\":184},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-14 09:00:00\"},{\"dt\":1581681600,\"main\":{\"temp\":9.03,\"feels_like\":4,\"temp_min\":9.03,\"temp_max\":9.03,\"pressure\":1016,\"sea_level\":1016,\"grnd_level\":1012,\"humidity\":73,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":5.43,\"deg\":206},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-14 12:00:00\"},{\"dt\":1581692400,\"main\":{\"temp\":9.86,\"feels_like\":4.22,\"temp_min\":9.86,\"temp_max\":9.86,\"pressure\":1014,\"sea_level\":1014,\"grnd_level\":1010,\"humidity\":74,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":6.58,\"deg\":209},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-14 15:00:00\"},{\"dt\":1581703200,\"main\":{\"temp\":9.48,\"feels_like\":4.8,\"temp_min\":9.48,\"temp_max\":9.48,\"pressure\":1013,\"sea_level\":1013,\"grnd_level\":1009,\"humidity\":83,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":5.6,\"deg\":206},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-14 18:00:00\"},{\"dt\":1581714000,\"main\":{\"temp\":10.03,\"feels_like\":6.48,\"temp_min\":10.03,\"temp_max\":10.03,\"pressure\":1013,\"sea_level\":1013,\"grnd_level\":1009,\"humidity\":93,\"temp_kf\":0},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":4.75,\"deg\":226},\"rain\":{\"3h\":3.13},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-14 21:00:00\"},{\"dt\":1581724800,\"main\":{\"temp\":9.48,\"feels_like\":6.25,\"temp_min\":9.48,\"temp_max\":9.48,\"pressure\":1013,\"sea_level\":1013,\"grnd_level\":1009,\"humidity\":89,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":3.87,\"deg\":214},\"rain\":{\"3h\":2.38},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-15 00:00:00\"},{\"dt\":1581735600,\"main\":{\"temp\":9.12,\"feels_like\":7.08,\"temp_min\":9.12,\"temp_max\":9.12,\"pressure\":1011,\"sea_level\":1011,\"grnd_level\":1007,\"humidity\":96,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":2.43,\"deg\":194},\"rain\":{\"3h\":1},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-15 03:00:00\"},{\"dt\":1581746400,\"main\":{\"temp\":10.32,\"feels_like\":6.71,\"temp_min\":10.32,\"temp_max\":10.32,\"pressure\":1009,\"sea_level\":1009,\"grnd_level\":1004,\"humidity\":95,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":5.05,\"deg\":196},\"rain\":{\"3h\":1.75},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-15 06:00:00\"},{\"dt\":1581757200,\"main\":{\"temp\":11.57,\"feels_like\":5.85,\"temp_min\":11.57,\"temp_max\":11.57,\"pressure\":1006,\"sea_level\":1006,\"grnd_level\":1002,\"humidity\":85,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":7.91,\"deg\":205},\"rain\":{\"3h\":1.44},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-15 09:00:00\"},{\"dt\":1581768000,\"main\":{\"temp\":12.25,\"feels_like\":4.46,\"temp_min\":12.25,\"temp_max\":12.25,\"pressure\":1003,\"sea_level\":1003,\"grnd_level\":998,\"humidity\":78,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":10.65,\"deg\":201},\"rain\":{\"3h\":1.81},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-15 12:00:00\"},{\"dt\":1581778800,\"main\":{\"temp\":12.19,\"feels_like\":3.17,\"temp_min\":12.19,\"temp_max\":12.19,\"pressure\":998,\"sea_level\":998,\"grnd_level\":994,\"humidity\":80,\"temp_kf\":0},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":12.52,\"deg\":204},\"rain\":{\"3h\":3.5},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-15 15:00:00\"},{\"dt\":1581789600,\"main\":{\"temp\":12.25,\"feels_like\":4.15,\"temp_min\":12.25,\"temp_max\":12.25,\"pressure\":996,\"sea_level\":996,\"grnd_level\":992,\"humidity\":83,\"temp_kf\":0},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":11.42,\"deg\":215},\"rain\":{\"3h\":4.88},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-15 18:00:00\"},{\"dt\":1581800400,\"main\":{\"temp\":12.64,\"feels_like\":5.85,\"temp_min\":12.64,\"temp_max\":12.64,\"pressure\":994,\"sea_level\":994,\"grnd_level\":990,\"humidity\":76,\"temp_kf\":0},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":9.22,\"deg\":217},\"rain\":{\"3h\":6.88},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-15 21:00:00\"},{\"dt\":1581811200,\"main\":{\"temp\":12.96,\"feels_like\":4.03,\"temp_min\":12.96,\"temp_max\":12.96,\"pressure\":988,\"sea_level\":988,\"grnd_level\":984,\"humidity\":83,\"temp_kf\":0},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":12.88,\"deg\":211},\"rain\":{\"3h\":5.63},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-16 00:00:00\"},{\"dt\":1581822000,\"main\":{\"temp\":13.13,\"feels_like\":5.17,\"temp_min\":13.13,\"temp_max\":13.13,\"pressure\":987,\"sea_level\":987,\"grnd_level\":982,\"humidity\":82,\"temp_kf\":0},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":11.49,\"deg\":246},\"rain\":{\"3h\":7.25},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-16 03:00:00\"},{\"dt\":1581832800,\"main\":{\"temp\":9.07,\"feels_like\":0.79,\"temp_min\":9.07,\"temp_max\":9.07,\"pressure\":990,\"sea_level\":990,\"grnd_level\":986,\"humidity\":75,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":10.18,\"deg\":255},\"rain\":{\"3h\":2},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-16 06:00:00\"},{\"dt\":1581843600,\"main\":{\"temp\":8.05,\"feels_like\":-0.9,\"temp_min\":8.05,\"temp_max\":8.05,\"pressure\":994,\"sea_level\":994,\"grnd_level\":990,\"humidity\":51,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":9.65,\"deg\":245},\"rain\":{\"3h\":1.19},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-16 09:00:00\"},{\"dt\":1581854400,\"main\":{\"temp\":9.54,\"feels_like\":0.13,\"temp_min\":9.54,\"temp_max\":9.54,\"pressure\":996,\"sea_level\":996,\"grnd_level\":991,\"humidity\":41,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],\"clouds\":{\"all\":94},\"wind\":{\"speed\":10.03,\"deg\":243},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-16 12:00:00\"},{\"dt\":1581865200,\"main\":{\"temp\":9.08,\"feels_like\":-0.35,\"temp_min\":9.08,\"temp_max\":9.08,\"pressure\":996,\"sea_level\":996,\"grnd_level\":991,\"humidity\":44,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":89},\"wind\":{\"speed\":10.15,\"deg\":246},\"rain\":{\"3h\":0.25},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-16 15:00:00\"},{\"dt\":1581876000,\"main\":{\"temp\":7.41,\"feels_like\":-1.34,\"temp_min\":7.41,\"temp_max\":7.41,\"pressure\":996,\"sea_level\":996,\"grnd_level\":992,\"humidity\":50,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":94},\"wind\":{\"speed\":9.21,\"deg\":240},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-16 18:00:00\"},{\"dt\":1581886800,\"main\":{\"temp\":6.42,\"feels_like\":-1.7,\"temp_min\":6.42,\"temp_max\":6.42,\"pressure\":997,\"sea_level\":997,\"grnd_level\":993,\"humidity\":58,\"temp_kf\":0},\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":67},\"wind\":{\"speed\":8.52,\"deg\":236},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-16 21:00:00\"},{\"dt\":1581897600,\"main\":{\"temp\":6.03,\"feels_like\":-2.65,\"temp_min\":6.03,\"temp_max\":6.03,\"pressure\":996,\"sea_level\":996,\"grnd_level\":993,\"humidity\":51,\"temp_kf\":0},\"weather\":[{\"id\":802,\"main\":\"Clouds\",\"description\":\"scattered clouds\",\"icon\":\"03n\"}],\"clouds\":{\"all\":38},\"wind\":{\"speed\":8.94,\"deg\":240},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-17 00:00:00\"},{\"dt\":1581908400,\"main\":{\"temp\":5.62,\"feels_like\":-2.86,\"temp_min\":5.62,\"temp_max\":5.62,\"pressure\":995,\"sea_level\":995,\"grnd_level\":991,\"humidity\":53,\"temp_kf\":0},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01n\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":8.67,\"deg\":241},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-17 03:00:00\"},{\"dt\":1581919200,\"main\":{\"temp\":5.51,\"feels_like\":-2.41,\"temp_min\":5.51,\"temp_max\":5.51,\"pressure\":995,\"sea_level\":995,\"grnd_level\":991,\"humidity\":61,\"temp_kf\":0},\"weather\":[{\"id\":802,\"main\":\"Clouds\",\"description\":\"scattered clouds\",\"icon\":\"03n\"}],\"clouds\":{\"all\":35},\"wind\":{\"speed\":8.2,\"deg\":244},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-17 06:00:00\"}],\"city\":{\"id\":2643743,\"name\":\"London\",\"coord\":{\"lat\":51.5085,\"lon\":-0.1257},\"country\":\"GB\",\"population\":1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}"; const char* expected_json = "{\"list\":[" @@ -58,8 +54,9 @@ TEST_CASE("OpenWeatherMap") { // clang-format on StaticJsonDocument<512> filter; - - REQUIRE(deserializeJson(filter, filter_json) == DeserializationError::Ok); + filter["list"][0]["dt"] = true; + filter["list"][0]["main"]["temp"] = true; + filter["list"][0]["weather"][0]["description"] = true; DynamicJsonDocument doc(16384); diff --git a/extras/tests/JsonArray/subscript.cpp b/extras/tests/JsonArray/subscript.cpp index e9a94737..492c70e0 100644 --- a/extras/tests/JsonArray/subscript.cpp +++ b/extras/tests/JsonArray/subscript.cpp @@ -9,7 +9,20 @@ TEST_CASE("JsonArray::operator[]") { DynamicJsonDocument doc(4096); JsonArray array = doc.to(); - array.add(0); + + SECTION("Pad with null") { + array[2] = 2; + array[5] = 5; + REQUIRE(array.size() == 6); + REQUIRE(array[0].isNull() == true); + REQUIRE(array[1].isNull() == true); + REQUIRE(array[2].isNull() == false); + REQUIRE(array[3].isNull() == true); + REQUIRE(array[4].isNull() == true); + REQUIRE(array[5].isNull() == false); + REQUIRE(array[2] == 2); + REQUIRE(array[5] == 5); + } SECTION("int") { array[0] = 123; diff --git a/extras/tests/JsonDocument/subscript.cpp b/extras/tests/JsonDocument/subscript.cpp index 524d4869..a4554cd2 100644 --- a/extras/tests/JsonDocument/subscript.cpp +++ b/extras/tests/JsonDocument/subscript.cpp @@ -43,3 +43,11 @@ TEST_CASE("JsonDocument automatically promotes to object") { REQUIRE(doc["one"]["two"]["three"] == 4); } + +TEST_CASE("JsonDocument automatically promotes to array") { + DynamicJsonDocument doc(4096); + + doc[2] = 2; + + REQUIRE(doc.as() == "[null,null,2]"); +} diff --git a/extras/tests/JsonVariant/subscript.cpp b/extras/tests/JsonVariant/subscript.cpp index c8d2dd6d..f16972ba 100644 --- a/extras/tests/JsonVariant/subscript.cpp +++ b/extras/tests/JsonVariant/subscript.cpp @@ -43,10 +43,10 @@ TEST_CASE("JsonVariant::operator[]") { SECTION("set value") { array.add("hello"); - var[0] = "world"; + var[1] = "world"; - REQUIRE(1 == var.size()); - REQUIRE(std::string("world") == var[0]); + REQUIRE(var.size() == 2); + REQUIRE(std::string("world") == var[1]); } SECTION("set value in a nested object") { diff --git a/extras/tests/MemberProxy/subscript.cpp b/extras/tests/MemberProxy/subscript.cpp index caf38f71..876a28e8 100644 --- a/extras/tests/MemberProxy/subscript.cpp +++ b/extras/tests/MemberProxy/subscript.cpp @@ -11,9 +11,15 @@ TEST_CASE("MemberProxy::operator[]") { DynamicJsonDocument doc(4096); MemberProxy mp = doc["hello"]; - SECTION("set integer") { + SECTION("set member") { mp["world"] = 42; REQUIRE(doc.as() == "{\"hello\":{\"world\":42}}"); } + + SECTION("set element") { + mp[2] = 42; + + REQUIRE(doc.as() == "{\"hello\":[null,null,42]}"); + } } diff --git a/src/ArduinoJson/Array/ArrayFunctions.hpp b/src/ArduinoJson/Array/ArrayFunctions.hpp index b50fce7f..c8335d28 100644 --- a/src/ArduinoJson/Array/ArrayFunctions.hpp +++ b/src/ArduinoJson/Array/ArrayFunctions.hpp @@ -9,7 +9,7 @@ namespace ARDUINOJSON_NAMESPACE { inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) { - return arr ? arr->add(pool) : 0; + return arr ? arr->addElement(pool) : 0; } template diff --git a/src/ArduinoJson/Array/ArrayRef.hpp b/src/ArduinoJson/Array/ArrayRef.hpp index ff024652..bb2fbaa7 100644 --- a/src/ArduinoJson/Array/ArrayRef.hpp +++ b/src/ArduinoJson/Array/ArrayRef.hpp @@ -87,7 +87,7 @@ class ArrayConstRef : public ArrayRefBase, } FORCE_INLINE VariantConstRef getElement(size_t index) const { - return VariantConstRef(_data ? _data->get(index) : 0); + return VariantConstRef(_data ? _data->getElement(index) : 0); } }; @@ -137,23 +137,28 @@ class ArrayRef : public ArrayRefBase, return arrayEquals(_data, rhs._data); } + // Internal use + FORCE_INLINE VariantRef getOrAddElement(size_t index) const { + return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0); + } + // Gets the value at the specified index. FORCE_INLINE VariantRef getElement(size_t index) const { - return VariantRef(_pool, _data ? _data->get(index) : 0); + return VariantRef(_pool, _data ? _data->getElement(index) : 0); } // Removes element at specified position. FORCE_INLINE void remove(iterator it) const { if (!_data) return; - _data->remove(it.internal()); + _data->removeSlot(it.internal()); } // Removes element at specified index. FORCE_INLINE void remove(size_t index) const { if (!_data) return; - _data->remove(index); + _data->removeElement(index); } private: diff --git a/src/ArduinoJson/Array/ElementProxy.hpp b/src/ArduinoJson/Array/ElementProxy.hpp index 31bab2c0..9af0994b 100644 --- a/src/ArduinoJson/Array/ElementProxy.hpp +++ b/src/ArduinoJson/Array/ElementProxy.hpp @@ -28,7 +28,7 @@ class ElementProxy : public VariantOperators >, : _array(src._array), _index(src._index) {} FORCE_INLINE this_type& operator=(const this_type& src) { - getUpstreamElement().set(src.as()); + getOrAddUpstreamElement().set(src.as()); return *this; } @@ -39,7 +39,7 @@ class ElementProxy : public VariantOperators >, // std::string, String, ArrayRef, ObjectRef template FORCE_INLINE this_type& operator=(const T& src) { - getUpstreamElement().set(src); + getOrAddUpstreamElement().set(src); return *this; } // @@ -47,7 +47,7 @@ class ElementProxy : public VariantOperators >, // TValue = char*, const char*, const __FlashStringHelper* template FORCE_INLINE this_type& operator=(T* src) { - getUpstreamElement().set(src); + getOrAddUpstreamElement().set(src); return *this; } @@ -79,7 +79,7 @@ class ElementProxy : public VariantOperators >, template FORCE_INLINE typename VariantTo::type to() const { - return getUpstreamElement().template to(); + return getOrAddUpstreamElement().template to(); } // Replaces the value @@ -89,14 +89,14 @@ class ElementProxy : public VariantOperators >, // std::string, String, ArrayRef, ObjectRef template FORCE_INLINE bool set(const TValue& value) const { - return getUpstreamElement().set(value); + return getOrAddUpstreamElement().set(value); } // // bool set(TValue) // TValue = char*, const char*, const __FlashStringHelper* template FORCE_INLINE bool set(TValue* value) const { - return getUpstreamElement().set(value); + return getOrAddUpstreamElement().set(value); } template @@ -120,20 +120,20 @@ class ElementProxy : public VariantOperators >, template VariantRef getOrAddMember(TNestedKey* key) const { - return getUpstreamElement().getOrAddMember(key); + return getOrAddUpstreamElement().getOrAddMember(key); } template VariantRef getOrAddMember(const TNestedKey& key) const { - return getUpstreamElement().getOrAddMember(key); + return getOrAddUpstreamElement().getOrAddMember(key); } VariantRef addElement() const { - return getUpstreamElement().addElement(); + return getOrAddUpstreamElement().addElement(); } VariantRef getElement(size_t index) const { - return getUpstreamElement().getElement(index); + return getOrAddUpstreamElement().getElement(index); } FORCE_INLINE void remove(size_t index) const { @@ -160,6 +160,10 @@ class ElementProxy : public VariantOperators >, return _array.getElement(_index); } + FORCE_INLINE VariantRef getOrAddUpstreamElement() const { + return _array.getOrAddElement(_index); + } + TArray _array; const size_t _index; }; diff --git a/src/ArduinoJson/Collection/CollectionData.hpp b/src/ArduinoJson/Collection/CollectionData.hpp index c555ea80..13fb78b2 100644 --- a/src/ArduinoJson/Collection/CollectionData.hpp +++ b/src/ArduinoJson/Collection/CollectionData.hpp @@ -25,45 +25,56 @@ class CollectionData { // - no destructor // - no virtual // - no inheritance - VariantSlot *addSlot(MemoryPool *); - VariantData *add(MemoryPool *pool); + // Array only + + VariantData *addElement(MemoryPool *pool); + + VariantData *getElement(size_t index) const; + + VariantData *getOrAddElement(size_t index, MemoryPool *pool); + + void removeElement(size_t index); + + bool equalsArray(const CollectionData &other) const; + + // Object only template - VariantData *add(TAdaptedString key, MemoryPool *pool); + VariantData *addMember(TAdaptedString key, MemoryPool *pool); - void clear(); + template + VariantData *getMember(TAdaptedString key) const; + + template + VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool); + + template + void removeMember(TAdaptedString key) { + removeSlot(getSlot(key)); + } template bool containsKey(const TAdaptedString &key) const; - bool copyFrom(const CollectionData &src, MemoryPool *pool); - - bool equalsArray(const CollectionData &other) const; bool equalsObject(const CollectionData &other) const; - VariantData *get(size_t index) const; + // Generic - template - VariantData *get(TAdaptedString key) const; + void clear(); + size_t memoryUsage() const; + size_t nesting() const; + size_t size() const; + + VariantSlot *addSlot(MemoryPool *); + void removeSlot(VariantSlot *slot); + + bool copyFrom(const CollectionData &src, MemoryPool *pool); VariantSlot *head() const { return _head; } - void remove(size_t index); - - template - void remove(TAdaptedString key) { - remove(getSlot(key)); - } - - void remove(VariantSlot *slot); - - size_t memoryUsage() const; - size_t nesting() const; - size_t size() const; - void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance); private: diff --git a/src/ArduinoJson/Collection/CollectionImpl.hpp b/src/ArduinoJson/Collection/CollectionImpl.hpp index 3f7e39b6..1f448ff2 100644 --- a/src/ArduinoJson/Collection/CollectionImpl.hpp +++ b/src/ArduinoJson/Collection/CollectionImpl.hpp @@ -26,12 +26,13 @@ inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) { return slot; } -inline VariantData* CollectionData::add(MemoryPool* pool) { +inline VariantData* CollectionData::addElement(MemoryPool* pool) { return slotData(addSlot(pool)); } template -inline VariantData* CollectionData::add(TAdaptedString key, MemoryPool* pool) { +inline VariantData* CollectionData::addMember(TAdaptedString key, + MemoryPool* pool) { VariantSlot* slot = addSlot(pool); if (!slotSetKey(slot, key, pool)) return 0; @@ -55,11 +56,11 @@ inline bool CollectionData::copyFrom(const CollectionData& src, VariantData* var; if (s->key() != 0) { if (s->ownsKey()) - var = add(RamStringAdapter(s->key()), pool); + var = addMember(RamStringAdapter(s->key()), pool); else - var = add(ConstRamStringAdapter(s->key()), pool); + var = addMember(ConstRamStringAdapter(s->key()), pool); } else { - var = add(pool); + var = addElement(pool); } if (!var) return false; @@ -73,7 +74,7 @@ inline bool CollectionData::equalsObject(const CollectionData& other) const { size_t count = 0; for (VariantSlot* slot = _head; slot; slot = slot->next()) { VariantData* v1 = slot->data(); - VariantData* v2 = other.get(adaptString(slot->key())); + VariantData* v2 = other.getMember(adaptString(slot->key())); if (!variantEquals(v1, v2)) return false; count++; @@ -123,17 +124,40 @@ inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const { } template -inline VariantData* CollectionData::get(TAdaptedString key) const { +inline VariantData* CollectionData::getMember(TAdaptedString key) const { VariantSlot* slot = getSlot(key); return slot ? slot->data() : 0; } -inline VariantData* CollectionData::get(size_t index) const { +template +inline VariantData* CollectionData::getOrAddMember(TAdaptedString key, + MemoryPool* pool) { + VariantSlot* slot = getSlot(key); + return slot ? slot->data() : addMember(key, pool); +} + +inline VariantData* CollectionData::getElement(size_t index) const { VariantSlot* slot = getSlot(index); return slot ? slot->data() : 0; } -inline void CollectionData::remove(VariantSlot* slot) { +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--; + } + return slotData(slot); +} + +inline void CollectionData::removeSlot(VariantSlot* slot) { if (!slot) return; VariantSlot* prev = getPreviousSlot(slot); @@ -146,8 +170,8 @@ inline void CollectionData::remove(VariantSlot* slot) { _tail = prev; } -inline void CollectionData::remove(size_t index) { - remove(getSlot(index)); +inline void CollectionData::removeElement(size_t index) { + removeSlot(getSlot(index)); } inline size_t CollectionData::memoryUsage() const { diff --git a/src/ArduinoJson/Document/JsonDocument.hpp b/src/ArduinoJson/Document/JsonDocument.hpp index 08919729..915d8a8e 100644 --- a/src/ArduinoJson/Document/JsonDocument.hpp +++ b/src/ArduinoJson/Document/JsonDocument.hpp @@ -192,6 +192,10 @@ class JsonDocument : public Visitable { return VariantConstRef(_data.getElement(index)); } + FORCE_INLINE VariantRef getOrAddElement(size_t index) { + return VariantRef(&_pool, _data.getOrAddElement(index, &_pool)); + } + // JsonVariantConst getMember(char*) const // JsonVariantConst getMember(const char*) const // JsonVariantConst getMember(const __FlashStringHelper*) const diff --git a/src/ArduinoJson/Json/JsonDeserializer.hpp b/src/ArduinoJson/Json/JsonDeserializer.hpp index d27810b9..4009431e 100644 --- a/src/ArduinoJson/Json/JsonDeserializer.hpp +++ b/src/ArduinoJson/Json/JsonDeserializer.hpp @@ -139,7 +139,7 @@ class JsonDeserializer { for (;;) { if (memberFilter.allow()) { // Allocate slot in array - VariantData *value = array.add(_pool); + VariantData *value = array.addElement(_pool); if (!value) return DeserializationError::NoMemory; @@ -231,7 +231,7 @@ class JsonDeserializer { TFilter memberFilter = filter[key]; if (memberFilter.allow()) { - VariantData *variant = object.get(adaptString(key)); + VariantData *variant = object.getMember(adaptString(key)); if (!variant) { // Allocate slot in object VariantSlot *slot = object.addSlot(_pool); diff --git a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp index 18e8eb27..c48f85b4 100644 --- a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -269,7 +269,7 @@ class MsgPackDeserializer { return DeserializationError::TooDeep; for (; n; --n) { - VariantData *value = array.add(_pool); + VariantData *value = array.addElement(_pool); if (!value) return DeserializationError::NoMemory; diff --git a/src/ArduinoJson/Object/MemberProxy.hpp b/src/ArduinoJson/Object/MemberProxy.hpp index 487ac68f..b4cfce4c 100644 --- a/src/ArduinoJson/Object/MemberProxy.hpp +++ b/src/ArduinoJson/Object/MemberProxy.hpp @@ -129,11 +129,14 @@ class MemberProxy : public VariantOperators >, return getOrAddUpstreamMember().addElement(); } - // getElement(size_t) const FORCE_INLINE VariantRef getElement(size_t index) const { return getUpstreamMember().getElement(index); } + FORCE_INLINE VariantRef getOrAddElement(size_t index) const { + return getOrAddUpstreamMember().getOrAddElement(index); + } + // getMember(char*) const // getMember(const char*) const // getMember(const __FlashStringHelper*) const diff --git a/src/ArduinoJson/Object/ObjectFunctions.hpp b/src/ArduinoJson/Object/ObjectFunctions.hpp index fd761a85..90859bdf 100644 --- a/src/ArduinoJson/Object/ObjectFunctions.hpp +++ b/src/ArduinoJson/Object/ObjectFunctions.hpp @@ -28,14 +28,14 @@ template inline VariantData *objectGet(const CollectionData *obj, TAdaptedString key) { if (!obj) return 0; - return obj->get(key); + return obj->getMember(key); } template void objectRemove(CollectionData *obj, TAdaptedString key) { if (!obj) return; - obj->remove(key); + obj->removeMember(key); } template @@ -49,10 +49,10 @@ inline VariantData *objectGetOrCreate(CollectionData *obj, TAdaptedString key, return 0; // search a matching key - VariantData *var = obj->get(key); + VariantData *var = obj->getMember(key); if (var) return var; - return obj->add(key, pool); + return obj->addMember(key, pool); } } // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Object/ObjectRef.hpp b/src/ArduinoJson/Object/ObjectRef.hpp index 5a826db3..faf00bde 100644 --- a/src/ArduinoJson/Object/ObjectRef.hpp +++ b/src/ArduinoJson/Object/ObjectRef.hpp @@ -213,7 +213,7 @@ class ObjectRef : public ObjectRefBase, FORCE_INLINE void remove(iterator it) const { if (!_data) return; - _data->remove(it.internal()); + _data->removeSlot(it.internal()); } // remove(const std::string&) const diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index bb05ce8b..3c6d7a8c 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -186,13 +186,13 @@ class VariantData { void remove(size_t index) { if (isArray()) - _content.asCollection.remove(index); + _content.asCollection.removeElement(index); } template void remove(TAdaptedString key) { if (isObject()) - _content.asCollection.remove(key); + _content.asCollection.removeMember(key); } void setBoolean(bool value) { @@ -335,16 +335,24 @@ class VariantData { toArray(); if (!isArray()) return 0; - return _content.asCollection.add(pool); + return _content.asCollection.addElement(pool); } VariantData *getElement(size_t index) const { - return isArray() ? _content.asCollection.get(index) : 0; + return isArray() ? _content.asCollection.getElement(index) : 0; + } + + VariantData *getOrAddElement(size_t index, MemoryPool *pool) { + if (isNull()) + toArray(); + if (!isArray()) + return 0; + return _content.asCollection.getOrAddElement(index, pool); } template VariantData *getMember(TAdaptedString key) const { - return isObject() ? _content.asCollection.get(key) : 0; + return isObject() ? _content.asCollection.getMember(key) : 0; } template @@ -353,10 +361,7 @@ class VariantData { toObject(); if (!isObject()) return 0; - VariantData *var = _content.asCollection.get(key); - if (var) - return var; - return _content.asCollection.add(key, pool); + return _content.asCollection.getOrAddMember(key, pool); } void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) { diff --git a/src/ArduinoJson/Variant/VariantFunctions.hpp b/src/ArduinoJson/Variant/VariantFunctions.hpp index 6a55797c..26f9077d 100644 --- a/src/ArduinoJson/Variant/VariantFunctions.hpp +++ b/src/ArduinoJson/Variant/VariantFunctions.hpp @@ -160,19 +160,27 @@ inline CollectionData *variantToObject(VariantData *var) { return &var->toObject(); } -inline NO_INLINE VariantData *variantAdd(VariantData *var, MemoryPool *pool) { +inline NO_INLINE VariantData *variantAddElement(VariantData *var, + MemoryPool *pool) { return var != 0 ? var->addElement(pool) : 0; } +inline NO_INLINE VariantData *variantGetOrAddElement(VariantData *var, + size_t index, + MemoryPool *pool) { + return var != 0 ? var->getOrAddElement(index, pool) : 0; +} + template -NO_INLINE VariantData *variantGetOrCreate(VariantData *var, TChar *key, - MemoryPool *pool) { +NO_INLINE VariantData *variantGetOrAddMember(VariantData *var, TChar *key, + MemoryPool *pool) { return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0; } template -NO_INLINE VariantData *variantGetOrCreate(VariantData *var, const TString &key, - MemoryPool *pool) { +NO_INLINE VariantData *variantGetOrAddMember(VariantData *var, + const TString &key, + MemoryPool *pool) { return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0; } diff --git a/src/ArduinoJson/Variant/VariantImpl.hpp b/src/ArduinoJson/Variant/VariantImpl.hpp index 8c26266d..05633297 100644 --- a/src/ArduinoJson/Variant/VariantImpl.hpp +++ b/src/ArduinoJson/Variant/VariantImpl.hpp @@ -119,13 +119,17 @@ inline VariantConstRef VariantConstRef::getElement(size_t index) const { } inline VariantRef VariantRef::addElement() const { - return VariantRef(_pool, variantAdd(_data, _pool)); + return VariantRef(_pool, variantAddElement(_data, _pool)); } inline VariantRef VariantRef::getElement(size_t index) const { return VariantRef(_pool, _data != 0 ? _data->getElement(index) : 0); } +inline VariantRef VariantRef::getOrAddElement(size_t index) const { + return VariantRef(_pool, variantGetOrAddElement(_data, index, _pool)); +} + template inline VariantRef VariantRef::getMember(TChar *key) const { return VariantRef(_pool, _data != 0 ? _data->getMember(adaptString(key)) : 0); @@ -139,11 +143,11 @@ VariantRef::getMember(const TString &key) const { template inline VariantRef VariantRef::getOrAddMember(TChar *key) const { - return VariantRef(_pool, variantGetOrCreate(_data, key, _pool)); + return VariantRef(_pool, variantGetOrAddMember(_data, key, _pool)); } template inline VariantRef VariantRef::getOrAddMember(const TString &key) const { - return VariantRef(_pool, variantGetOrCreate(_data, key, _pool)); + return VariantRef(_pool, variantGetOrAddMember(_data, key, _pool)); } } // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantRef.hpp b/src/ArduinoJson/Variant/VariantRef.hpp index 9c9d1e91..8398624f 100644 --- a/src/ArduinoJson/Variant/VariantRef.hpp +++ b/src/ArduinoJson/Variant/VariantRef.hpp @@ -301,6 +301,8 @@ class VariantRef : public VariantRefBase, FORCE_INLINE VariantRef getElement(size_t) const; + FORCE_INLINE VariantRef getOrAddElement(size_t) const; + // getMember(const char*) const // getMember(const __FlashStringHelper*) const template @@ -391,7 +393,7 @@ class VariantConstRef : public VariantRefBase, template FORCE_INLINE VariantConstRef getMember(TChar *key) const { const CollectionData *obj = variantAsObject(_data); - return VariantConstRef(obj ? obj->get(adaptString(key)) : 0); + return VariantConstRef(obj ? obj->getMember(adaptString(key)) : 0); } // operator[](const std::string&) const