Răsfoiți Sursa

Added memoryUsage() to JsonArray, JsonObject, and JsonVariant

Benoit Blanchon 7 ani în urmă
părinte
comite
c51cc91f92

+ 1 - 0
CHANGELOG.md

@@ -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
 > 

+ 4 - 0
src/ArduinoJson/Array/ArrayRef.hpp

@@ -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;
   }

+ 1 - 0
src/ArduinoJson/Collection/CollectionData.hpp

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

+ 9 - 0
src/ArduinoJson/Collection/CollectionImpl.hpp

@@ -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);
 }

+ 4 - 0
src/ArduinoJson/Object/ObjectRef.hpp

@@ -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;
   }

+ 14 - 0
src/ArduinoJson/Variant/VariantData.hpp

@@ -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();

+ 4 - 0
src/ArduinoJson/Variant/VariantRef.hpp

@@ -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);
   }

+ 1 - 0
test/JsonArray/CMakeLists.txt

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

+ 42 - 0
test/JsonArray/memoryUsage.cpp

@@ -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));
+  }
+}

+ 1 - 1
test/JsonArray/size.cpp

@@ -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());
   }
 

+ 1 - 0
test/JsonObject/CMakeLists.txt

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

+ 43 - 0
test/JsonObject/memoryUsage.cpp

@@ -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));
+  }
+}

+ 1 - 0
test/JsonVariant/CMakeLists.txt

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

+ 39 - 0
test/JsonVariant/memoryUsage.cpp

@@ -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);
+  }
+}