diff --git a/esphome/components/api/proto.cpp b/esphome/components/api/proto.cpp index d659f9587a..9ed8b2bfc9 100644 --- a/esphome/components/api/proto.cpp +++ b/esphome/components/api/proto.cpp @@ -350,7 +350,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) { ProtoVarInt value = *value_res; // Try regular fields first using binary search - if (const FieldMeta *field = find_field_binary(fields, field_count, field_id, 0)) { + if (const FieldMeta *field = find_field_binary(fields, field_count, field_id)) { void *field_addr = base + field->get_offset(); decoded = decode_varint_field(field->get_type(), field_addr, value); } @@ -387,7 +387,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) { ProtoLengthDelimited value(&buffer[i], field_length); // Try regular fields first using binary search - if (const FieldMeta *field = find_field_binary(fields, field_count, field_id, 2)) { + if (const FieldMeta *field = find_field_binary(fields, field_count, field_id)) { void *field_addr = base + field->get_offset(); decoded = decode_length_field(field->get_type(), field_addr, value, field->get_message_type_id()); } @@ -422,7 +422,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) { Proto32Bit value(raw); // Try regular fields first using binary search - if (const FieldMeta *field = find_field_binary(fields, field_count, field_id, 5)) { + if (const FieldMeta *field = find_field_binary(fields, field_count, field_id)) { void *field_addr = base + field->get_offset(); decoded = decode_32bit_field(field->get_type(), field_addr, value); } diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index d9962183c7..7be4782c2f 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -309,7 +309,7 @@ struct RepeatedFieldMeta { }; // Binary search for field lookup - optimized for performance -inline const FieldMeta *find_field_binary(const FieldMeta *fields, uint8_t count, uint8_t field_id, uint8_t wire_type) { +inline const FieldMeta *find_field_binary(const FieldMeta *fields, uint8_t count, uint8_t field_id) { uint8_t left = 0; uint8_t right = count; @@ -322,28 +322,8 @@ inline const FieldMeta *find_field_binary(const FieldMeta *fields, uint8_t count } else if (mid_field > field_id) { right = mid; } else { - // Found field_id, check wire type - if (get_wire_type(fields[mid].get_type()) == wire_type) { - return &fields[mid]; - } - // Field number matches but wire type doesn't - search nearby entries - // (in case there are multiple fields with same number but different types) - - // Search backwards - for (uint8_t k = mid; k > 0 && fields[k - 1].field_num == field_id; k--) { - if (get_wire_type(fields[k - 1].get_type()) == wire_type) { - return &fields[k - 1]; - } - } - - // Search forwards - for (uint8_t k = mid + 1; k < count && fields[k].field_num == field_id; k++) { - if (get_wire_type(fields[k].get_type()) == wire_type) { - return &fields[k]; - } - } - - return nullptr; // Field number found but no matching wire type + // Found field_id + return &fields[mid]; } }