From d93cffedfa2a834e946c4898ec54b494e334502e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 13:08:52 -1000 Subject: [PATCH] [mdns] Use stack buffer for txt records on ESP32 --- esphome/components/mdns/mdns_esp32.cpp | 7 ++++--- esphome/core/helpers.h | 14 ++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/esphome/components/mdns/mdns_esp32.cpp b/esphome/components/mdns/mdns_esp32.cpp index e6b43e59cb..3123f3b604 100644 --- a/esphome/components/mdns/mdns_esp32.cpp +++ b/esphome/components/mdns/mdns_esp32.cpp @@ -24,13 +24,14 @@ static void register_esp32(MDNSComponent *comp, StaticVector(service.txt_records.size()); + // Stack buffer for up to 16 txt records, heap fallback for more + SmallBufferWithHeapFallback<16, mdns_txt_item_t> txt_records(service.txt_records.size()); for (size_t i = 0; i < service.txt_records.size(); i++) { const auto &record = service.txt_records[i]; // key and value are either compile-time string literals in flash or pointers to dynamic_txt_values_ // Both remain valid for the lifetime of this function, and ESP-IDF makes internal copies - txt_records[i].key = MDNS_STR_ARG(record.key); - txt_records[i].value = MDNS_STR_ARG(record.value); + txt_records.get()[i].key = MDNS_STR_ARG(record.key); + txt_records.get()[i].value = MDNS_STR_ARG(record.value); } uint16_t port = const_cast &>(service.port).value(); err = mdns_service_add(nullptr, MDNS_STR_ARG(service.service_type), MDNS_STR_ARG(service.proto), port, diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 7de952a712..eaf3ffb877 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -371,13 +371,15 @@ template class FixedVector { /// @brief Helper class for efficient buffer allocation - uses stack for small sizes, heap for large /// This is useful when most operations need a small buffer but occasionally need larger ones. /// The stack buffer avoids heap allocation in the common case, while heap fallback handles edge cases. -template class SmallBufferWithHeapFallback { +/// @tparam STACK_SIZE Number of elements in the stack buffer +/// @tparam T Element type (default: uint8_t) +template class SmallBufferWithHeapFallback { public: explicit SmallBufferWithHeapFallback(size_t size) { if (size <= STACK_SIZE) { this->buffer_ = this->stack_buffer_; } else { - this->heap_buffer_ = new uint8_t[size]; + this->heap_buffer_ = new T[size]; this->buffer_ = this->heap_buffer_; } } @@ -389,12 +391,12 @@ template class SmallBufferWithHeapFallback { SmallBufferWithHeapFallback(SmallBufferWithHeapFallback &&) = delete; SmallBufferWithHeapFallback &operator=(SmallBufferWithHeapFallback &&) = delete; - uint8_t *get() { return this->buffer_; } + T *get() { return this->buffer_; } private: - uint8_t stack_buffer_[STACK_SIZE]; - uint8_t *heap_buffer_{nullptr}; - uint8_t *buffer_; + T stack_buffer_[STACK_SIZE]; + T *heap_buffer_{nullptr}; + T *buffer_; }; ///@}