diff --git a/esphome/components/api/proto.cpp b/esphome/components/api/proto.cpp index 3d1dc3fde0..a31c66e6c9 100644 --- a/esphome/components/api/proto.cpp +++ b/esphome/components/api/proto.cpp @@ -16,18 +16,7 @@ void ProtoByteBuffer::grow_(size_t n) { this->capacity_ = n; } -uint32_t ProtoSize::varint_slow_(uint32_t value) { - // value is guaranteed >= 128 here (fast path handled inline) - if (value < 16384) { - return 2; // 14 bits - } else if (value < 2097152) { - return 3; // 21 bits - } else if (value < 268435456) { - return 4; // 28 bits - } else { - return 5; // 32 bits (maximum for uint32_t) - } -} +uint32_t ProtoSize::varint_slow(uint32_t value) { return varint_wide(value); } #ifdef USE_API_VARINT64 optional ProtoVarInt::parse_wide(const uint8_t *buffer, uint32_t len, uint32_t *consumed, diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index bd73243ab5..513c4a7aa0 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -556,21 +556,26 @@ class ProtoSize { static constexpr inline uint32_t ESPHOME_ALWAYS_INLINE varint(uint32_t value) { if (value < 128) return 1; // Fast path: 7 bits, most common case - if (__builtin_is_constant_evaluated()) { - // Compile-time: full cascade for constexpr callers - if (value < 16384) - return 2; - if (value < 2097152) - return 3; - if (value < 268435456) - return 4; - return 5; - } - return varint_slow_(value); + if (__builtin_is_constant_evaluated()) + return varint_wide(value); + return varint_slow(value); } - // Slow path for varint >= 128, outlined to keep fast path small - static uint32_t varint_slow_(uint32_t value) __attribute__((noinline)); + private: + // Slow path for varint >= 128, outlined to keep fast path small + static uint32_t varint_slow(uint32_t value) __attribute__((noinline)); + // Shared cascade for values >= 128 (used by both constexpr and noinline paths) + static constexpr inline uint32_t ESPHOME_ALWAYS_INLINE varint_wide(uint32_t value) { + if (value < 16384) + return 2; + if (value < 2097152) + return 3; + if (value < 268435456) + return 4; + return 5; + } + + public: /** * @brief Calculates the size in bytes needed to encode a uint64_t value as a varint *