1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-23 21:52:23 +01:00
This commit is contained in:
J. Nick Koston
2025-09-15 21:34:19 -05:00
parent 7fe92085b4
commit b0b207eddb
2 changed files with 17 additions and 10 deletions

View File

@@ -71,17 +71,25 @@ bool parse_json(const std::string &data, const json_parse_t &f) {
} }
// JsonBuilder implementation // JsonBuilder implementation
JsonBuilder::JsonBuilder() JsonBuilder::JsonBuilder() {
: doc_(
#ifdef USE_PSRAM #ifdef USE_PSRAM
(allocator_ = std::make_unique<SpiRamAllocator>(), allocator_.get()) // Verify our storage is large enough (and log the actual size for reference)
static_assert(sizeof(SpiRamAllocator) <= sizeof(allocator_storage_), "allocator_storage_ too small");
// Note: sizeof(SpiRamAllocator) is typically around 24-32 bytes on ESP32
// Use placement new to construct SpiRamAllocator in the pre-allocated storage
auto *allocator = new (allocator_storage_) SpiRamAllocator();
doc_ = JsonDocument(allocator);
#else #else
nullptr doc_ = JsonDocument();
#endif #endif
) {
} }
JsonBuilder::~JsonBuilder() = default; JsonBuilder::~JsonBuilder() {
#ifdef USE_PSRAM
// Explicitly call destructor for placement-new allocated object
reinterpret_cast<SpiRamAllocator *>(allocator_storage_)->~SpiRamAllocator();
#endif
}
std::string JsonBuilder::serialize() { std::string JsonBuilder::serialize() {
if (doc_.overflowed()) { if (doc_.overflowed()) {

View File

@@ -25,9 +25,6 @@ std::string build_json(const json_build_t &f);
/// Parse a JSON string and run the provided json parse function if it's valid. /// Parse a JSON string and run the provided json parse function if it's valid.
bool parse_json(const std::string &data, const json_parse_t &f); bool parse_json(const std::string &data, const json_parse_t &f);
// Forward declaration to avoid exposing implementation details
struct SpiRamAllocator;
/// Builder class for creating JSON documents without lambdas /// Builder class for creating JSON documents without lambdas
class JsonBuilder { class JsonBuilder {
public: public:
@@ -46,7 +43,9 @@ class JsonBuilder {
private: private:
#ifdef USE_PSRAM #ifdef USE_PSRAM
std::unique_ptr<SpiRamAllocator> allocator_; // One heap allocation, but keeps code clean // Storage for SpiRamAllocator - typically around 24-32 bytes on ESP32
// Static assert in .cpp file ensures this is large enough
std::aligned_storage<32, alignof(void *)>::type allocator_storage_;
#endif #endif
JsonDocument doc_; JsonDocument doc_;
JsonObject root_; JsonObject root_;