ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
proto.h
Go to the documentation of this file.
1#pragma once
2
5#include "esphome/core/log.h"
7
8#include <cassert>
9#include <cstring>
10#include <vector>
11
12#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
13#define HAS_PROTO_MESSAGE_DUMP
14#endif
15
16namespace esphome::api {
17
18// Helper functions for ZigZag encoding/decoding
19inline constexpr uint32_t encode_zigzag32(int32_t value) {
20 return (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
21}
22
23inline constexpr uint64_t encode_zigzag64(int64_t value) {
24 return (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
25}
26
27inline constexpr int32_t decode_zigzag32(uint32_t value) {
28 return (value & 1) ? static_cast<int32_t>(~(value >> 1)) : static_cast<int32_t>(value >> 1);
29}
30
31inline constexpr int64_t decode_zigzag64(uint64_t value) {
32 return (value & 1) ? static_cast<int64_t>(~(value >> 1)) : static_cast<int64_t>(value >> 1);
33}
34
35/*
36 * StringRef Ownership Model for API Protocol Messages
37 * ===================================================
38 *
39 * StringRef is used for zero-copy string handling in outgoing (SOURCE_SERVER) messages.
40 * It holds a pointer and length to existing string data without copying.
41 *
42 * CRITICAL: The referenced string data MUST remain valid until message encoding completes.
43 *
44 * Safe StringRef Patterns:
45 * 1. String literals: StringRef("literal") - Always safe (static storage duration)
46 * 2. Member variables: StringRef(this->member_string_) - Safe if object outlives encoding
47 * 3. Global/static strings: StringRef(GLOBAL_CONSTANT) - Always safe
48 * 4. Local variables: Safe ONLY if encoding happens before function returns:
49 * std::string temp = compute_value();
50 * msg.set_field(StringRef(temp));
51 * return this->send_message(msg); // temp is valid during encoding
52 *
53 * Unsafe Patterns (WILL cause crashes/corruption):
54 * 1. Temporaries: msg.set_field(StringRef(obj.get_string())) // get_string() returns by value
55 * 2. Concatenation: msg.set_field(StringRef(str1 + str2)) // Result is temporary
56 *
57 * For unsafe patterns, store in a local variable first:
58 * std::string temp = get_string(); // or str1 + str2
59 * msg.set_field(StringRef(temp));
60 *
61 * The send_*_response pattern ensures proper lifetime management by encoding
62 * within the same function scope where temporaries are created.
63 */
64
67 public:
69 explicit ProtoVarInt(uint64_t value) : value_(value) {}
70
71 static optional<ProtoVarInt> parse(const uint8_t *buffer, uint32_t len, uint32_t *consumed) {
72 if (len == 0) {
73 if (consumed != nullptr)
74 *consumed = 0;
75 return {};
76 }
77
78 // Most common case: single-byte varint (values 0-127)
79 if ((buffer[0] & 0x80) == 0) {
80 if (consumed != nullptr)
81 *consumed = 1;
82 return ProtoVarInt(buffer[0]);
83 }
84
85 // General case for multi-byte varints
86 // Since we know buffer[0]'s high bit is set, initialize with its value
87 uint64_t result = buffer[0] & 0x7F;
88 uint8_t bitpos = 7;
89
90 // Start from the second byte since we've already processed the first
91 for (uint32_t i = 1; i < len; i++) {
92 uint8_t val = buffer[i];
93 result |= uint64_t(val & 0x7F) << uint64_t(bitpos);
94 bitpos += 7;
95 if ((val & 0x80) == 0) {
96 if (consumed != nullptr)
97 *consumed = i + 1;
98 return ProtoVarInt(result);
99 }
100 }
101
102 if (consumed != nullptr)
103 *consumed = 0;
104 return {}; // Incomplete or invalid varint
105 }
106
107 constexpr uint16_t as_uint16() const { return this->value_; }
108 constexpr uint32_t as_uint32() const { return this->value_; }
109 constexpr uint64_t as_uint64() const { return this->value_; }
110 constexpr bool as_bool() const { return this->value_; }
111 constexpr int32_t as_int32() const {
112 // Not ZigZag encoded
113 return static_cast<int32_t>(this->as_int64());
114 }
115 constexpr int64_t as_int64() const {
116 // Not ZigZag encoded
117 return static_cast<int64_t>(this->value_);
118 }
119 constexpr int32_t as_sint32() const {
120 // with ZigZag encoding
121 return decode_zigzag32(static_cast<uint32_t>(this->value_));
122 }
123 constexpr int64_t as_sint64() const {
124 // with ZigZag encoding
125 return decode_zigzag64(this->value_);
126 }
138 void encode_to_buffer_unchecked(uint8_t *buffer, size_t len) {
139 uint64_t val = this->value_;
140 if (val <= 0x7F) {
141 buffer[0] = val;
142 return;
143 }
144 size_t i = 0;
145 while (val && i < len) {
146 uint8_t temp = val & 0x7F;
147 val >>= 7;
148 if (val) {
149 buffer[i++] = temp | 0x80;
150 } else {
151 buffer[i++] = temp;
152 }
153 }
154 }
155 void encode(std::vector<uint8_t> &out) {
156 uint64_t val = this->value_;
157 if (val <= 0x7F) {
158 out.push_back(val);
159 return;
160 }
161 while (val) {
162 uint8_t temp = val & 0x7F;
163 val >>= 7;
164 if (val) {
165 out.push_back(temp | 0x80);
166 } else {
167 out.push_back(temp);
168 }
169 }
170 }
171
172 protected:
173 uint64_t value_;
174};
175
176// Forward declaration for decode_to_message and encode_to_writer
177class ProtoMessage;
179
181 public:
182 explicit ProtoLengthDelimited(const uint8_t *value, size_t length) : value_(value), length_(length) {}
183 std::string as_string() const { return std::string(reinterpret_cast<const char *>(this->value_), this->length_); }
184
195
196 protected:
197 const uint8_t *const value_;
198 const size_t length_;
199};
200
202 public:
203 explicit Proto32Bit(uint32_t value) : value_(value) {}
204 uint32_t as_fixed32() const { return this->value_; }
205 int32_t as_sfixed32() const { return static_cast<int32_t>(this->value_); }
206 float as_float() const {
207 union {
208 uint32_t raw;
209 float value;
210 } s{};
211 s.raw = this->value_;
212 return s.value;
213 }
214
215 protected:
216 const uint32_t value_;
217};
218
219// NOTE: Proto64Bit class removed - wire type 1 (64-bit fixed) not supported
220
222 public:
223 ProtoWriteBuffer(std::vector<uint8_t> *buffer) : buffer_(buffer) {}
224 void write(uint8_t value) { this->buffer_->push_back(value); }
225 void encode_varint_raw(ProtoVarInt value) { value.encode(*this->buffer_); }
226 void encode_varint_raw(uint32_t value) { this->encode_varint_raw(ProtoVarInt(value)); }
239 void encode_field_raw(uint32_t field_id, uint32_t type) {
240 uint32_t val = (field_id << 3) | (type & 0b111);
241 this->encode_varint_raw(val);
242 }
243 void encode_string(uint32_t field_id, const char *string, size_t len, bool force = false) {
244 if (len == 0 && !force)
245 return;
246
247 this->encode_field_raw(field_id, 2); // type 2: Length-delimited string
248 this->encode_varint_raw(len);
249
250 // Using resize + memcpy instead of insert provides significant performance improvement:
251 // ~10-11x faster for 16-32 byte strings, ~3x faster for 64-byte strings
252 // as it avoids iterator checks and potential element moves that insert performs
253 size_t old_size = this->buffer_->size();
254 this->buffer_->resize(old_size + len);
255 std::memcpy(this->buffer_->data() + old_size, string, len);
256 }
257 void encode_string(uint32_t field_id, const std::string &value, bool force = false) {
258 this->encode_string(field_id, value.data(), value.size(), force);
259 }
260 void encode_string(uint32_t field_id, const StringRef &ref, bool force = false) {
261 this->encode_string(field_id, ref.c_str(), ref.size(), force);
262 }
263 void encode_bytes(uint32_t field_id, const uint8_t *data, size_t len, bool force = false) {
264 this->encode_string(field_id, reinterpret_cast<const char *>(data), len, force);
265 }
266 void encode_uint32(uint32_t field_id, uint32_t value, bool force = false) {
267 if (value == 0 && !force)
268 return;
269 this->encode_field_raw(field_id, 0); // type 0: Varint - uint32
270 this->encode_varint_raw(value);
271 }
272 void encode_uint64(uint32_t field_id, uint64_t value, bool force = false) {
273 if (value == 0 && !force)
274 return;
275 this->encode_field_raw(field_id, 0); // type 0: Varint - uint64
276 this->encode_varint_raw(ProtoVarInt(value));
277 }
278 void encode_bool(uint32_t field_id, bool value, bool force = false) {
279 if (!value && !force)
280 return;
281 this->encode_field_raw(field_id, 0); // type 0: Varint - bool
282 this->write(0x01);
283 }
284 void encode_fixed32(uint32_t field_id, uint32_t value, bool force = false) {
285 if (value == 0 && !force)
286 return;
287
288 this->encode_field_raw(field_id, 5); // type 5: 32-bit fixed32
289 this->write((value >> 0) & 0xFF);
290 this->write((value >> 8) & 0xFF);
291 this->write((value >> 16) & 0xFF);
292 this->write((value >> 24) & 0xFF);
293 }
294 // NOTE: Wire type 1 (64-bit fixed: double, fixed64, sfixed64) is intentionally
295 // not supported to reduce overhead on embedded systems. All ESPHome devices are
296 // 32-bit microcontrollers where 64-bit operations are expensive. If 64-bit support
297 // is needed in the future, the necessary encoding/decoding functions must be added.
298 void encode_float(uint32_t field_id, float value, bool force = false) {
299 if (value == 0.0f && !force)
300 return;
301
302 union {
303 float value;
304 uint32_t raw;
305 } val{};
306 val.value = value;
307 this->encode_fixed32(field_id, val.raw);
308 }
309 void encode_int32(uint32_t field_id, int32_t value, bool force = false) {
310 if (value < 0) {
311 // negative int32 is always 10 byte long
312 this->encode_int64(field_id, value, force);
313 return;
314 }
315 this->encode_uint32(field_id, static_cast<uint32_t>(value), force);
316 }
317 void encode_int64(uint32_t field_id, int64_t value, bool force = false) {
318 this->encode_uint64(field_id, static_cast<uint64_t>(value), force);
319 }
320 void encode_sint32(uint32_t field_id, int32_t value, bool force = false) {
321 this->encode_uint32(field_id, encode_zigzag32(value), force);
322 }
323 void encode_sint64(uint32_t field_id, int64_t value, bool force = false) {
324 this->encode_uint64(field_id, encode_zigzag64(value), force);
325 }
326 void encode_message(uint32_t field_id, const ProtoMessage &value, bool force = false);
327 std::vector<uint8_t> *get_buffer() const { return buffer_; }
328
329 protected:
330 std::vector<uint8_t> *buffer_;
331};
332
333// Forward declaration
334class ProtoSize;
335
337 public:
338 virtual ~ProtoMessage() = default;
339 // Default implementation for messages with no fields
340 virtual void encode(ProtoWriteBuffer buffer) const {}
341 // Default implementation for messages with no fields
342 virtual void calculate_size(ProtoSize &size) const {}
343#ifdef HAS_PROTO_MESSAGE_DUMP
344 std::string dump() const;
345 virtual void dump_to(std::string &out) const = 0;
346 virtual const char *message_name() const { return "unknown"; }
347#endif
348};
349
350// Base class for messages that support decoding
352 public:
353 void decode(const uint8_t *buffer, size_t length);
354
355 protected:
356 virtual bool decode_varint(uint32_t field_id, ProtoVarInt value) { return false; }
357 virtual bool decode_length(uint32_t field_id, ProtoLengthDelimited value) { return false; }
358 virtual bool decode_32bit(uint32_t field_id, Proto32Bit value) { return false; }
359 // NOTE: decode_64bit removed - wire type 1 not supported
360};
361
363 private:
364 uint32_t total_size_ = 0;
365
366 public:
385 ProtoSize() = default;
386
387 uint32_t get_size() const { return total_size_; }
388
395 static constexpr uint32_t varint(uint32_t value) {
396 // Optimized varint size calculation using leading zeros
397 // Each 7 bits requires one byte in the varint encoding
398 if (value < 128)
399 return 1; // 7 bits, common case for small values
400
401 // For larger values, count bytes needed based on the position of the highest bit set
402 if (value < 16384) {
403 return 2; // 14 bits
404 } else if (value < 2097152) {
405 return 3; // 21 bits
406 } else if (value < 268435456) {
407 return 4; // 28 bits
408 } else {
409 return 5; // 32 bits (maximum for uint32_t)
410 }
411 }
412
419 static constexpr uint32_t varint(uint64_t value) {
420 // Handle common case of values fitting in uint32_t (vast majority of use cases)
421 if (value <= UINT32_MAX) {
422 return varint(static_cast<uint32_t>(value));
423 }
424
425 // For larger values, determine size based on highest bit position
426 if (value < (1ULL << 35)) {
427 return 5; // 35 bits
428 } else if (value < (1ULL << 42)) {
429 return 6; // 42 bits
430 } else if (value < (1ULL << 49)) {
431 return 7; // 49 bits
432 } else if (value < (1ULL << 56)) {
433 return 8; // 56 bits
434 } else if (value < (1ULL << 63)) {
435 return 9; // 63 bits
436 } else {
437 return 10; // 64 bits (maximum for uint64_t)
438 }
439 }
440
450 static constexpr uint32_t varint(int32_t value) {
451 // Negative values are sign-extended to 64 bits in protocol buffers,
452 // which always results in a 10-byte varint for negative int32
453 if (value < 0) {
454 return 10; // Negative int32 is always 10 bytes long
455 }
456 // For non-negative values, use the uint32_t implementation
457 return varint(static_cast<uint32_t>(value));
458 }
459
466 static constexpr uint32_t varint(int64_t value) {
467 // For int64_t, we convert to uint64_t and calculate the size
468 // This works because the bit pattern determines the encoding size,
469 // and we've handled negative int32 values as a special case above
470 return varint(static_cast<uint64_t>(value));
471 }
472
480 static constexpr uint32_t field(uint32_t field_id, uint32_t type) {
481 uint32_t tag = (field_id << 3) | (type & 0b111);
482 return varint(tag);
483 }
484
502 inline void add_int32(uint32_t field_id_size, int32_t value) {
503 if (value != 0) {
504 add_int32_force(field_id_size, value);
505 }
506 }
507
511 inline void add_int32_force(uint32_t field_id_size, int32_t value) {
512 // Always calculate size when forced
513 // Negative values are encoded as 10-byte varints in protobuf
514 total_size_ += field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value)));
515 }
516
520 inline void add_uint32(uint32_t field_id_size, uint32_t value) {
521 if (value != 0) {
522 add_uint32_force(field_id_size, value);
523 }
524 }
525
529 inline void add_uint32_force(uint32_t field_id_size, uint32_t value) {
530 // Always calculate size when force is true
531 total_size_ += field_id_size + varint(value);
532 }
533
537 inline void add_bool(uint32_t field_id_size, bool value) {
538 if (value) {
539 // Boolean fields always use 1 byte when true
540 total_size_ += field_id_size + 1;
541 }
542 }
543
547 inline void add_bool_force(uint32_t field_id_size, bool value) {
548 // Always calculate size when force is true
549 // Boolean fields always use 1 byte
550 total_size_ += field_id_size + 1;
551 }
552
556 inline void add_float(uint32_t field_id_size, float value) {
557 if (value != 0.0f) {
558 total_size_ += field_id_size + 4;
559 }
560 }
561
562 // NOTE: add_double_field removed - wire type 1 (64-bit: double) not supported
563 // to reduce overhead on embedded systems
564
568 inline void add_fixed32(uint32_t field_id_size, uint32_t value) {
569 if (value != 0) {
570 total_size_ += field_id_size + 4;
571 }
572 }
573
574 // NOTE: add_fixed64_field removed - wire type 1 (64-bit: fixed64) not supported
575 // to reduce overhead on embedded systems
576
580 inline void add_sfixed32(uint32_t field_id_size, int32_t value) {
581 if (value != 0) {
582 total_size_ += field_id_size + 4;
583 }
584 }
585
586 // NOTE: add_sfixed64_field removed - wire type 1 (64-bit: sfixed64) not supported
587 // to reduce overhead on embedded systems
588
594 inline void add_sint32(uint32_t field_id_size, int32_t value) {
595 if (value != 0) {
596 add_sint32_force(field_id_size, value);
597 }
598 }
599
605 inline void add_sint32_force(uint32_t field_id_size, int32_t value) {
606 // Always calculate size when force is true
607 // ZigZag encoding for sint32
608 total_size_ += field_id_size + varint(encode_zigzag32(value));
609 }
610
614 inline void add_int64(uint32_t field_id_size, int64_t value) {
615 if (value != 0) {
616 add_int64_force(field_id_size, value);
617 }
618 }
619
623 inline void add_int64_force(uint32_t field_id_size, int64_t value) {
624 // Always calculate size when force is true
625 total_size_ += field_id_size + varint(value);
626 }
627
631 inline void add_uint64(uint32_t field_id_size, uint64_t value) {
632 if (value != 0) {
633 add_uint64_force(field_id_size, value);
634 }
635 }
636
640 inline void add_uint64_force(uint32_t field_id_size, uint64_t value) {
641 // Always calculate size when force is true
642 total_size_ += field_id_size + varint(value);
643 }
644
645 // NOTE: sint64 support functions (add_sint64_field, add_sint64_field_force) removed
646 // sint64 type is not supported by ESPHome API to reduce overhead on embedded systems
647
651 inline void add_length(uint32_t field_id_size, size_t len) {
652 if (len != 0) {
653 add_length_force(field_id_size, len);
654 }
655 }
656
661 inline void add_length_force(uint32_t field_id_size, size_t len) {
662 // Always calculate size when force is true
663 // Field ID + length varint + data bytes
664 total_size_ += field_id_size + varint(static_cast<uint32_t>(len)) + static_cast<uint32_t>(len);
665 }
666
675 inline void add_precalculated_size(uint32_t size) { total_size_ += size; }
676
685 inline void add_message_field(uint32_t field_id_size, uint32_t nested_size) {
686 if (nested_size != 0) {
687 add_message_field_force(field_id_size, nested_size);
688 }
689 }
690
696 inline void add_message_field_force(uint32_t field_id_size, uint32_t nested_size) {
697 // Always calculate size when force is true
698 // Field ID + length varint + nested message content
699 total_size_ += field_id_size + varint(nested_size) + nested_size;
700 }
701
711 inline void add_message_object(uint32_t field_id_size, const ProtoMessage &message) {
712 // Calculate nested message size by creating a temporary ProtoSize
713 ProtoSize nested_calc;
714 message.calculate_size(nested_calc);
715 uint32_t nested_size = nested_calc.get_size();
716
717 // Use the base implementation with the calculated nested_size
718 add_message_field(field_id_size, nested_size);
719 }
720
726 inline void add_message_object_force(uint32_t field_id_size, const ProtoMessage &message) {
727 // Calculate nested message size by creating a temporary ProtoSize
728 ProtoSize nested_calc;
729 message.calculate_size(nested_calc);
730 uint32_t nested_size = nested_calc.get_size();
731
732 // Use the base implementation with the calculated nested_size
733 add_message_field_force(field_id_size, nested_size);
734 }
735
745 template<typename MessageType>
746 inline void add_repeated_message(uint32_t field_id_size, const std::vector<MessageType> &messages) {
747 // Skip if the vector is empty
748 if (messages.empty()) {
749 return;
750 }
751
752 // Use the force version for all messages in the repeated field
753 for (const auto &message : messages) {
754 add_message_object_force(field_id_size, message);
755 }
756 }
757};
758
759// Implementation of encode_message - must be after ProtoMessage is defined
760inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessage &value, bool force) {
761 this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
762
763 // Calculate the message size first
764 ProtoSize msg_size;
765 value.calculate_size(msg_size);
766 uint32_t msg_length_bytes = msg_size.get_size();
767
768 // Calculate how many bytes the length varint needs
769 uint32_t varint_length_bytes = ProtoSize::varint(msg_length_bytes);
770
771 // Reserve exact space for the length varint
772 size_t begin = this->buffer_->size();
773 this->buffer_->resize(this->buffer_->size() + varint_length_bytes);
774
775 // Write the length varint directly
776 ProtoVarInt(msg_length_bytes).encode_to_buffer_unchecked(this->buffer_->data() + begin, varint_length_bytes);
777
778 // Now encode the message content - it will append to the buffer
779 value.encode(*this);
780
781 // Verify that the encoded size matches what we calculated
782 assert(this->buffer_->size() == begin + varint_length_bytes + msg_length_bytes);
783}
784
785// Implementation of decode_to_message - must be after ProtoDecodableMessage is defined
787 msg.decode(this->value_, this->length_);
788}
789
790template<typename T> const char *proto_enum_to_string(T value);
791
793 public:
794 protected:
795 virtual bool is_authenticated() = 0;
796 virtual bool is_connection_setup() = 0;
797 virtual void on_fatal_error() = 0;
798#ifdef USE_API_PASSWORD
799 virtual void on_unauthenticated_access() = 0;
800#endif
801 virtual void on_no_setup_connection() = 0;
809 virtual ProtoWriteBuffer create_buffer(uint32_t reserve_size) = 0;
810 virtual bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) = 0;
811 virtual void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) = 0;
812
813 // Optimized method that pre-allocates buffer based on message size
814 bool send_message_(const ProtoMessage &msg, uint8_t message_type) {
815 ProtoSize size;
816 msg.calculate_size(size);
817 uint32_t msg_size = size.get_size();
818
819 // Create a pre-sized buffer
820 auto buffer = this->create_buffer(msg_size);
821
822 // Encode message into the buffer
823 msg.encode(buffer);
824
825 // Send the buffer
826 return this->send_buffer(buffer, message_type);
827 }
828
829 // Authentication helper methods
831 if (!this->is_connection_setup()) {
833 return false;
834 }
835 return true;
836 }
837
839#ifdef USE_API_PASSWORD
840 if (!this->check_connection_setup_()) {
841 return false;
842 }
843 if (!this->is_authenticated()) {
845 return false;
846 }
847 return true;
848#else
849 return this->check_connection_setup_();
850#endif
851 }
852};
853
854} // namespace esphome::api
uint8_t raw[35]
Definition bl0939.h:0
StringRef is a reference to a string owned by something else.
Definition string_ref.h:22
constexpr const char * c_str() const
Definition string_ref.h:69
constexpr size_type size() const
Definition string_ref.h:70
uint32_t as_fixed32() const
Definition proto.h:204
int32_t as_sfixed32() const
Definition proto.h:205
float as_float() const
Definition proto.h:206
const uint32_t value_
Definition proto.h:216
Proto32Bit(uint32_t value)
Definition proto.h:203
virtual bool decode_32bit(uint32_t field_id, Proto32Bit value)
Definition proto.h:358
virtual bool decode_varint(uint32_t field_id, ProtoVarInt value)
Definition proto.h:356
void decode(const uint8_t *buffer, size_t length)
Definition proto.cpp:10
virtual bool decode_length(uint32_t field_id, ProtoLengthDelimited value)
Definition proto.h:357
void decode_to_message(ProtoDecodableMessage &msg) const
Decode the length-delimited data into an existing ProtoDecodableMessage instance.
Definition proto.h:786
const uint8_t *const value_
Definition proto.h:197
ProtoLengthDelimited(const uint8_t *value, size_t length)
Definition proto.h:182
std::string as_string() const
Definition proto.h:183
virtual void encode(ProtoWriteBuffer buffer) const
Definition proto.h:340
virtual const char * message_name() const
Definition proto.h:346
std::string dump() const
Definition proto.cpp:84
virtual ~ProtoMessage()=default
virtual void calculate_size(ProtoSize &size) const
Definition proto.h:342
virtual void dump_to(std::string &out) const =0
virtual void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data)=0
virtual void on_unauthenticated_access()=0
virtual ProtoWriteBuffer create_buffer(uint32_t reserve_size)=0
Create a buffer with a reserved size.
virtual void on_fatal_error()=0
virtual bool is_connection_setup()=0
virtual bool is_authenticated()=0
virtual void on_no_setup_connection()=0
bool send_message_(const ProtoMessage &msg, uint8_t message_type)
Definition proto.h:814
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.
Definition proto.h:711
static constexpr uint32_t varint(uint32_t value)
Calculates the size in bytes needed to encode a uint32_t value as a varint.
Definition proto.h:395
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)
Definition proto.h:696
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)
Definition proto.h:726
void add_float(uint32_t field_id_size, float value)
Calculates and adds the size of a float field to the total message size.
Definition proto.h:556
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.
Definition proto.h:480
static constexpr uint32_t varint(int32_t value)
Calculates the size in bytes needed to encode an int32_t value as a varint.
Definition proto.h:450
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.
Definition proto.h:580
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)
Definition proto.h:529
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)
Definition proto.h:511
static constexpr uint32_t varint(int64_t value)
Calculates the size in bytes needed to encode an int64_t value as a varint.
Definition proto.h:466
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)
Definition proto.h:623
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.
Definition proto.h:594
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.
Definition proto.h:685
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)
Definition proto.h:547
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.
Definition proto.h:614
void add_bool(uint32_t field_id_size, bool value)
Calculates and adds the size of a boolean field to the total message size.
Definition proto.h:537
uint32_t get_size() const
Definition proto.h:387
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.
Definition proto.h:520
static constexpr uint32_t varint(uint64_t value)
Calculates the size in bytes needed to encode a uint64_t value as a varint.
Definition proto.h:419
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.
Definition proto.h:746
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.
Definition proto.h:631
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...
Definition proto.h:661
void add_int32(uint32_t field_id_size, int32_t value)
Common parameters for all add_*_field methods.
Definition proto.h:502
void add_precalculated_size(uint32_t size)
Adds a pre-calculated size directly to the total.
Definition proto.h:675
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)
Definition proto.h:605
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)
Definition proto.h:640
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.
Definition proto.h:568
ProtoSize()=default
ProtoSize class for Protocol Buffer serialization size calculation.
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.
Definition proto.h:651
Representation of a VarInt - in ProtoBuf should be 64bit but we only use 32bit.
Definition proto.h:66
constexpr uint16_t as_uint16() const
Definition proto.h:107
constexpr uint64_t as_uint64() const
Definition proto.h:109
constexpr int32_t as_int32() const
Definition proto.h:111
void encode_to_buffer_unchecked(uint8_t *buffer, size_t len)
Encode the varint value to a pre-allocated buffer without bounds checking.
Definition proto.h:138
void encode(std::vector< uint8_t > &out)
Definition proto.h:155
constexpr uint32_t as_uint32() const
Definition proto.h:108
constexpr int64_t as_int64() const
Definition proto.h:115
constexpr bool as_bool() const
Definition proto.h:110
ProtoVarInt(uint64_t value)
Definition proto.h:69
constexpr int32_t as_sint32() const
Definition proto.h:119
constexpr int64_t as_sint64() const
Definition proto.h:123
static optional< ProtoVarInt > parse(const uint8_t *buffer, uint32_t len, uint32_t *consumed)
Definition proto.h:71
void encode_varint_raw(uint32_t value)
Definition proto.h:226
void encode_string(uint32_t field_id, const std::string &value, bool force=false)
Definition proto.h:257
void write(uint8_t value)
Definition proto.h:224
void encode_int64(uint32_t field_id, int64_t value, bool force=false)
Definition proto.h:317
void encode_float(uint32_t field_id, float value, bool force=false)
Definition proto.h:298
void encode_int32(uint32_t field_id, int32_t value, bool force=false)
Definition proto.h:309
void encode_sint64(uint32_t field_id, int64_t value, bool force=false)
Definition proto.h:323
void encode_string(uint32_t field_id, const char *string, size_t len, bool force=false)
Definition proto.h:243
void encode_bool(uint32_t field_id, bool value, bool force=false)
Definition proto.h:278
ProtoWriteBuffer(std::vector< uint8_t > *buffer)
Definition proto.h:223
void encode_uint64(uint32_t field_id, uint64_t value, bool force=false)
Definition proto.h:272
void encode_string(uint32_t field_id, const StringRef &ref, bool force=false)
Definition proto.h:260
void encode_uint32(uint32_t field_id, uint32_t value, bool force=false)
Definition proto.h:266
void encode_sint32(uint32_t field_id, int32_t value, bool force=false)
Definition proto.h:320
void encode_field_raw(uint32_t field_id, uint32_t type)
Encode a field key (tag/wire type combination).
Definition proto.h:239
void encode_message(uint32_t field_id, const ProtoMessage &value, bool force=false)
Definition proto.h:760
std::vector< uint8_t > * get_buffer() const
Definition proto.h:327
void encode_bytes(uint32_t field_id, const uint8_t *data, size_t len, bool force=false)
Definition proto.h:263
void encode_fixed32(uint32_t field_id, uint32_t value, bool force=false)
Definition proto.h:284
void encode_varint_raw(ProtoVarInt value)
Definition proto.h:225
std::vector< uint8_t > * buffer_
Definition proto.h:330
uint8_t type
mopeka_std_values val[4]
constexpr uint32_t encode_zigzag32(int32_t value)
Definition proto.h:19
const char * proto_enum_to_string(T value)
constexpr uint64_t encode_zigzag64(int64_t value)
Definition proto.h:23
constexpr int32_t decode_zigzag32(uint32_t value)
Definition proto.h:27
constexpr int64_t decode_zigzag64(uint64_t value)
Definition proto.h:31
std::string size_t len
Definition helpers.h:279
uint16_t length
Definition tt21100.cpp:0