This commit is contained in:
J. Nick Koston
2026-04-03 23:34:57 -10:00
parent 392aa0fcbc
commit 8b0e6a3324
3 changed files with 17 additions and 15 deletions
+3 -3
View File
@@ -398,7 +398,7 @@ uint16_t APIConnection::fill_and_encode_entity_info(EntityBase *entity, InfoResp
#ifdef USE_DEVICES
msg.device_id = entity->get_device_id();
#endif
return encode_to_buffer_slow_(size_fn(&msg), encode_fn, &msg, conn, remaining_size);
return encode_to_buffer_slow(size_fn(&msg), encode_fn, &msg, conn, remaining_size);
}
uint16_t APIConnection::fill_and_encode_entity_info_with_device_class(EntityBase *entity, InfoResponseProtoMessage &msg,
@@ -1999,8 +1999,8 @@ bool APIConnection::send_message_(uint32_t payload_size, uint8_t message_type, M
// encode_to_buffer is defined inline in api_connection.h (ESPHOME_ALWAYS_INLINE)
// Noinline version for cold paths — single shared copy
uint16_t APIConnection::encode_to_buffer_slow_(uint32_t calculated_size, MessageEncodeFn encode_fn, const void *msg,
APIConnection *conn, uint32_t remaining_size) {
uint16_t APIConnection::encode_to_buffer_slow(uint32_t calculated_size, MessageEncodeFn encode_fn, const void *msg,
APIConnection *conn, uint32_t remaining_size) {
return encode_to_buffer(calculated_size, encode_fn, msg, conn, remaining_size);
}
bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
+5 -5
View File
@@ -443,18 +443,18 @@ class APIConnection final : public APIServerConnectionBase {
// Noinline version of encode_to_buffer for cold paths (entity info, zero-payload messages).
// All cold callers share this single copy instead of each getting an ALWAYS_INLINE expansion.
static uint16_t encode_to_buffer_slow_(uint32_t calculated_size, MessageEncodeFn encode_fn, const void *msg,
APIConnection *conn, uint32_t remaining_size);
static uint16_t encode_to_buffer_slow(uint32_t calculated_size, MessageEncodeFn encode_fn, const void *msg,
APIConnection *conn, uint32_t remaining_size);
// Thin template wrapper — uses noinline encode_to_buffer_slow_ since
// Thin template wrapper — uses noinline encode_to_buffer_slow since
// encode_message_to_buffer callers are cold paths (zero-payload control messages).
// Hot paths (state/info) go through fill_and_encode_entity_state/info instead.
template<typename T> static uint16_t encode_message_to_buffer(T &msg, APIConnection *conn, uint32_t remaining_size) {
conn->batch_message_type_ = T::MESSAGE_TYPE;
if constexpr (T::ESTIMATED_SIZE == 0) {
return encode_to_buffer_slow_(0, &encode_msg_noop, &msg, conn, remaining_size);
return encode_to_buffer_slow(0, &encode_msg_noop, &msg, conn, remaining_size);
} else {
return encode_to_buffer_slow_(msg.calculate_size(), &proto_encode_msg<T>, &msg, conn, remaining_size);
return encode_to_buffer_slow(msg.calculate_size(), &proto_encode_msg<T>, &msg, conn, remaining_size);
}
}
@@ -302,17 +302,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;
uint16_t total_len = 0;
// First message has max padding (header_size = HEADER_PADDING), may have unused leading bytes.
// Subsequent messages were encoded with exact header sizes (header_size = actual header len).
// write_plaintext_header right-justifies the header within header_size bytes of padding.
for (const auto &msg : messages) {
uint8_t header_len =
write_plaintext_header(buffer_data + msg.offset, msg.payload_size, msg.message_type, msg.header_size);
if (write_start == nullptr)
write_start = buffer_data + msg.offset + msg.header_size - header_len;
const auto &first = messages[0];
uint8_t header_len =
write_plaintext_header(buffer_data + first.offset, first.payload_size, first.message_type, HEADER_PADDING);
uint8_t *write_start = buffer_data + first.offset + HEADER_PADDING - header_len;
uint16_t total_len = header_len + first.payload_size;
for (size_t i = 1; i < messages.size(); i++) {
const auto &msg = messages[i];
header_len = write_plaintext_header(buffer_data + msg.offset, msg.payload_size, msg.message_type, msg.header_size);
total_len += header_len + msg.payload_size;
}