diff --git a/src/ArduinoJson/Memory/ResourceManager.hpp b/src/ArduinoJson/Memory/ResourceManager.hpp index cad05666..1d70d3d4 100644 --- a/src/ArduinoJson/Memory/ResourceManager.hpp +++ b/src/ArduinoJson/Memory/ResourceManager.hpp @@ -118,32 +118,21 @@ class ResourceManager { } StringNode* allocString(size_t length) { - auto node = reinterpret_cast( - allocator_->allocate(sizeofString(length))); - if (node) { - node->length = uint16_t(length); - node->references = 1; - } else { + auto node = StringNode::create(length, allocator_); + if (!node) overflowed_ = true; - } return node; } StringNode* reallocString(StringNode* node, size_t length) { - ARDUINOJSON_ASSERT(node != nullptr); - auto newNode = reinterpret_cast( - allocator_->reallocate(node, sizeofString(length))); - if (newNode) { - newNode->length = uint16_t(length); - } else { + node = StringNode::resize(node, length, allocator_); + if (!node) overflowed_ = true; - allocator_->deallocate(node); - } - return newNode; + return node; } void deallocString(StringNode* node) { - allocator_->deallocate(node); + StringNode::destroy(node, allocator_); } void dereferenceString(const char* s) { @@ -155,7 +144,7 @@ class ResourceManager { prev->next = node->next; else strings_ = node->next; - allocator_->deallocate(node); + StringNode::destroy(node, allocator_); } return; } diff --git a/src/ArduinoJson/Memory/StringNode.hpp b/src/ArduinoJson/Memory/StringNode.hpp index b1c7e0e3..3f020d97 100644 --- a/src/ArduinoJson/Memory/StringNode.hpp +++ b/src/ArduinoJson/Memory/StringNode.hpp @@ -4,7 +4,9 @@ #pragma once +#include #include +#include #include // uint16_t @@ -15,11 +17,41 @@ struct StringNode { uint16_t length; uint16_t references; char data[1]; + + static constexpr size_t sizeForLength(size_t n) { + return n + 1 + offsetof(StringNode, data); + } + + static StringNode* create(size_t length, Allocator* allocator) { + auto node = reinterpret_cast( + allocator->allocate(sizeForLength(length))); + if (node) { + node->length = uint16_t(length); + node->references = 1; + } + return node; + } + + static StringNode* resize(StringNode* node, size_t length, + Allocator* allocator) { + ARDUINOJSON_ASSERT(node != nullptr); + auto newNode = reinterpret_cast( + allocator->reallocate(node, sizeForLength(length))); + if (newNode) + newNode->length = uint16_t(length); + else + allocator->deallocate(node); + return newNode; + } + + static void destroy(StringNode* node, Allocator* allocator) { + allocator->deallocate(node); + } }; // Returns the size (in bytes) of an string with n characters. constexpr size_t sizeofString(size_t n) { - return n + 1 + offsetof(StringNode, data); + return StringNode::sizeForLength(n); } ARDUINOJSON_END_PRIVATE_NAMESPACE