17#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
18#define HAS_PROTO_MESSAGE_DUMP
45 return (
static_cast<uint32_t>(value) << 1) ^ (
static_cast<uint32_t>(value >> 31));
49 return (
static_cast<uint64_t
>(value) << 1) ^ (
static_cast<uint64_t
>(value >> 63));
53 return (value & 1) ?
static_cast<int32_t
>(~(value >> 1)) :
static_cast<int32_t
>(value >> 1);
57 return (value & 1) ?
static_cast<int64_t
>(~(value >> 1)) :
static_cast<int64_t
>(value >> 1);
63 constexpr size_t word_size =
sizeof(Word);
64 constexpr Word lane_ones = ~Word{0} / 0xFF;
65 const uint8_t *
end = data +
len;
66 size_t continuations = 0;
69 if ((
reinterpret_cast<uintptr_t
>(data) & (word_size - 1)) == 0 &&
static_cast<size_t>(
end - data) >= word_size) {
71 memcpy(&word, __builtin_assume_aligned(data, word_size), word_size);
72 continuations += (((word >> 7) & lane_ones) * lane_ones) >> (word_size * 8 - 8);
75 continuations += *data++ >> 7;
78 return static_cast<uint16_t
>(
len - continuations);
85 *
buffer++ =
static_cast<uint8_t
>(
val | 0x80);
122#ifdef USE_API_VARINT64
146#ifdef ESPHOME_DEBUG_API
151 if ((
buffer[0] & 0x80) == 0) [[likely]]
168#ifdef USE_API_VARINT64
193 const uint8_t *
data()
const {
return this->data_; }
194 size_t size()
const {
return static_cast<size_t>(this->scalar_); }
195 std::string
as_string()
const {
return std::string(
reinterpret_cast<const char *
>(this->data_), this->
size()); }
213 const uint8_t *data_;
222#ifdef ESPHOME_DEBUG_API
223#define PROTO_ENCODE_DEBUG_PARAM , uint8_t *proto_debug_end_
224#define PROTO_ENCODE_DEBUG_ARG , proto_debug_end_
225#define PROTO_ENCODE_DEBUG_INIT(buf) , (buf)->data() + (buf)->size()
226#define PROTO_ENCODE_CHECK_BOUNDS(pos, n) \
228 if ((pos) + (n) > proto_debug_end_) \
229 proto_check_bounds_failed(pos, n, proto_debug_end_, __builtin_FUNCTION()); \
238#define PROTO_ENCODE_DEBUG_PARAM
239#define PROTO_ENCODE_DEBUG_ARG
240#define PROTO_ENCODE_DEBUG_INIT(buf)
241#define PROTO_ENCODE_CHECK_BOUNDS(pos, n)
249 if (value < 128) [[likely]] {
251 *this->
pos_++ =
static_cast<uint8_t
>(value);
277#ifdef ESPHOME_DEBUG_API
291#if defined(USE_ESP32) || (defined(__arm__) && !defined(__ARM_FEATURE_UNALIGNED))
292#define PROTO_OUTLINE_FOR_SIZE __attribute__((noinline))
293#define PROTO_FIXED32_BYTE_STORES true
295#define PROTO_OUTLINE_FOR_SIZE inline
296#define PROTO_FIXED32_BYTE_STORES false
304using ProtoEncodeFn = uint8_t *(*)(
const void *, uint8_t *PROTO_ENCODE_DEBUG_PARAM);
316 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
317 *
pos++ =
static_cast<uint8_t
>(value | 0x80);
319 }
while (value > 0x7F);
320 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
321 *
pos++ =
static_cast<uint8_t
>(value);
324 [[nodiscard]]
static inline uint8_t *ESPHOME_ALWAYS_INLINE
327 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
328 *
pos++ =
static_cast<uint8_t
>(value);
334 [[nodiscard]]
static inline uint8_t *ESPHOME_ALWAYS_INLINE
337 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
338 *
pos++ =
static_cast<uint8_t
>(value);
342 PROTO_ENCODE_CHECK_BOUNDS(
pos, 2);
343 *
pos++ =
static_cast<uint8_t
>(value | 0x80);
344 *
pos++ =
static_cast<uint8_t
>(value >> 7);
349 [[nodiscard]]
static inline uint8_t *ESPHOME_ALWAYS_INLINE
352 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
353 *
pos++ =
static_cast<uint8_t
>(value);
363 [[nodiscard]]
static inline uint8_t *ESPHOME_ALWAYS_INLINE
365#ifdef ESPHOME_DEBUG_API
366 assert(value < (1ULL << (MAC_ADDRESS_SIZE * 8)) &&
"encode_varint_raw_48bit: value exceeds 48 bits");
370 if (value >= (1ULL << (MAC_ADDRESS_SIZE * 8 - 6))) [[likely]] {
371 PROTO_ENCODE_CHECK_BOUNDS(
pos, 7);
372 pos[0] =
static_cast<uint8_t
>(value | 0x80);
373 pos[1] =
static_cast<uint8_t
>((value >> 7) | 0x80);
374 pos[2] =
static_cast<uint8_t
>((value >> 14) | 0x80);
375 pos[3] =
static_cast<uint8_t
>((value >> 21) | 0x80);
376 pos[4] =
static_cast<uint8_t
>((value >> 28) | 0x80);
377 pos[5] =
static_cast<uint8_t
>((value >> 35) | 0x80);
378 pos[6] =
static_cast<uint8_t
>(value >> 42);
383 [[nodiscard]]
static inline uint8_t *ESPHOME_ALWAYS_INLINE
388 [[nodiscard]]
static inline uint8_t *ESPHOME_ALWAYS_INLINE
390 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
396 [[nodiscard]]
static inline uint8_t *ESPHOME_ALWAYS_INLINE
398 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
402 [[nodiscard]]
static inline uint8_t *ESPHOME_ALWAYS_INLINE
403 encode_raw(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
const void *data,
size_t len) {
404 PROTO_ENCODE_CHECK_BOUNDS(
pos,
len);
405 std::memcpy(
pos, data,
len);
416#ifdef ESPHOME_DEBUG_API
417 assert(
ref.size() < 128 &&
"encode_short_string_force: string exceeds max_data_length < 128");
419 PROTO_ENCODE_CHECK_BOUNDS(
pos, 2 +
ref.size());
421 pos[1] =
static_cast<uint8_t
>(
ref.size());
422 std::memcpy(
pos + 2,
ref.c_str(),
ref.size());
423 return pos + 2 +
ref.size();
429#ifdef ESPHOME_DEBUG_API
430 assert(
ref.size() < 128 &&
"encode_short_progmem_string_force: string exceeds max_data_length < 128");
432 PROTO_ENCODE_CHECK_BOUNDS(
pos, 2 +
ref.size());
434 pos[1] =
static_cast<uint8_t
>(
ref.size());
436 return pos + 2 +
ref.size();
440 uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM, uint8_t tag,
uint32_t value) {
441 PROTO_ENCODE_CHECK_BOUNDS(
pos, 5);
443 write_fixed32_le(
pos + 1, value);
447 uint32_t field_id,
const char *
string,
size_t len) {
451 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1 +
len);
452 *
pos++ =
static_cast<uint8_t
>(
len);
455 PROTO_ENCODE_CHECK_BOUNDS(
pos,
len);
457 std::memcpy(
pos,
string,
len);
460 [[nodiscard]]
static inline uint8_t *
encode_string(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
461 uint32_t field_id,
const char *
string,
size_t len) {
467 uint32_t field_id,
const std::string &value) {
470 [[nodiscard]]
static inline uint8_t *
encode_string(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
478 [[nodiscard]]
static inline uint8_t *
encode_bytes(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
479 uint32_t field_id,
const uint8_t *data,
size_t len) {
480 return encode_string(
pos PROTO_ENCODE_DEBUG_ARG, field_id,
reinterpret_cast<const char *
>(data),
len);
483 uint32_t field_id,
const uint8_t *data,
size_t len) {
488 uint32_t field_id,
const uint8_t *data,
size_t len) {
494 uint32_t field_id,
const uint8_t *data,
size_t len) {
497 PROTO_ENCODE_CHECK_BOUNDS(
pos,
len);
506 reinterpret_cast<const uint8_t *
>(
ref.progmem_ptr()),
ref.size());
516 reinterpret_cast<const uint8_t *
>(
ref.progmem_ptr()),
ref.size());
526 [[nodiscard]]
static inline uint8_t *
encode_uint32(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
533 uint32_t field_id, uint64_t value) {
537 [[nodiscard]]
static inline uint8_t *
encode_uint64(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
538 uint32_t field_id, uint64_t value) {
546 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
547 *
pos++ = value ? 0x01 : 0x00;
550 [[nodiscard]]
static inline uint8_t *
encode_bool(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
560 PROTO_ENCODE_CHECK_BOUNDS(
pos, 4);
561 write_fixed32_le(
pos, value);
564 [[nodiscard]]
static inline uint8_t *
encode_fixed32(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
574 [[nodiscard]]
static inline uint8_t *
encode_float(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
590 [[nodiscard]]
static inline uint8_t *
encode_int32(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
596 [[nodiscard]]
static inline uint8_t *
encode_int64(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
598 return encode_uint64(
pos PROTO_ENCODE_DEBUG_ARG, field_id,
static_cast<uint64_t
>(value));
604 [[nodiscard]]
static inline uint8_t *
encode_sint32(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
612 [[nodiscard]]
static inline uint8_t *
encode_sint64(uint8_t *__restrict__
pos PROTO_ENCODE_DEBUG_PARAM,
623 uint32_t field_id,
const T &value) {
630 uint32_t field_id,
const T &value) {
631 uint32_t nested_size = T::calc_size_msg(&value);
632 if (nested_size == 0)
635#ifdef ESPHOME_DEBUG_API
648 uint32_t nested_size,
const void *value,
655 static inline void ESPHOME_ALWAYS_INLINE write_fixed32_le(uint8_t *__restrict__
pos,
uint32_t value) {
656 if constexpr (PROTO_FIXED32_BYTE_STORES) {
658 pos[0] =
static_cast<uint8_t
>(value);
659 pos[1] =
static_cast<uint8_t
>(value >> 8);
660 pos[2] =
static_cast<uint8_t
>(value >> 16);
661 pos[3] =
static_cast<uint8_t
>(value >> 24);
664 __builtin_memcpy(
pos, &le, 4);
668#undef PROTO_OUTLINE_FOR_SIZE
669#undef PROTO_FIXED32_BYTE_STORES
671#ifdef HAS_PROTO_MESSAGE_DUMP
686 append_impl_(str, strlen(str));
692 append_impl_(str,
len);
701 memset(buf_ +
pos_, c, n);
714 append_impl_(str, strlen(str));
725 append_impl_(str,
len);
736 const char *
c_str()
const {
return buf_; }
737 size_t size()
const {
return pos_; }
742 size_t pos()
const {
return pos_; }
754 void append_impl_(
const char *str,
size_t len) {
759 memcpy(buf_ + pos_, str,
len);
774 static uint8_t *
encode_msg(
const void *self, uint8_t *
pos PROTO_ENCODE_DEBUG_PARAM) {
return pos; }
778#ifdef HAS_PROTO_MESSAGE_DUMP
780 virtual const LogString *
message_name()
const {
return LOG_STR(
"unknown"); }
818#ifndef HAS_PROTO_MESSAGE_DUMP
820static_assert(!std::is_polymorphic_v<ProtoDecodableMessage>,
"decodable messages carry no vtable");
834 static constexpr inline uint8_t ESPHOME_ALWAYS_INLINE
varint16(uint16_t value) {
847 if (__builtin_is_constant_evaluated())
848 return varint_wide(value);
849 return varint_slow(value);
858 if (__builtin_is_constant_evaluated())
859 return varint_wide(value);
860 return varint_slow(value);
867 static constexpr inline uint32_t ESPHOME_ALWAYS_INLINE varint_wide(
uint32_t value) {
886 if (value <= UINT32_MAX) {
891 if (value < (1ULL << 35)) {
893 }
else if (value < (1ULL << 42)) {
895 }
else if (value < (1ULL << 49)) {
897 }
else if (value < (1ULL << 56)) {
899 }
else if (value < (1ULL << 63)) {
935 return varint(
static_cast<uint64_t
>(value));
953 return value ? field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value))) : 0;
956 return field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value)));
959 return value ? field_id_size +
varint(value) : 0;
962 return field_id_size +
varint(value);
967 return float_to_raw(value) != 0 ? field_id_size + 4 : 0;
970 return value ? field_id_size + 4 : 0;
973 return value ? field_id_size + 4 : 0;
982 return value ? field_id_size +
varint(value) : 0;
985 return field_id_size +
varint(value);
988 return value ? field_id_size +
varint(value) : 0;
991 return field_id_size +
varint(value);
999 return field_id_size + (value >= (1ULL << (MAC_ADDRESS_SIZE * 8 - 6)) ? 7 :
varint(value));
1014 return value ? field_id_size + 8 : 0;
1017 return value ? field_id_size + 8 : 0;
1020 return nested_size ? field_id_size +
varint(nested_size) + nested_size : 0;
1024 return field_id_size +
varint(nested_size) + nested_size;
A string that may live in flash (on ESP8266): pointer and length, with no byte-reading operations.
StringRef is a reference to a string owned by something else.
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)
void append_p_esp8266(const char *str)
Out-of-line ESP8266 PROGMEM append to avoid inlining strlen_P/memcpy_P at every call site.
DumpBuffer & append_p(const char *str)
Append a PROGMEM string (flash-safe on ESP8266, regular append on other platforms)
size_t pos() const
Get current position for use with buf_append_printf.
DumpBuffer & append_p(const char *str, size_t len)
Append len bytes of a PROGMEM string.
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.
static void decode_fields(void *msg, const uint8_t *buffer, size_t length, DecodeFieldFn field)
Walk buffer and hand every field to field.
void(*)(void *msg, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) DecodeFieldFn
Stores one decoded field into msg; generated per message type.
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.
Static encode helpers for the generated encode bodies.
static uint8_t *ESPHOME_ALWAYS_INLINE encode_field_raw(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t type)
static uint8_t * encode_short_string_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint8_t tag, const StringRef &ref)
Encode tag + 1-byte length + raw string data.
static uint8_t * encode_string_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const StringRef &ref)
static uint8_t * encode_int64_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int64_t value)
static uint8_t *ESPHOME_ALWAYS_INLINE encode_varint_raw_48bit(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint64_t value)
Encode a 48-bit MAC address (stored in a uint64) as varint.
static uint8_t * encode_progmem_bytes(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const uint8_t *data, size_t len)
encode_bytes for data in flash (PROGMEM), which ESP8266 can only read with progmem_memcpy.
static uint8_t * encode_int32_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int32_t value)
static uint8_t * encode_string(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const StringRef &ref)
static uint8_t * encode_string_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const std::string &value)
static uint8_t * encode_sint64_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int64_t value)
static uint8_t * encode_sub_message(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const T &value)
Repeated sub-message element; the constant tag is written inline.
static uint8_t * encode_uint32_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t value)
static uint8_t * encode_int32(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int32_t value)
static uint8_t *ESPHOME_ALWAYS_INLINE write_raw_byte(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint8_t b)
Write a single precomputed tag byte. Tag must be < 128.
static uint8_t *ESPHOME_ALWAYS_INLINE encode_varint_raw(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t value)
static PROTO_OUTLINE_FOR_SIZE uint8_t * encode_fixed32_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t value)
Tag + fixed32 for multi-byte tags; single-byte tags use write_tag_and_fixed32.
static uint8_t * encode_sint64(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int64_t value)
static uint8_t * encode_string_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const char *string, size_t len)
static uint8_t * encode_string(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const char *string, size_t len)
static uint8_t * encode_uint32(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t value)
static uint8_t * encode_sint32(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int32_t value)
static uint8_t * encode_fixed32(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t value)
static uint8_t * encode_sized_sub_message_body(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t nested_size, const void *value, ProtoEncodeFn encode_fn)
Length and body for a precomputed size.
static uint8_t * encode_optional_sub_message(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const T &value)
Singular sub-message field, skipped when it encodes to nothing.
static uint8_t *ESPHOME_ALWAYS_INLINE reserve_byte(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM)
Reserve one byte for later backpatch (e.g., sub-message length).
static uint8_t * encode_varint_raw_loop(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, T value)
Write a multi-byte varint directly through a pos pointer.
static uint8_t * encode_sint32_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int32_t value)
static uint8_t * encode_progmem_string_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const ProgmemStringRef &ref)
static uint8_t * encode_short_progmem_string_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint8_t tag, const ProgmemStringRef &ref)
encode_short_string_force for a string that may be in flash (PROGMEM).
static uint8_t * encode_progmem_bytes_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const uint8_t *data, size_t len)
static PROTO_OUTLINE_FOR_SIZE uint8_t * write_tag_and_fixed32(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint8_t tag, uint32_t value)
Write a precomputed tag byte + 32-bit value. Outlined on embedded: one copy beats inline stores per f...
static uint8_t * encode_float_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, float value)
static uint8_t * encode_bool(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, bool value)
static uint8_t * encode_progmem_string(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const ProgmemStringRef &ref)
encode_progmem_bytes for a string field that may be in flash.
static uint8_t * encode_bytes(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const uint8_t *data, size_t len)
static uint8_t *ESPHOME_ALWAYS_INLINE encode_raw(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, const void *data, size_t len)
Write raw bytes to the buffer (no tag, no length prefix).
static uint8_t *ESPHOME_ALWAYS_INLINE encode_varint_raw_short(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t value)
Encode a varint that is expected to be 1-2 bytes (e.g. zigzag RSSI, small lengths).
static uint8_t *ESPHOME_ALWAYS_INLINE encode_varint_raw_64(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint64_t value)
static uint8_t * encode_uint64(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint64_t value)
static uint8_t * encode_uint64_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint64_t value)
static uint8_t * encode_int64(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int64_t value)
static uint8_t * encode_float(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, float value)
static uint8_t * encode_sub_message_body(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, const void *value, ProtoEncodeFn encode_fn)
Length and body, length backpatched after the body is written.
static uint8_t * encode_bytes_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const uint8_t *data, size_t len)
static uint8_t * encode_bool_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, bool value)
One decoded field: the payload pointer and a scalar holding the varint or fixed32 value,...
void decode_to_message(T &msg) const
Decode the length-delimited payload into a message instance.
std::string as_string() const
uint32_t as_fixed32() const
const uint8_t * data() const
ProtoFieldValue(const uint8_t *data, proto_varint_value_t scalar)
proto_varint_value_t as_varint() const
int32_t as_sfixed32() const
virtual const LogString * message_name() const
uint8_t * encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const
uint32_t calculate_size() const
static uint32_t calc_size_msg(const void *self)
static uint8_t * encode_msg(const void *self, uint8_t *pos PROTO_ENCODE_DEBUG_PARAM)
virtual const char * dump_to(DumpBuffer &out) const =0
static constexpr uint32_t calc_uint64(uint32_t field_id_size, uint64_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_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 ESPHOME_ALWAYS_INLINE calc_uint64_force(uint32_t field_id_size, uint64_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 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 ESPHOME_ALWAYS_INLINE calc_uint64_48bit_force(uint32_t field_id_size, uint64_t value)
48-bit MAC address variant: matches encode_varint_raw_48bit's fast path.
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 VARINT_THRESHOLD_3_BYTE
static constexpr uint8_t ESPHOME_ALWAYS_INLINE varint16(uint16_t value)
static constexpr uint32_t calc_length(uint32_t field_id_size, size_t len)
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 ESPHOME_ALWAYS_INLINE varint_short(uint32_t value)
Size of a varint expected to be 1-2 bytes (e.g.
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 ESPHOME_ALWAYS_INLINE calc_length_force(uint32_t field_id_size, size_t len)
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 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 constexpr uint32_t VARINT_THRESHOLD_2_BYTE
static constexpr uint32_t ESPHOME_ALWAYS_INLINE calc_message_force(uint32_t field_id_size, uint32_t nested_size)
static constexpr uint32_t ESPHOME_ALWAYS_INLINE calc_sint32_force(uint32_t field_id_size, int32_t value)
static constexpr uint32_t VARINT_THRESHOLD_1_BYTE
static constexpr uint32_t VARINT_THRESHOLD_4_BYTE
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 set_pos(uint8_t *pos)
void debug_check_bounds_(size_t bytes)
void encode_varint_raw_slow_(uint32_t value) __attribute__((noinline))
void encode_field_raw(uint32_t field_id, uint32_t type)
Encode a field key (tag/wire type combination).
void debug_check_bounds_(size_t bytes, const char *caller=__builtin_FUNCTION())
uint8_t * get_pos() const
APIBuffer * get_buffer() const
void ESPHOME_ALWAYS_INLINE encode_varint_raw(uint32_t value)
ProtoWriteBuffer(APIBuffer *buffer, size_t write_pos)
ProtoWriteBuffer(APIBuffer *buffer)
struct @66::@67 __attribute__
Wake the main loop task from an ISR. ISR-safe.
std::vector< uint8_t > & out
uint16_t count_packed_varints(const uint8_t *data, size_t len)
Count varints in a packed buffer: len minus bytes with the continuation bit, summed a word at a time.
constexpr uint32_t encode_zigzag32(int32_t value)
uint8_t *(*)(const void *, uint8_t *PROTO_ENCODE_DEBUG_PARAM) ProtoEncodeFn
Generated encode body: writes the fields at pos, returns the cursor past them.
constexpr uint32_t VARINT_MAX_2_BYTE
constexpr uint8_t WIRE_TYPE_VARINT
constexpr uint32_t proto_tag(uint32_t field_id, uint32_t wire_type)
Case label for decode_field(): the wire tag of a field, so a field that arrives with another wire typ...
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)
void proto_check_encode_end(const uint8_t *end, const uint8_t *expected)
Aborts unless an encode body ended exactly where calculate_size() promised.
constexpr uint32_t VARINT_MAX_1_BYTE
constexpr uint64_t encode_zigzag64(int64_t value)
void proto_check_sub_message_size(uint32_t field_id, uint32_t expected, const uint8_t *len_pos, const uint8_t *end)
Aborts unless a sized sub-message (length prefix at len_pos) ended where its calculated size said.
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
uint32_t float_to_raw(float value)
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.
void proto_check_bounds_failed(const uint8_t *pos, size_t bytes, const uint8_t *end, const char *caller)
void progmem_memcpy(void *dst, const void *src, size_t len)
constexpr T convert_little_endian(T val)
Convert a value between host byte order and little endian (least significant byte first) order.
Result of parsing a varint: value + number of bytes consumed.
constexpr bool has_value() const
proto_varint_value_t value