13#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
14#define HAS_PROTO_MESSAGE_DUMP
28 return (
static_cast<uint32_t
>(value) << 1) ^ (
static_cast<uint32_t
>(value >> 31));
32 return (
static_cast<uint64_t
>(value) << 1) ^ (
static_cast<uint64_t
>(value >> 63));
36 return (value & 1) ?
static_cast<int32_t
>(~(value >> 1)) :
static_cast<int32_t
>(value >> 1);
40 return (value & 1) ?
static_cast<int64_t
>(~(value >> 1)) :
static_cast<int64_t
>(value >> 1);
48 while (
len > 0 && (*data & 0x80)) {
65 *buffer++ =
static_cast<uint8_t
>(
val | 0x80);
68 *buffer =
static_cast<uint8_t
>(
val);
109#ifdef ESPHOME_DEBUG_API
110 assert(consumed !=
nullptr);
116 if ((buffer[0] & 0x80) == 0) {
125 uint32_t result32 = buffer[0] & 0x7F;
126#ifdef USE_API_VARINT64
127 uint32_t limit = std::min(
len, uint32_t(4));
129 uint32_t limit = std::min(
len, uint32_t(5));
131 for (uint32_t i = 1; i < limit; i++) {
132 uint8_t
val = buffer[i];
133 result32 |= uint32_t(
val & 0x7F) << (i * 7);
134 if ((
val & 0x80) == 0) {
140#ifdef USE_API_VARINT64
147#ifdef USE_API_VARINT64
162 return static_cast<int32_t
>(this->
value_);
168#ifdef USE_API_VARINT64
172 return static_cast<int64_t
>(this->
value_);
181#ifdef USE_API_VARINT64
242 :
buffer_(buffer),
pos_(buffer->data() + write_pos) {}
244 while (
value > 0x7F) {
246 *this->
pos_++ =
static_cast<uint8_t
>(
value | 0x80);
250 *this->
pos_++ =
static_cast<uint8_t
>(
value);
253 while (
value > 0x7F) {
255 *this->
pos_++ =
static_cast<uint8_t
>(
value | 0x80);
259 *this->
pos_++ =
static_cast<uint8_t
>(
value);
283 std::memcpy(this->
pos_,
string, len);
312 *this->
pos_++ = value ? 0x01 : 0x00;
321#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
323 std::memcpy(this->
pos_, &value, 4);
326 *this->
pos_++ = (value >> 0) & 0xFF;
327 *this->
pos_++ = (value >> 8) & 0xFF;
328 *this->
pos_++ = (value >> 16) & 0xFF;
329 *this->
pos_++ = (value >> 24) & 0xFF;
336 void encode_float(uint32_t field_id,
float value,
bool force =
false) {
345 this->encode_fixed32(field_id,
val.raw);
347 void encode_int32(uint32_t field_id, int32_t
value,
bool force =
false) {
355 void encode_int64(uint32_t field_id, int64_t
value,
bool force =
false) {
358 void encode_sint32(uint32_t field_id, int32_t
value,
bool force =
false) {
361 void encode_sint64(uint32_t field_id, int64_t
value,
bool force =
false) {
365 void encode_packed_sint32(uint32_t field_id,
const std::vector<int32_t> &values);
371#ifdef ESPHOME_DEBUG_API
382#ifdef HAS_PROTO_MESSAGE_DUMP
397 append_impl_(str, strlen(str));
403 append_impl_(str,
len);
412 memset(buf_ + pos_, c, n);
419 const char *
c_str()
const {
return buf_; }
420 size_t size()
const {
return pos_; }
425 size_t pos()
const {
return pos_; }
437 void append_impl_(
const char *str,
size_t len) {
442 memcpy(buf_ + pos_, str,
len);
461#ifdef HAS_PROTO_MESSAGE_DUMP
475 virtual void decode(
const uint8_t *buffer,
size_t length);
498 uint32_t total_size_ = 0;
529 static constexpr uint32_t
varint(uint32_t value) {
538 }
else if (value < 2097152) {
540 }
else if (value < 268435456) {
553 static constexpr uint32_t
varint(uint64_t value) {
555 if (value <= UINT32_MAX) {
556 return varint(
static_cast<uint32_t
>(value));
560 if (value < (1ULL << 35)) {
562 }
else if (value < (1ULL << 42)) {
564 }
else if (value < (1ULL << 49)) {
566 }
else if (value < (1ULL << 56)) {
568 }
else if (value < (1ULL << 63)) {
584 static constexpr uint32_t
varint(int32_t value) {
591 return varint(
static_cast<uint32_t
>(value));
600 static constexpr uint32_t
varint(int64_t value) {
604 return varint(
static_cast<uint64_t
>(value));
614 static constexpr uint32_t
field(uint32_t field_id, uint32_t
type) {
636 inline void add_int32(uint32_t field_id_size, int32_t value) {
648 total_size_ += field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value)));
654 inline void add_uint32(uint32_t field_id_size, uint32_t value) {
665 total_size_ += field_id_size +
varint(value);
671 inline void add_bool(uint32_t field_id_size,
bool value) {
674 total_size_ += field_id_size + 1;
684 total_size_ += field_id_size + 1;
690 inline void add_float(uint32_t field_id_size,
float value) {
692 total_size_ += field_id_size + 4;
704 total_size_ += field_id_size + 4;
716 total_size_ += field_id_size + 4;
728 inline void add_sint32(uint32_t field_id_size, int32_t value) {
748 inline void add_int64(uint32_t field_id_size, int64_t value) {
759 total_size_ += field_id_size +
varint(value);
765 inline void add_uint64(uint32_t field_id_size, uint64_t value) {
776 total_size_ += field_id_size +
varint(value);
798 total_size_ += field_id_size +
varint(
static_cast<uint32_t
>(
len)) +
static_cast<uint32_t
>(
len);
820 if (nested_size != 0) {
833 total_size_ += field_id_size +
varint(nested_size) + nested_size;
848 message.calculate_size(nested_calc);
849 uint32_t nested_size = nested_calc.
get_size();
863 message.calculate_size(nested_calc);
864 uint32_t nested_size = nested_calc.
get_size();
879 template<
typename MessageType>
882 if (!messages.empty()) {
884 for (
const auto &
message : messages) {
897 template<
typename MessageType>
900 if (!messages.
empty()) {
902 for (
const auto &
message : messages) {
915 size_t packed_size = 0;
916 for (
int value : values) {
921 total_size_ += field_id_size +
varint(
static_cast<uint32_t
>(packed_size)) +
static_cast<uint32_t
>(packed_size);
930 return size.get_size();
934inline void ProtoWriteBuffer::encode_packed_sint32(uint32_t field_id,
const std::vector<int32_t> &values) {
939 size_t packed_size = 0;
940 for (
int value : values) {
947 for (
int value : values) {
956 value.calculate_size(msg_size);
957 uint32_t msg_length_bytes = msg_size.
get_size();
961 if (msg_length_bytes == 0 && !
force)
970#ifdef ESPHOME_DEBUG_API
971 uint8_t *start = this->
pos_;
973 if (
static_cast<uint32_t
>(this->pos_ - start) != msg_length_bytes)
995 virtual void read_message(uint32_t msg_size, uint32_t msg_type,
const uint8_t *msg_data) = 0;
Fixed-capacity vector - allocates once at runtime, never reallocates This avoids std::vector template...
StringRef is a reference to a string owned by something else.
constexpr const char * c_str() const
constexpr size_type size() const
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, ProtoVarInt 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
uint32_t calculated_size() const
virtual const char * message_name() const
virtual void calculate_size(ProtoSize &size) const
virtual void encode(ProtoWriteBuffer &buffer) const
virtual const char * dump_to(DumpBuffer &out) const =0
virtual void on_fatal_error()=0
virtual bool send_message_impl(const ProtoMessage &msg, uint8_t message_type)=0
Send a protobuf message by calculating its size, allocating a buffer, encoding, and sending.
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
void add_message_object(uint32_t field_id_size, const ProtoMessage &message)
Calculates and adds the size of a nested message field to the total message size.
static constexpr uint32_t varint(uint32_t value)
Calculates the size in bytes needed to encode a uint32_t value as a varint.
void add_message_field_force(uint32_t field_id_size, uint32_t nested_size)
Calculates and adds the size of a nested message field to the total message size (force version)
void add_message_object_force(uint32_t field_id_size, const ProtoMessage &message)
Calculates and adds the size of a nested message field to the total message size (force version)
void add_float(uint32_t field_id_size, float value)
Calculates and adds the size of a float field to the total message size.
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 varint(int32_t value)
Calculates the size in bytes needed to encode an int32_t value as a varint.
void add_sfixed32(uint32_t field_id_size, int32_t value)
Calculates and adds the size of a sfixed32 field to the total message size.
void add_uint32_force(uint32_t field_id_size, uint32_t value)
Calculates and adds the size of a uint32 field to the total message size (force version)
void add_int32_force(uint32_t field_id_size, int32_t value)
Calculates and adds the size of an int32 field to the total message size (force version)
void add_repeated_message(uint32_t field_id_size, const FixedVector< MessageType > &messages)
Calculates and adds the sizes of all messages in a repeated field to the total message size (FixedVec...
static constexpr uint32_t varint(int64_t value)
Calculates the size in bytes needed to encode an int64_t value as a varint.
void add_int64_force(uint32_t field_id_size, int64_t value)
Calculates and adds the size of an int64 field to the total message size (force version)
void add_sint32(uint32_t field_id_size, int32_t value)
Calculates and adds the size of a sint32 field to the total message size.
void add_message_field(uint32_t field_id_size, uint32_t nested_size)
Calculates and adds the size of a nested message field to the total message size.
void add_bool_force(uint32_t field_id_size, bool value)
Calculates and adds the size of a boolean field to the total message size (force version)
void add_int64(uint32_t field_id_size, int64_t value)
Calculates and adds the size of an int64 field to the total message size.
void add_bool(uint32_t field_id_size, bool value)
Calculates and adds the size of a boolean field to the total message size.
uint32_t get_size() const
void add_uint32(uint32_t field_id_size, uint32_t value)
Calculates and adds the size of a uint32 field to the total message size.
static constexpr uint32_t varint(uint64_t value)
Calculates the size in bytes needed to encode a uint64_t value as a varint.
void add_repeated_message(uint32_t field_id_size, const std::vector< MessageType > &messages)
Calculates and adds the sizes of all messages in a repeated field to the total message size.
void add_uint64(uint32_t field_id_size, uint64_t value)
Calculates and adds the size of a uint64 field to the total message size.
void add_length_force(uint32_t field_id_size, size_t len)
Calculates and adds the size of a length-delimited field (string/bytes) to the total message size (re...
void add_int32(uint32_t field_id_size, int32_t value)
Common parameters for all add_*_field methods.
void add_precalculated_size(uint32_t size)
Adds a pre-calculated size directly to the total.
void add_sint32_force(uint32_t field_id_size, int32_t value)
Calculates and adds the size of a sint32 field to the total message size (force version)
void add_uint64_force(uint32_t field_id_size, uint64_t value)
Calculates and adds the size of a uint64 field to the total message size (force version)
void add_fixed32(uint32_t field_id_size, uint32_t value)
Calculates and adds the size of a fixed32 field to the total message size.
ProtoSize()=default
ProtoSize class for Protocol Buffer serialization size calculation.
void add_packed_sint32(uint32_t field_id_size, const std::vector< int32_t > &values)
Calculate size of a packed repeated sint32 field.
void add_length(uint32_t field_id_size, size_t len)
Calculates and adds the size of a length-delimited field (string/bytes) to the total message size.
Representation of a VarInt - in ProtoBuf should be 64bit but we only use 32bit.
constexpr uint16_t as_uint16() const
constexpr uint64_t as_uint64() const
constexpr int32_t as_int32() const
constexpr uint32_t as_uint32() const
static optional< ProtoVarInt > parse_wide(const uint8_t *buffer, uint32_t len, uint32_t *consumed, uint32_t result32) __attribute__((noinline))
Continue parsing varint bytes 4-9 with 64-bit arithmetic.
constexpr int64_t as_int64() const
constexpr bool as_bool() const
ProtoVarInt(uint64_t value)
constexpr int32_t as_sint32() const
constexpr int64_t as_sint64() const
static optional< ProtoVarInt > parse(const uint8_t *buffer, uint32_t len, uint32_t *consumed)
Parse a varint from buffer. consumed must be a valid pointer (not null).
void encode_varint_raw(uint32_t value)
void encode_string(uint32_t field_id, const std::string &value, bool force=false)
ProtoWriteBuffer(std::vector< uint8_t > *buffer, size_t write_pos)
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)
ProtoWriteBuffer(std::vector< uint8_t > *buffer)
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).
std::vector< uint8_t > * get_buffer() const
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)
void encode_message(uint32_t field_id, const ProtoMessage &value, bool force=true)
Encode a nested message field (force=true for repeated, false for singular)
std::vector< uint8_t > * buffer_
void encode_varint_raw_64(uint64_t value)
struct @65::@66 __attribute__
constexpr uint32_t encode_zigzag32(int32_t value)
constexpr uint8_t WIRE_TYPE_VARINT
const char * proto_enum_to_string(T value)
constexpr uint64_t encode_zigzag64(int64_t value)
constexpr uint8_t WIRE_TYPE_MASK
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.