15#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
16#define HAS_PROTO_MESSAGE_DUMP
43 return (
static_cast<uint32_t>(value) << 1) ^ (
static_cast<uint32_t>(value >> 31));
47 return (
static_cast<uint64_t
>(value) << 1) ^ (
static_cast<uint64_t
>(value >> 63));
51 return (value & 1) ?
static_cast<int32_t
>(~(value >> 1)) :
static_cast<int32_t
>(value >> 1);
55 return (value & 1) ?
static_cast<int64_t
>(~(value >> 1)) :
static_cast<int64_t
>(value >> 1);
63 while (
len > 0 && (*data & 0x80)) {
80 *buffer++ =
static_cast<uint8_t
>(
val | 0x80);
83 *buffer =
static_cast<uint8_t
>(
val);
117#ifdef USE_API_VARINT64
141#ifdef ESPHOME_DEBUG_API
146 if ((buffer[0] & 0x80) == 0) [[likely]]
147 return {buffer[0], 1};
163#ifdef USE_API_VARINT64
214#ifdef ESPHOME_DEBUG_API
215#define PROTO_ENCODE_DEBUG_PARAM , uint8_t *proto_debug_end_
216#define PROTO_ENCODE_DEBUG_ARG , proto_debug_end_
217#define PROTO_ENCODE_DEBUG_INIT(buf) , (buf)->data() + (buf)->size()
218#define PROTO_ENCODE_CHECK_BOUNDS(pos, n) \
220 if ((pos) + (n) > proto_debug_end_) \
221 proto_check_bounds_failed(pos, n, proto_debug_end_, __builtin_FUNCTION()); \
225#define PROTO_ENCODE_DEBUG_PARAM
226#define PROTO_ENCODE_DEBUG_ARG
227#define PROTO_ENCODE_DEBUG_INIT(buf)
228#define PROTO_ENCODE_CHECK_BOUNDS(pos, n)
236 if (value < 128) [[likely]] {
238 *this->
pos_++ =
static_cast<uint8_t
>(value);
266 uint8_t *(*encode_fn)(
const void *,
ProtoWriteBuffer &PROTO_ENCODE_DEBUG_PARAM));
269 uint8_t *(*encode_fn)(
const void *,
ProtoWriteBuffer &PROTO_ENCODE_DEBUG_PARAM));
279#ifdef ESPHOME_DEBUG_API
304 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
305 *
pos++ =
static_cast<uint8_t
>(value | 0x80);
307 }
while (value > 0x7F);
308 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
309 *
pos++ =
static_cast<uint8_t
>(value);
311 static inline void ESPHOME_ALWAYS_INLINE
encode_varint_raw(uint8_t *__restrict__ &
pos PROTO_ENCODE_DEBUG_PARAM,
314 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
315 *
pos++ =
static_cast<uint8_t
>(value);
324 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
325 *
pos++ =
static_cast<uint8_t
>(value);
329 PROTO_ENCODE_CHECK_BOUNDS(
pos, 2);
330 *
pos++ =
static_cast<uint8_t
>(value | 0x80);
331 *
pos++ =
static_cast<uint8_t
>(value >> 7);
339 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
340 *
pos++ =
static_cast<uint8_t
>(value);
352#ifdef ESPHOME_DEBUG_API
353 assert(value < (1ULL << (MAC_ADDRESS_SIZE * 8)) &&
"encode_varint_raw_48bit: value exceeds 48 bits");
357 if (value >= (1ULL << (MAC_ADDRESS_SIZE * 8 - 6))) [[likely]] {
358 PROTO_ENCODE_CHECK_BOUNDS(
pos, 7);
359 pos[0] =
static_cast<uint8_t
>(value | 0x80);
360 pos[1] =
static_cast<uint8_t
>((value >> 7) | 0x80);
361 pos[2] =
static_cast<uint8_t
>((value >> 14) | 0x80);
362 pos[3] =
static_cast<uint8_t
>((value >> 21) | 0x80);
363 pos[4] =
static_cast<uint8_t
>((value >> 28) | 0x80);
364 pos[5] =
static_cast<uint8_t
>((value >> 35) | 0x80);
365 pos[6] =
static_cast<uint8_t
>(value >> 42);
371 static inline void ESPHOME_ALWAYS_INLINE
encode_field_raw(uint8_t *__restrict__ &
pos PROTO_ENCODE_DEBUG_PARAM,
376 static inline void ESPHOME_ALWAYS_INLINE
write_raw_byte(uint8_t *__restrict__ &
pos PROTO_ENCODE_DEBUG_PARAM,
378 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
383 static inline void ESPHOME_ALWAYS_INLINE
reserve_byte(uint8_t *__restrict__ &
pos PROTO_ENCODE_DEBUG_PARAM) {
384 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
388 static inline void ESPHOME_ALWAYS_INLINE
encode_raw(uint8_t *__restrict__ &
pos PROTO_ENCODE_DEBUG_PARAM,
389 const void *data,
size_t len) {
390 PROTO_ENCODE_CHECK_BOUNDS(
pos,
len);
391 std::memcpy(
pos, data,
len);
398#ifdef ESPHOME_DEBUG_API
399 assert(ref.
size() < 128 &&
"encode_short_string_force: string exceeds max_data_length < 128");
401 PROTO_ENCODE_CHECK_BOUNDS(
pos, 2 + ref.
size());
403 pos[1] =
static_cast<uint8_t
>(ref.
size());
410 PROTO_ENCODE_CHECK_BOUNDS(
pos, 5);
412#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
413 std::memcpy(
pos + 1, &value, 4);
415 pos[1] =
static_cast<uint8_t
>(value & 0xFF);
416 pos[2] =
static_cast<uint8_t
>((value >> 8) & 0xFF);
417 pos[3] =
static_cast<uint8_t
>((value >> 16) & 0xFF);
418 pos[4] =
static_cast<uint8_t
>((value >> 24) & 0xFF);
423 const char *
string,
size_t len,
bool force =
false) {
424 if (
len == 0 && !force)
429 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1 +
len);
430 *
pos++ =
static_cast<uint8_t
>(
len);
433 PROTO_ENCODE_CHECK_BOUNDS(
pos,
len);
435 std::memcpy(
pos,
string,
len);
439 const std::string &value,
bool force =
false) {
440 encode_string(
pos PROTO_ENCODE_DEBUG_ARG, field_id, value.data(), value.size(), force);
443 const StringRef &ref,
bool force =
false) {
447 const uint8_t *data,
size_t len,
bool force =
false) {
448 encode_string(
pos PROTO_ENCODE_DEBUG_ARG, field_id,
reinterpret_cast<const char *
>(data),
len, force);
451 uint32_t value,
bool force =
false) {
452 if (value == 0 && !force)
458 uint64_t value,
bool force =
false) {
459 if (value == 0 && !force)
465 bool force =
false) {
466 if (!value && !force)
469 PROTO_ENCODE_CHECK_BOUNDS(
pos, 1);
470 *
pos++ = value ? 0x01 : 0x00;
473 uint32_t value,
bool force =
false) {
474 if (value == 0 && !force)
477 PROTO_ENCODE_CHECK_BOUNDS(
pos, 4);
478#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
479 std::memcpy(
pos, &value, 4);
482 *
pos++ = (value >> 0) & 0xFF;
483 *
pos++ = (value >> 8) & 0xFF;
484 *
pos++ = (value >> 16) & 0xFF;
485 *
pos++ = (value >> 24) & 0xFF;
493 bool force =
false) {
495 if (
raw == 0 && !force)
500 bool force =
false) {
503 encode_uint64(
pos PROTO_ENCODE_DEBUG_ARG, field_id,
static_cast<uint64_t
>(value), force);
509 bool force =
false) {
510 encode_uint64(
pos PROTO_ENCODE_DEBUG_ARG, field_id,
static_cast<uint64_t
>(value), force);
513 int32_t value,
bool force =
false) {
517 int64_t value,
bool force =
false) {
523 uint32_t field_id,
const T &value) {
537#ifdef HAS_PROTO_MESSAGE_DUMP
552 append_impl_(str, strlen(str));
558 append_impl_(str,
len);
567 memset(buf_ + pos_, c, n);
580 append_impl_(str, strlen(str));
591 const char *
c_str()
const {
return buf_; }
592 size_t size()
const {
return pos_; }
597 size_t pos()
const {
return pos_; }
609 void append_impl_(
const char *str,
size_t len) {
614 memcpy(buf_ + pos_, str,
len);
634#ifdef HAS_PROTO_MESSAGE_DUMP
636 virtual const LogString *
message_name()
const {
return LOG_STR(
"unknown"); }
683 static constexpr inline uint8_t ESPHOME_ALWAYS_INLINE
varint16(uint16_t value) {
688 static constexpr inline uint8_t ESPHOME_ALWAYS_INLINE
varint8(uint8_t value) {
701 if (__builtin_is_constant_evaluated())
702 return varint_wide(value);
703 return varint_slow(value);
712 if (__builtin_is_constant_evaluated())
713 return varint_wide(value);
714 return varint_slow(value);
721 static constexpr inline uint32_t ESPHOME_ALWAYS_INLINE varint_wide(
uint32_t value) {
740 if (value <= UINT32_MAX) {
745 if (value < (1ULL << 35)) {
747 }
else if (value < (1ULL << 42)) {
749 }
else if (value < (1ULL << 49)) {
751 }
else if (value < (1ULL << 56)) {
753 }
else if (value < (1ULL << 63)) {
789 return varint(
static_cast<uint64_t
>(value));
807 return value ? field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value))) : 0;
810 return field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value)));
813 return value ? field_id_size +
varint(value) : 0;
816 return field_id_size +
varint(value);
821 return float_to_raw(value) != 0 ? field_id_size + 4 : 0;
824 return value ? field_id_size + 4 : 0;
827 return value ? field_id_size + 4 : 0;
836 return value ? field_id_size +
varint(value) : 0;
839 return field_id_size +
varint(value);
842 return value ? field_id_size +
varint(value) : 0;
845 return field_id_size +
varint(value);
853 return field_id_size + (value >= (1ULL << (MAC_ADDRESS_SIZE * 8 - 6)) ? 7 :
varint(value));
868 return value ? field_id_size + 8 : 0;
871 return value ? field_id_size + 8 : 0;
874 return nested_size ? field_id_size +
varint(nested_size) + nested_size : 0;
878 return field_id_size +
varint(nested_size) + nested_size;
886 return static_cast<const T *
>(msg)->encode(buf PROTO_ENCODE_DEBUG_ARG);
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)
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.
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)
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.
Static encode helpers for generated encode() functions.
static void encode_bool(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, bool value, bool force=false)
static void encode_string(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const char *string, size_t len, bool force=false)
static void encode_sint32(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int32_t value, bool force=false)
static void ESPHOME_ALWAYS_INLINE encode_varint_raw_64(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint64_t value)
static void 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 void encode_string(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const StringRef &ref, bool force=false)
static void encode_int64(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int64_t value, bool force=false)
static void 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 void 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 void encode_float(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, float value, bool force=false)
static void 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 void ESPHOME_ALWAYS_INLINE 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 in one operation.
static void encode_optional_sub_message(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, ProtoWriteBuffer &buffer, uint32_t field_id, const T &value)
static void encode_sub_message(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, ProtoWriteBuffer &buffer, uint32_t field_id, const T &value)
Sub-message encoding: sync pos to buffer, delegate, get pos from return value.
static void 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 void 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 void encode_sint64(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int64_t value, bool force=false)
static void 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 void encode_fixed32(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t value, bool force=false)
static void ESPHOME_ALWAYS_INLINE encode_field_raw(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t type)
static void ESPHOME_ALWAYS_INLINE encode_varint_raw(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t value)
static void encode_uint64(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint64_t value, bool force=false)
static void encode_int32(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, int32_t value, bool force=false)
static void encode_bytes(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const uint8_t *data, size_t len, bool force=false)
static void encode_uint32(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t value, bool force=false)
static void encode_string(uint8_t *__restrict__ &pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, const std::string &value, bool force=false)
void decode_to_message(T &msg) const
Decode the length-delimited data into a message instance.
const uint8_t *const value_
const uint8_t * data() const
ProtoLengthDelimited(const uint8_t *value, size_t length)
std::string as_string() const
virtual const LogString * message_name() const
uint8_t * encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const
uint32_t calculate_size() const
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 uint8_t ESPHOME_ALWAYS_INLINE varint8(uint8_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_encode_size_(uint32_t field_id, uint32_t expected, ptrdiff_t actual)
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 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())
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 @65::@66 __attribute__
Wake the main loop task from an ISR. ISR-safe.
constexpr uint32_t encode_zigzag32(int32_t value)
constexpr uint32_t VARINT_MAX_2_BYTE
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.
uint8_t * proto_encode_msg(const void *msg, ProtoWriteBuffer &buf PROTO_ENCODE_DEBUG_PARAM)
const char * proto_enum_to_string(T value)
constexpr uint32_t VARINT_MAX_1_BYTE
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
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.
uint16_t count_packed_varints(const uint8_t *data, size_t len)
Count number of varints in a packed buffer.
void proto_check_bounds_failed(const uint8_t *pos, size_t bytes, const uint8_t *end, const char *caller)
Result of parsing a varint: value + number of bytes consumed.
constexpr bool has_value() const
proto_varint_value_t value