From 06bc9462f16cae7693ad7902a7f6d63bf5ba5009 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 1 Apr 2026 22:10:17 -1000 Subject: [PATCH] [api] Deduplicate header code in plaintext write_protobuf_messages Use a single loop for all messages instead of separate first-message and loop paths. The first iteration skips memmove via the null check. Eliminates duplicated write_plaintext_header inlining, reducing flash from 326 to 229 bytes (-30%) while keeping the 64-byte stack frame. --- .../api/api_frame_helper_plaintext.cpp | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/esphome/components/api/api_frame_helper_plaintext.cpp b/esphome/components/api/api_frame_helper_plaintext.cpp index 89a8b63910..ff682b0185 100644 --- a/esphome/components/api/api_frame_helper_plaintext.cpp +++ b/esphome/components/api/api_frame_helper_plaintext.cpp @@ -294,20 +294,19 @@ APIError APIPlaintextFrameHelper::write_protobuf_messages(ProtoWriteBuffer buffe assert(!messages.empty()); #endif uint8_t *buffer_data = buffer.get_buffer()->data(); + uint8_t *write_start = nullptr; + uint8_t *write_end = nullptr; - // First message: write header, record start position - const auto &first = messages[0]; - uint8_t header_len = write_plaintext_header(buffer_data + first.offset, first); - uint8_t *write_start = buffer_data + first.offset + HEADER_PADDING - header_len; - uint8_t *write_end = write_start + header_len + first.payload_size; - - // Subsequent messages: write header, then compact to close 0-3 byte gaps - for (size_t i = 1; i < messages.size(); i++) { - const auto &msg = messages[i]; - header_len = write_plaintext_header(buffer_data + msg.offset, msg); + // Write headers and compact messages to close 0-3 byte varint padding gaps. + for (const auto &msg : messages) { + uint8_t header_len = write_plaintext_header(buffer_data + msg.offset, msg); uint8_t *src = buffer_data + msg.offset + HEADER_PADDING - header_len; uint16_t msg_len = header_len + msg.payload_size; - if (src != write_end) { + if (write_end == nullptr) { + // First message: record start, no compaction needed + write_start = src; + write_end = src; + } else if (src != write_end) { memmove(write_end, src, msg_len); } write_end += msg_len;