The header padding is a compile-time constant per protocol (6 for
plaintext, 7 for noise). Using constexpr eliminates memory loads
on the hot path. The value is defined once per class with the
component breakdown in the comment.
WRITE_FAILED=-1 matches the socket write() return value directly,
so the fast path can pass sent through without remapping. Simplifies
both the inline fast path and the slow path errno check.
WRITE_NOT_ATTEMPTED (-1): cold path, no write tried yet — try write
WRITE_FAILED (-2): fast path write() returned -1 — skip retry, check errno
This avoids a redundant write() syscall when the fast path already
got EWOULDBLOCK and fell through to the slow path.
LOG_PACKET_SENDING was in write_raw_iov_ which is only called on
the slow path. Moved to write_protobuf_packet and write_protobuf_messages
so all packets are logged regardless of which write path is taken.
When called from cold paths (write_raw_buf_, write_frame_) with
sent=-1 and empty overflow, the function would skip the write and
read a stale errno. Now always attempts the write when overflow is
empty, matching the original write_raw_ behavior.
No overloads — every method has a unique name matching its data type:
write_raw_fast_buf_ / write_raw_buf_ — single contiguous buffer
write_raw_fast_iov_ / write_raw_iov_ — iovec array
Moving iovec construction into write_raw_fast_ caused an 8% regression
by enlarging the inlined failure path. The 33-byte out-of-line wrapper
keeps the hot inline path minimal.
Callers already guarantee DATA state before calling write_protobuf_packet
(via try_to_clear_buffer) and write_protobuf_messages (via loop processing).
The runtime check is unreachable — replaced with ESPHOME_DEBUG_API assert.
The wrappers called write_raw_inline_ which expanded the full fast
path code, defeating the purpose. Cold callers now call write_raw_slow_
directly with sent=-1, which is the same behavior without duplicating
the fast path at each cold call site.
Hot paths use write_raw_inline_ (ALWAYS_INLINE fast path).
Cold paths (handshake, error handling) use write_raw_ which is
an out-of-line wrapper that calls write_raw_inline_ — same logic,
no code duplication, but the compiler won't expand the fast path
at each cold call site.
Cold paths (write_frame_, bad indicator) no longer need to construct
an iovec just to call the slow path. The single-buffer overload wraps
in iovec internally, keeping call sites clean and avoiding iovec
setup in the caller's stack frame.
write_frame_ (handshake) and bad indicator response are cold paths
that don't benefit from the inlined write_raw_ fast path. Calling
write_raw_slow_ directly avoids expanding the inline fast path code
at these call sites, saving ~70 bytes per site.