Added memoryUsage() to JsonArray, JsonObject, and JsonVariant

This commit is contained in:
Benoit Blanchon
2019-01-16 09:50:57 +01:00
parent 8b04046321
commit c51cc91f92
14 changed files with 165 additions and 1 deletions

View File

@ -10,6 +10,7 @@ HEAD
* `JsonArray::copyFrom()` accepts `JsonArrayConst`
* `JsonVariant::set()` accepts `JsonArrayConst` and `JsonObjectConst`
* `JsonDocument` was missing in the ArduinoJson namespace
* Added `memoryUsage()` to `JsonArray`, `JsonObject`, and `JsonVariant`
> ### BREAKING CHANGES
>

View File

@ -34,6 +34,10 @@ class ArrayRefBase {
return VariantConstRef(_data ? _data->get(index) : 0);
}
FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0;
}
FORCE_INLINE size_t size() const {
return _data ? _data->size() : 0;
}

View File

@ -55,6 +55,7 @@ class CollectionData {
void remove(VariantSlot *slot);
size_t memoryUsage() const;
size_t size() const;
private:

View File

@ -138,6 +138,15 @@ inline void CollectionData::remove(size_t index) {
remove(getSlot(index));
}
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;
}
return total;
}
inline size_t CollectionData::size() const {
return slotSize(_head);
}

View File

@ -42,6 +42,10 @@ class ObjectRefBase {
return _data == 0;
}
FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0;
}
FORCE_INLINE size_t size() const {
return _data ? _data->size() : 0;
}

View File

@ -266,6 +266,20 @@ class VariantData {
return _content.asCollection;
}
size_t memoryUsage() const {
switch (type()) {
case VALUE_IS_OWNED_STRING:
return strlen(_content.asString) + 1;
case VALUE_IS_OWNED_RAW:
return _content.asRaw.size;
case VALUE_IS_OBJECT:
case VALUE_IS_ARRAY:
return _content.asCollection.memoryUsage();
default:
return 0;
}
}
size_t size() const {
if (type() == VALUE_IS_OBJECT || type() == VALUE_IS_ARRAY)
return _content.asCollection.size();

View File

@ -95,6 +95,10 @@ class VariantRefBase {
return variantIsNull(_data);
}
FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0;
}
size_t size() const {
return variantSize(_data);
}

View File

@ -11,6 +11,7 @@ add_executable(JsonArrayTests
get.cpp
isNull.cpp
iterator.cpp
memoryUsage.cpp
remove.cpp
size.cpp
std_string.cpp

View File

@ -0,0 +1,42 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonArray::memoryUsage()") {
DynamicJsonDocument doc(4096);
JsonArray arr = doc.to<JsonArray>();
SECTION("return 0 if uninitialized") {
JsonArray unitialized;
REQUIRE(unitialized.memoryUsage() == 0);
}
SECTION("JSON_ARRAY_SIZE(0) if empty") {
REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0));
}
SECTION("JSON_ARRAY_SIZE(1) after add") {
arr.add("hello");
REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(1));
}
SECTION("includes the size of the string") {
arr.add(std::string("hello"));
REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(1) + 6);
}
SECTION("includes the size of the nested array") {
JsonArray nested = arr.createNestedArray();
nested.add(42);
REQUIRE(arr.memoryUsage() == 2 * JSON_ARRAY_SIZE(1));
}
SECTION("includes the size of the nested arrect") {
JsonObject nested = arr.createNestedObject();
nested["hello"] = "world";
REQUIRE(arr.memoryUsage() == JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1));
}
}

View File

@ -9,7 +9,7 @@ TEST_CASE("JsonArray::size()") {
DynamicJsonDocument doc(4096);
JsonArray array = doc.to<JsonArray>();
SECTION("InitialSizeIsZero") {
SECTION("returns 0 is empty") {
REQUIRE(0U == array.size());
}

View File

@ -11,6 +11,7 @@ add_executable(JsonObjectTests
invalid.cpp
isNull.cpp
iterator.cpp
memoryUsage.cpp
remove.cpp
size.cpp
std_string.cpp

View File

@ -0,0 +1,43 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string>
TEST_CASE("JsonObject::memoryUsage()") {
DynamicJsonDocument doc(4096);
JsonObject obj = doc.to<JsonObject>();
SECTION("return 0 if uninitialized") {
JsonObject unitialized;
REQUIRE(unitialized.memoryUsage() == 0);
}
SECTION("JSON_OBJECT_SIZE(0) for empty object") {
REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0));
}
SECTION("JSON_OBJECT_SIZE(1) after add") {
obj["hello"] = 42;
REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(1));
}
SECTION("includes the size of the key") {
obj[std::string("hello")] = 42;
REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(1) + 6);
}
SECTION("includes the size of the nested array") {
JsonArray nested = obj.createNestedArray("nested");
nested.add(42);
REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1));
}
SECTION("includes the size of the nested object") {
JsonObject nested = obj.createNestedObject("nested");
nested["hello"] = "world";
REQUIRE(obj.memoryUsage() == 2 * JSON_OBJECT_SIZE(1));
}
}

View File

@ -9,6 +9,7 @@ add_executable(JsonVariantTests
get.cpp
is.cpp
isnull.cpp
memoryUsage.cpp
misc.cpp
or.cpp
set.cpp

View File

@ -0,0 +1,39 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string>
TEST_CASE("JsonVariant::memoryUsage()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("returns 0 if uninitialized") {
JsonVariant unitialized;
REQUIRE(unitialized.memoryUsage() == 0);
}
SECTION("returns size of object") {
JsonObject obj = var.to<JsonObject>();
obj["hello"] = 42;
REQUIRE(var.memoryUsage() == JSON_OBJECT_SIZE(1));
}
SECTION("returns size of array") {
JsonArray arr = var.to<JsonArray>();
arr.add(42);
REQUIRE(var.memoryUsage() == JSON_ARRAY_SIZE(1));
}
SECTION("returns size of owned string") {
var.set(std::string("hello"));
REQUIRE(var.memoryUsage() == 6);
}
SECTION("returns size of owned raw") {
var.set(serialized(std::string("hello")));
REQUIRE(var.memoryUsage() == 5);
}
}