diff --git a/src/utils/DynamicJsonHandler.cpp b/src/utils/DynamicJsonHandler.cpp new file mode 100644 index 00000000..8b7c4fab --- /dev/null +++ b/src/utils/DynamicJsonHandler.cpp @@ -0,0 +1,39 @@ +#include "DynamicJsonHandler.h" + +DynamicJsonHandler::DynamicJsonHandler() : doc(min_size) { +} + +DynamicJsonHandler::~DynamicJsonHandler() { + delete &doc; +} + +String DynamicJsonHandler::toString() { + String jsonString; + serializeJson(doc, jsonString); + doc.clear(); // TODO: Entfernen wegen mqtt + webserial? + return jsonString; +} + +void DynamicJsonHandler::clear() { + doc.clear(); +} + +size_t DynamicJsonHandler::size() const { + return doc.memoryUsage(); +} + +void DynamicJsonHandler::resizeDocument(size_t requiredSize) { + // TODO: multiplikator zwei muss ersetzt werden? Kann noch minimal werden. + size_t newCapacity = min(max(requiredSize * 2, min_size), max_size); + DynamicJsonDocument newDoc(newCapacity); + newDoc.set(doc); // Bestehende Daten kopieren + doc = std::move(newDoc); +} + +size_t DynamicJsonHandler::min(size_t a, size_t b) { + return (a < b) ? a : b; +} + +size_t DynamicJsonHandler::max(size_t a, size_t b) { + return (a > b) ? a : b; +} diff --git a/src/utils/DynamicJsonHandler.h b/src/utils/DynamicJsonHandler.h new file mode 100644 index 00000000..4c7a7476 --- /dev/null +++ b/src/utils/DynamicJsonHandler.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// 2022 Ahoy, https://github.com/lumpapu/ahoy +// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ +//----------------------------------------------------------------------------- + +#ifndef __DYNAMICJSONHANDLER_H__ +#define __DYNAMICJSONHANDLER_H__ + +#include <Arduino.h> +#include <ArduinoJson.h> +#include <string> + +class DynamicJsonHandler { +public: + DynamicJsonHandler(); + ~DynamicJsonHandler(); + + template<typename T> + void addProperty(const std::string& key, const T& value); + + String toString(); + void clear(); + size_t size() const; + +private: + DynamicJsonDocument doc; + static const size_t min_size = 256; + static const size_t max_size = 5000; // Max RAM : 2 = da es für resizeDocument eng werden könnte? + + void resizeDocument(size_t requiredSize); + size_t min(size_t a, size_t b); + size_t max(size_t a, size_t b); +}; + +template<typename T> +void DynamicJsonHandler::addProperty(const std::string& key, const T& value) { + size_t additionalSize = JSON_OBJECT_SIZE(1) + key.length() + sizeof(value); + if (doc.memoryUsage() + additionalSize > doc.capacity()) { + resizeDocument(doc.memoryUsage() + additionalSize); + } + doc[key] = value; +} + +#endif /*__DYNAMICJSONHANDLER_H__*/