8static const char *
const TAG =
"api.proto";
10#ifdef USE_API_VARINT64
13 uint64_t result64 = result32;
14 uint32_t limit = std::min(
len, uint32_t(10));
15 for (uint32_t i = 4; i < limit; i++) {
16 uint8_t
val = buffer[i];
17 result64 |= uint64_t(
val & 0x7F) << (i * 7);
18 if ((
val & 0x80) == 0) {
29 const uint8_t *ptr = buffer;
37 if (!res.has_value()) {
41 uint32_t tag = res->as_uint32();
43 uint32_t field_id = tag >> 3;
47 if (field_id == target_field_id) {
55 if (!res.has_value()) {
63 if (!res.has_value()) {
66 uint32_t field_length = res->as_uint32();
68 if (field_length >
static_cast<size_t>(
end - ptr)) {
90#ifdef ESPHOME_DEBUG_API
92 if (this->
pos_ + bytes > this->
buffer_->data() + this->buffer_->size()) {
93 ESP_LOGE(TAG,
"ProtoWriteBuffer bounds check failed in %s: bytes=%zu offset=%td buf_size=%zu", caller, bytes,
94 this->
pos_ - this->
buffer_->data(), this->buffer_->size());
99 ESP_LOGE(TAG,
"encode_message: size mismatch for field %" PRIu32
": calculated=%" PRIu32
" actual=%td", field_id,
106 const uint8_t *ptr = buffer;
114 if (!res.has_value()) {
115 ESP_LOGV(TAG,
"Invalid field start at offset %ld", (
long) (ptr - buffer));
119 uint32_t tag = res->as_uint32();
121 uint32_t field_id = tag >> 3;
124 switch (field_type) {
127 if (!res.has_value()) {
128 ESP_LOGV(TAG,
"Invalid VarInt at offset %ld", (
long) (ptr - buffer));
132 ESP_LOGV(TAG,
"Cannot decode VarInt field %" PRIu32
" with value %" PRIu32
"!", field_id, res->as_uint32());
139 if (!res.has_value()) {
140 ESP_LOGV(TAG,
"Invalid Length Delimited at offset %ld", (
long) (ptr - buffer));
143 uint32_t field_length = res->as_uint32();
145 if (field_length >
static_cast<size_t>(
end - ptr)) {
146 ESP_LOGV(TAG,
"Out-of-bounds Length Delimited at offset %ld", (
long) (ptr - buffer));
150 ESP_LOGV(TAG,
"Cannot decode Length Delimited field %" PRIu32
"!", field_id);
157 ESP_LOGV(TAG,
"Out-of-bounds Fixed32-bit at offset %ld", (
long) (ptr - buffer));
162 ESP_LOGV(TAG,
"Cannot decode 32-bit field %" PRIu32
" with value %" PRIu32
"!", field_id,
val);
168 ESP_LOGV(TAG,
"Invalid field type %" PRIu32
" at offset %ld", field_type, (
long) (ptr - buffer));
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)
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.
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.
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 debug_check_encode_size_(uint32_t field_id, uint32_t expected, ptrdiff_t actual)
void debug_check_bounds_(size_t bytes, const char *caller=__builtin_FUNCTION())
std::vector< uint8_t > * buffer_
constexpr uint8_t WIRE_TYPE_VARINT
constexpr uint8_t WIRE_TYPE_MASK
constexpr uint8_t WIRE_TYPE_LENGTH_DELIMITED
constexpr uint8_t WIRE_TYPE_FIXED32
constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4)
Encode a 32-bit value given four bytes in most to least significant byte order.