14#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
15#define HAS_PROTO_MESSAGE_DUMP
29 return (
static_cast<uint32_t>(value) << 1) ^ (
static_cast<uint32_t>(value >> 31));
33 return (
static_cast<uint64_t
>(value) << 1) ^ (
static_cast<uint64_t
>(value >> 63));
37 return (value & 1) ?
static_cast<int32_t
>(~(value >> 1)) :
static_cast<int32_t
>(value >> 1);
41 return (value & 1) ?
static_cast<int64_t
>(~(value >> 1)) :
static_cast<int64_t
>(value >> 1);
49 while (
len > 0 && (*data & 0x80)) {
66 *buffer++ =
static_cast<uint8_t
>(
val | 0x80);
69 *buffer =
static_cast<uint8_t
>(
val);
103#ifdef USE_API_VARINT64
127#ifdef ESPHOME_DEBUG_API
132 if ((buffer[0] & 0x80) == 0) [[likely]]
133 return {buffer[0], 1};
149#ifdef USE_API_VARINT64
156class ProtoDecodableMessage;
210 if (
value < 128) [[likely]] {
212 *this->
pos_++ =
static_cast<uint8_t
>(
value);
218 while (
value > 0x7F) {
220 *this->
pos_++ =
static_cast<uint8_t
>(
value | 0x80);
224 *this->
pos_++ =
static_cast<uint8_t
>(
value);
248 std::memcpy(this->
pos_,
string, len);
277 *this->
pos_++ = value ? 0x01 : 0x00;
286#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
288 std::memcpy(this->
pos_, &value, 4);
291 *this->
pos_++ = (value >> 0) & 0xFF;
292 *this->
pos_++ = (value >> 8) & 0xFF;
293 *this->
pos_++ = (value >> 16) & 0xFF;
294 *this->
pos_++ = (value >> 24) & 0xFF;
310 this->encode_fixed32(field_id,
val.raw);
330 void encode_packed_sint32(
uint32_t field_id,
const std::vector<int32_t> &values);
349#ifdef ESPHOME_DEBUG_API
360#ifdef HAS_PROTO_MESSAGE_DUMP
375 append_impl_(str, strlen(str));
381 append_impl_(str,
len);
390 memset(buf_ + pos_, c, n);
397 const char *
c_str()
const {
return buf_; }
398 size_t size()
const {
return pos_; }
403 size_t pos()
const {
return pos_; }
415 void append_impl_(
const char *str,
size_t len) {
420 memcpy(buf_ + pos_, str,
len);
440#ifdef HAS_PROTO_MESSAGE_DUMP
457 virtual void decode(
const uint8_t *buffer,
size_t length);
487 if (value < 128) [[likely]]
489 if (__builtin_is_constant_evaluated())
490 return varint_wide(value);
491 return varint_slow(value);
498 static constexpr inline uint32_t ESPHOME_ALWAYS_INLINE varint_wide(
uint32_t value) {
503 if (value < 268435456)
517 if (value <= UINT32_MAX) {
522 if (value < (1ULL << 35)) {
524 }
else if (value < (1ULL << 42)) {
526 }
else if (value < (1ULL << 49)) {
528 }
else if (value < (1ULL << 56)) {
530 }
else if (value < (1ULL << 63)) {
566 return varint(
static_cast<uint64_t
>(value));
584 return value ? field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value))) : 0;
587 return field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value)));
590 return value ? field_id_size +
varint(value) : 0;
593 return field_id_size +
varint(value);
598 return value != 0.0f ? field_id_size + 4 : 0;
601 return value ? field_id_size + 4 : 0;
604 return value ? field_id_size + 4 : 0;
613 return value ? field_id_size +
varint(value) : 0;
616 return field_id_size +
varint(value);
619 return value ? field_id_size +
varint(value) : 0;
622 return field_id_size +
varint(value);
637 return value ? field_id_size + 8 : 0;
640 return value ? field_id_size + 8 : 0;
643 return nested_size ? field_id_size +
varint(nested_size) + nested_size : 0;
646 return field_id_size +
varint(nested_size) + nested_size;
653inline void ProtoWriteBuffer::encode_packed_sint32(
uint32_t field_id,
const std::vector<int32_t> &values) {
658 size_t packed_size = 0;
659 for (
int value : values) {
666 for (
int value : values) {
673 static_cast<const T *
>(msg)->encode(buf);
StringRef is a reference to a string owned by something else.
constexpr const char * c_str() const
constexpr size_type size() const
Byte buffer that skips zero-initialization on resize().
Fixed-size buffer for message dumps - avoids heap allocation.
const char * c_str() const
DumpBuffer & append(size_t n, char c)
size_t pos() const
Get current position for use with buf_append_printf.
static constexpr size_t CAPACITY
DumpBuffer & append(const char *str, size_t len)
DumpBuffer & append(const char *str)
char * data()
Get writable buffer pointer for use with buf_append_printf.
void set_pos(size_t pos)
Update position after buf_append_printf call.
uint32_t as_fixed32() const
int32_t as_sfixed32() const
Proto32Bit(uint32_t value)
virtual bool decode_32bit(uint32_t field_id, Proto32Bit value)
virtual bool decode_varint(uint32_t field_id, proto_varint_value_t value)
virtual void decode(const uint8_t *buffer, size_t length)
~ProtoDecodableMessage()=default
virtual bool decode_length(uint32_t field_id, ProtoLengthDelimited value)
static uint32_t count_repeated_field(const uint8_t *buffer, size_t length, uint32_t target_field_id)
Count occurrences of a repeated field in a protobuf buffer.
void decode_to_message(ProtoDecodableMessage &msg) const
Decode the length-delimited data into an existing ProtoDecodableMessage instance.
const uint8_t *const value_
const uint8_t * data() const
ProtoLengthDelimited(const uint8_t *value, size_t length)
std::string as_string() const
void encode(ProtoWriteBuffer &buffer) const
uint32_t calculate_size() const
virtual const char * message_name() const
virtual const char * dump_to(DumpBuffer &out) const =0
virtual void on_fatal_error()=0
virtual bool is_connection_setup()=0
virtual bool is_authenticated()=0
virtual void read_message(uint32_t msg_size, uint32_t msg_type, const uint8_t *msg_data)=0
bool check_authenticated_()
bool check_connection_setup_()
virtual void on_no_setup_connection()=0
virtual bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type)=0
static constexpr uint32_t calc_uint64(uint32_t field_id_size, uint64_t value)
static constexpr uint32_t calc_sint32_force(uint32_t field_id_size, int32_t value)
static constexpr uint32_t calc_int64(uint32_t field_id_size, int64_t value)
static constexpr uint32_t calc_bool(uint32_t field_id_size, bool value)
static constexpr uint32_t calc_uint64_force(uint32_t field_id_size, uint64_t value)
static constexpr uint32_t calc_message(uint32_t field_id_size, uint32_t nested_size)
static constexpr uint32_t calc_sint32(uint32_t field_id_size, int32_t value)
static constexpr uint32_t calc_sint64_force(uint32_t field_id_size, int64_t value)
static constexpr uint32_t field(uint32_t field_id, uint32_t type)
Calculates the size in bytes needed to encode a field ID and wire type.
static constexpr uint32_t ESPHOME_ALWAYS_INLINE varint(uint32_t value)
Calculates the size in bytes needed to encode a uint32_t value as a varint.
static constexpr uint32_t calc_uint32_force(uint32_t field_id_size, uint32_t value)
static constexpr uint32_t calc_length_force(uint32_t field_id_size, size_t len)
static constexpr uint32_t varint(int32_t value)
Calculates the size in bytes needed to encode an int32_t value as a varint.
static constexpr uint32_t calc_int64_force(uint32_t field_id_size, int64_t value)
static constexpr uint32_t calc_sfixed64(uint32_t field_id_size, int64_t value)
static constexpr uint32_t calc_uint32(uint32_t field_id_size, uint32_t value)
static constexpr uint32_t calc_length(uint32_t field_id_size, size_t len)
static constexpr uint32_t calc_message_force(uint32_t field_id_size, uint32_t nested_size)
static constexpr uint32_t calc_int32(uint32_t field_id_size, int32_t value)
static constexpr uint32_t calc_fixed64(uint32_t field_id_size, uint64_t value)
static constexpr uint32_t varint(int64_t value)
Calculates the size in bytes needed to encode an int64_t value as a varint.
static constexpr uint32_t calc_bool_force(uint32_t field_id_size)
static constexpr uint32_t calc_sfixed32(uint32_t field_id_size, int32_t value)
static constexpr uint32_t varint(uint64_t value)
Calculates the size in bytes needed to encode a uint64_t value as a varint.
static constexpr uint32_t calc_float(uint32_t field_id_size, float value)
static constexpr uint32_t calc_sint64(uint32_t field_id_size, int64_t value)
static constexpr uint32_t calc_int32_force(uint32_t field_id_size, int32_t value)
static constexpr uint32_t calc_fixed32(uint32_t field_id_size, uint32_t value)
Static varint parsing methods for the protobuf wire format.
static ProtoVarIntResult ESPHOME_ALWAYS_INLINE parse_non_empty(const uint8_t *buffer, uint32_t len)
Parse a varint from buffer.
static ProtoVarIntResult parse_wide(const uint8_t *buffer, uint32_t len, uint32_t result32) __attribute__((noinline))
Continue parsing varint bytes 4-9 with 64-bit arithmetic.
static ProtoVarIntResult parse_slow(const uint8_t *buffer, uint32_t len) __attribute__((noinline))
static ProtoVarIntResult ESPHOME_ALWAYS_INLINE parse(const uint8_t *buffer, uint32_t len)
Parse a varint from buffer (safe for empty buffers).
void encode_string(uint32_t field_id, const std::string &value, bool force=false)
void debug_check_encode_size_(uint32_t field_id, uint32_t expected, ptrdiff_t actual)
void debug_check_bounds_(size_t bytes)
void encode_string(uint32_t field_id, const char *string, size_t len, bool force=false)
__attribute__((noinline)) void encode_fixed32(uint32_t field_id
void encode_bool(uint32_t field_id, bool value, bool force=false)
void encode_varint_raw_slow_(uint32_t value) __attribute__((noinline))
void encode_uint64(uint32_t field_id, uint64_t value, bool force=false)
void encode_string(uint32_t field_id, const StringRef &ref, bool force=false)
void encode_uint32(uint32_t field_id, uint32_t value, bool force=false)
void encode_field_raw(uint32_t field_id, uint32_t type)
Encode a field key (tag/wire type combination).
void encode_optional_sub_message(uint32_t field_id, const T &value)
Encode an optional singular submessage field — skips if empty.
void encode_sub_message(uint32_t field_id, const T &value)
Single-pass encode for repeated submessage elements.
void debug_check_bounds_(size_t bytes, const char *caller=__builtin_FUNCTION())
void encode_bytes(uint32_t field_id, const uint8_t *data, size_t len, bool force=false)
APIBuffer * get_buffer() const
void ESPHOME_ALWAYS_INLINE encode_varint_raw(uint32_t value)
ProtoWriteBuffer(APIBuffer *buffer, size_t write_pos)
void encode_varint_raw_64(uint64_t value)
ProtoWriteBuffer(APIBuffer *buffer)
struct @65::@66 __attribute__
void proto_encode_msg(const void *msg, ProtoWriteBuffer &buf)
constexpr uint32_t encode_zigzag32(int32_t value)
constexpr uint8_t WIRE_TYPE_VARINT
uint64_t proto_varint_value_t
Type used for decoded varint values - uint64_t when BLE needs 64-bit addresses, uint32_t otherwise.
const char * proto_enum_to_string(T value)
constexpr uint64_t encode_zigzag64(int64_t value)
constexpr uint8_t WIRE_TYPE_MASK
constexpr uint32_t PROTO_VARINT_PARSE_FAILED
Sentinel value for consumed field indicating parse failure.
constexpr uint8_t WIRE_TYPE_LENGTH_DELIMITED
constexpr int32_t decode_zigzag32(uint32_t value)
constexpr uint8_t WIRE_TYPE_FIXED32
constexpr int64_t decode_zigzag64(uint64_t value)
void encode_varint_to_buffer(uint32_t val, uint8_t *buffer)
Encode a varint directly into a pre-allocated buffer.
uint16_t count_packed_varints(const uint8_t *data, size_t len)
Count number of varints in a packed buffer.
Result of parsing a varint: value + number of bytes consumed.
constexpr bool has_value() const
proto_varint_value_t value