From 30b94493bbda82e50bcaeb0ec293d0e92b060ad3 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 17 Jan 2019 09:55:51 +0100 Subject: [PATCH] Added nesting() to JsonArray, JsonDocument, JsonObject, and JsonVariant --- CHANGELOG.md | 1 + src/ArduinoJson/Array/ArrayRef.hpp | 4 +++ src/ArduinoJson/Collection/CollectionData.hpp | 1 + src/ArduinoJson/Collection/CollectionImpl.hpp | 9 +++++ src/ArduinoJson/Document/JsonDocument.hpp | 4 +++ src/ArduinoJson/Object/ObjectRef.hpp | 4 +++ src/ArduinoJson/Variant/VariantData.hpp | 10 ++++++ src/ArduinoJson/Variant/VariantRef.hpp | 4 +++ test/JsonArray/CMakeLists.txt | 1 + test/JsonArray/nesting.cpp | 35 +++++++++++++++++++ test/JsonDocument/CMakeLists.txt | 1 + test/JsonDocument/nesting.cpp | 30 ++++++++++++++++ test/JsonObject/CMakeLists.txt | 1 + test/JsonObject/nesting.cpp | 35 +++++++++++++++++++ test/JsonVariant/CMakeLists.txt | 1 + test/JsonVariant/nesting.cpp | 31 ++++++++++++++++ 16 files changed, 172 insertions(+) create mode 100644 test/JsonArray/nesting.cpp create mode 100644 test/JsonDocument/nesting.cpp create mode 100644 test/JsonObject/nesting.cpp create mode 100644 test/JsonVariant/nesting.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 765ef5e0..f6eb155b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ HEAD * `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` > ### BREAKING CHANGES > diff --git a/src/ArduinoJson/Array/ArrayRef.hpp b/src/ArduinoJson/Array/ArrayRef.hpp index f993c832..1e237a99 100644 --- a/src/ArduinoJson/Array/ArrayRef.hpp +++ b/src/ArduinoJson/Array/ArrayRef.hpp @@ -38,6 +38,10 @@ class ArrayRefBase { return _data ? _data->memoryUsage() : 0; } + FORCE_INLINE size_t nesting() const { + return _data ? _data->nesting() : 0; + } + FORCE_INLINE size_t size() const { return _data ? _data->size() : 0; } diff --git a/src/ArduinoJson/Collection/CollectionData.hpp b/src/ArduinoJson/Collection/CollectionData.hpp index 3f5f0b83..0b29647b 100644 --- a/src/ArduinoJson/Collection/CollectionData.hpp +++ b/src/ArduinoJson/Collection/CollectionData.hpp @@ -56,6 +56,7 @@ class CollectionData { void remove(VariantSlot *slot); size_t memoryUsage() const; + size_t nesting() const; size_t size() const; private: diff --git a/src/ArduinoJson/Collection/CollectionImpl.hpp b/src/ArduinoJson/Collection/CollectionImpl.hpp index 8dbe42f3..8b273379 100644 --- a/src/ArduinoJson/Collection/CollectionImpl.hpp +++ b/src/ArduinoJson/Collection/CollectionImpl.hpp @@ -147,6 +147,15 @@ inline size_t CollectionData::memoryUsage() const { return total; } +inline size_t CollectionData::nesting() const { + size_t maxChildNesting = 0; + for (VariantSlot* s = _head; s; s = s->next()) { + size_t childNesting = s->data()->nesting(); + if (childNesting > maxChildNesting) maxChildNesting = childNesting; + } + return maxChildNesting + 1; +} + inline size_t CollectionData::size() const { return slotSize(_head); } diff --git a/src/ArduinoJson/Document/JsonDocument.hpp b/src/ArduinoJson/Document/JsonDocument.hpp index 3eb37ac3..604d67fc 100644 --- a/src/ArduinoJson/Document/JsonDocument.hpp +++ b/src/ArduinoJson/Document/JsonDocument.hpp @@ -43,6 +43,10 @@ class JsonDocument : public Visitable { return _pool.size(); } + size_t nesting() const { + return _data.nesting(); + } + size_t capacity() const { return _pool.capacity(); } diff --git a/src/ArduinoJson/Object/ObjectRef.hpp b/src/ArduinoJson/Object/ObjectRef.hpp index b2792cdc..208a2430 100644 --- a/src/ArduinoJson/Object/ObjectRef.hpp +++ b/src/ArduinoJson/Object/ObjectRef.hpp @@ -46,6 +46,10 @@ class ObjectRefBase { return _data ? _data->memoryUsage() : 0; } + FORCE_INLINE size_t nesting() const { + return _data ? _data->nesting() : 0; + } + FORCE_INLINE size_t size() const { return _data ? _data->size() : 0; } diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index c17b5bd4..60a2cebb 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -280,6 +280,16 @@ class VariantData { } } + size_t nesting() const { + switch (type()) { + case VALUE_IS_OBJECT: + case VALUE_IS_ARRAY: + return _content.asCollection.nesting(); + default: + return 0; + } + } + size_t size() const { if (type() == VALUE_IS_OBJECT || type() == VALUE_IS_ARRAY) return _content.asCollection.size(); diff --git a/src/ArduinoJson/Variant/VariantRef.hpp b/src/ArduinoJson/Variant/VariantRef.hpp index 8578e86f..31031965 100644 --- a/src/ArduinoJson/Variant/VariantRef.hpp +++ b/src/ArduinoJson/Variant/VariantRef.hpp @@ -99,6 +99,10 @@ class VariantRefBase { return _data ? _data->memoryUsage() : 0; } + FORCE_INLINE size_t nesting() const { + return _data ? _data->nesting() : 0; + } + size_t size() const { return variantSize(_data); } diff --git a/test/JsonArray/CMakeLists.txt b/test/JsonArray/CMakeLists.txt index 851be713..9ae88e96 100644 --- a/test/JsonArray/CMakeLists.txt +++ b/test/JsonArray/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(JsonArrayTests isNull.cpp iterator.cpp memoryUsage.cpp + nesting.cpp remove.cpp size.cpp std_string.cpp diff --git a/test/JsonArray/nesting.cpp b/test/JsonArray/nesting.cpp new file mode 100644 index 00000000..c998d7e4 --- /dev/null +++ b/test/JsonArray/nesting.cpp @@ -0,0 +1,35 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("JsonArray::nesting()") { + DynamicJsonDocument doc(4096); + JsonArray arr = doc.to(); + + SECTION("return 0 if uninitialized") { + JsonArray unitialized; + REQUIRE(unitialized.nesting() == 0); + } + + SECTION("returns 1 for empty array") { + REQUIRE(arr.nesting() == 1); + } + + SECTION("returns 1 for flat array") { + arr.add("hello"); + REQUIRE(arr.nesting() == 1); + } + + SECTION("returns 2 with nested array") { + arr.createNestedArray(); + REQUIRE(arr.nesting() == 2); + } + + SECTION("returns 2 with nested object") { + arr.createNestedObject(); + REQUIRE(arr.nesting() == 2); + } +} diff --git a/test/JsonDocument/CMakeLists.txt b/test/JsonDocument/CMakeLists.txt index 4ce5e97f..f727b341 100644 --- a/test/JsonDocument/CMakeLists.txt +++ b/test/JsonDocument/CMakeLists.txt @@ -4,6 +4,7 @@ add_executable(JsonDocumentTests DynamicJsonDocument.cpp + nesting.cpp StaticJsonDocument.cpp ) diff --git a/test/JsonDocument/nesting.cpp b/test/JsonDocument/nesting.cpp new file mode 100644 index 00000000..5b28c425 --- /dev/null +++ b/test/JsonDocument/nesting.cpp @@ -0,0 +1,30 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("JsonDocument::nesting()") { + DynamicJsonDocument doc(4096); + + SECTION("return 0 if uninitialized") { + REQUIRE(doc.nesting() == 0); + } + + SECTION("returns 0 for string") { + JsonVariant var = doc.to(); + var.set("hello"); + REQUIRE(doc.nesting() == 0); + } + + SECTION("returns 1 for empty object") { + doc.to(); + REQUIRE(doc.nesting() == 1); + } + + SECTION("returns 1 for empty array") { + doc.to(); + REQUIRE(doc.nesting() == 1); + } +} diff --git a/test/JsonObject/CMakeLists.txt b/test/JsonObject/CMakeLists.txt index 389fec63..7cfa807c 100644 --- a/test/JsonObject/CMakeLists.txt +++ b/test/JsonObject/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(JsonObjectTests isNull.cpp iterator.cpp memoryUsage.cpp + nesting.cpp remove.cpp size.cpp std_string.cpp diff --git a/test/JsonObject/nesting.cpp b/test/JsonObject/nesting.cpp new file mode 100644 index 00000000..b6963be1 --- /dev/null +++ b/test/JsonObject/nesting.cpp @@ -0,0 +1,35 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("JsonObject::nesting()") { + DynamicJsonDocument doc(4096); + JsonObject obj = doc.to(); + + SECTION("return 0 if uninitialized") { + JsonObject unitialized; + REQUIRE(unitialized.nesting() == 0); + } + + SECTION("returns 1 for empty object") { + REQUIRE(obj.nesting() == 1); + } + + SECTION("returns 1 for flat object") { + obj["hello"] = "world"; + REQUIRE(obj.nesting() == 1); + } + + SECTION("returns 2 with nested array") { + obj.createNestedArray("nested"); + REQUIRE(obj.nesting() == 2); + } + + SECTION("returns 2 with nested object") { + obj.createNestedObject("nested"); + REQUIRE(obj.nesting() == 2); + } +} diff --git a/test/JsonVariant/CMakeLists.txt b/test/JsonVariant/CMakeLists.txt index 8ef62fb6..7e67ae6d 100644 --- a/test/JsonVariant/CMakeLists.txt +++ b/test/JsonVariant/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(JsonVariantTests is.cpp isnull.cpp memoryUsage.cpp + nesting.cpp misc.cpp or.cpp set.cpp diff --git a/test/JsonVariant/nesting.cpp b/test/JsonVariant/nesting.cpp new file mode 100644 index 00000000..290a5cbc --- /dev/null +++ b/test/JsonVariant/nesting.cpp @@ -0,0 +1,31 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("JsonVariant::nesting()") { + DynamicJsonDocument doc(4096); + JsonVariant var = doc.to(); + + SECTION("return 0 if uninitialized") { + JsonVariant unitialized; + REQUIRE(unitialized.nesting() == 0); + } + + SECTION("returns 0 for string") { + var.set("hello"); + REQUIRE(var.nesting() == 0); + } + + SECTION("returns 1 for empty object") { + var.to(); + REQUIRE(var.nesting() == 1); + } + + SECTION("returns 1 for empty array") { + var.to(); + REQUIRE(var.nesting() == 1); + } +}