From b125cd6979dd2393802db92db03354852829eb1e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 19 Jul 2025 13:43:47 -1000 Subject: [PATCH] save some more --- esphome/components/api/api_frame_helper.cpp | 10 +++++++--- esphome/components/api/api_frame_helper.h | 9 +++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index a6070185af..2e7956cb74 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -80,8 +80,11 @@ APIError APIFrameHelper::loop() { void APIFrameHelper::buffer_data_from_iov_(const struct iovec *iov, int iovcnt, uint16_t total_write_len, uint16_t offset) { SendBuffer buffer; - buffer.data.reserve(total_write_len - offset); + buffer.size = total_write_len - offset; + buffer.data = std::make_unique(buffer.size); + uint16_t to_skip = offset; + uint16_t write_pos = 0; for (int i = 0; i < iovcnt; i++) { if (to_skip >= iov[i].iov_len) { @@ -89,9 +92,10 @@ void APIFrameHelper::buffer_data_from_iov_(const struct iovec *iov, int iovcnt, to_skip -= static_cast(iov[i].iov_len); } else { // Include this segment (partially or fully) - const uint8_t *data = reinterpret_cast(iov[i].iov_base) + to_skip; + const uint8_t *src = reinterpret_cast(iov[i].iov_base) + to_skip; uint16_t len = static_cast(iov[i].iov_len) - to_skip; - buffer.data.insert(buffer.data.end(), data, data + len); + std::memcpy(buffer.data.get() + write_pos, src, len); + write_pos += len; to_skip = 0; } } diff --git a/esphome/components/api/api_frame_helper.h b/esphome/components/api/api_frame_helper.h index 2debfb6131..b5b25700a8 100644 --- a/esphome/components/api/api_frame_helper.h +++ b/esphome/components/api/api_frame_helper.h @@ -116,12 +116,13 @@ class APIFrameHelper { // Buffer containing data to be sent struct SendBuffer { - std::vector data; - uint16_t offset{0}; // Current offset within the buffer (uint16_t to reduce memory usage) + std::unique_ptr data; + uint16_t size{0}; // Total size of the buffer + uint16_t offset{0}; // Current offset within the buffer // Using uint16_t reduces memory usage since ESPHome API messages are limited to UINT16_MAX (65535) bytes - uint16_t remaining() const { return static_cast(data.size()) - offset; } - const uint8_t *current_data() const { return data.data() + offset; } + uint16_t remaining() const { return size - offset; } + const uint8_t *current_data() const { return data.get() + offset; } }; // Common implementation for writing raw data to socket