ESPHome 2025.10.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
185 // Direct access to raw data without string allocation
186 const uint8_t *data() const { return this->value_; }
187 size_t size() const { return this->length_; }
188
199
200 protected:
201 const uint8_t *const value_;
202 const size_t length_;
203};
204
206 public:
207 explicit Proto32Bit(uint32_t value) : value_(value) {}
208 uint32_t as_fixed32() const { return this->value_; }
209 int32_t as_sfixed32() const { return static_cast<int32_t>(this->value_); }
210 float as_float() const {
211 union {
212 uint32_t raw;
213 float value;
214 } s{};
215 s.raw = this->value_;
216 return s.value;
217 }
218
219 protected:
220 const uint32_t value_;
221};
222
223// NOTE: Proto64Bit class removed - wire type 1 (64-bit fixed) not supported
224
226 public:
227 ProtoWriteBuffer(std::vector<uint8_t> *buffer) : buffer_(buffer) {}
228 void write(uint8_t value) { this->buffer_->push_back(value); }
229 void encode_varint_raw(ProtoVarInt value) { value.encode(*this->buffer_); }
230 void encode_varint_raw(uint32_t value) { this->encode_varint_raw(ProtoVarInt(value)); }
243 void encode_field_raw(uint32_t field_id, uint32_t type) {
244 uint32_t val = (field_id << 3) | (type & 0b111);
245 this->encode_varint_raw(val);
246 }
247 void encode_string(uint32_t field_id, const char *string, size_t len, bool force = false) {
248 if (len == 0 && !force)
249 return;
250
251 this->encode_field_raw(field_id, 2); // type 2: Length-delimited string
252 this->encode_varint_raw(len);
253
254 // Using resize + memcpy instead of insert provides significant performance improvement:
255 // ~10-11x faster for 16-32 byte strings, ~3x faster for 64-byte strings
256 // as it avoids iterator checks and potential element moves that insert performs
257 size_t old_size = this->buffer_->size();
258 this->buffer_->resize(old_size + len);
259 std::memcpy(this->buffer_->data() + old_size, string, len);
260 }
261 void encode_string(uint32_t field_id, const std::string &value, bool force = false) {
262 this->encode_string(field_id, value.data(), value.size(), force);
263 }
264 void encode_string(uint32_t field_id, const StringRef &ref, bool force = false) {
265 this->encode_string(field_id, ref.c_str(), ref.size(), force);
266 }
267 void encode_bytes(uint32_t field_id, const uint8_t *data, size_t len, bool force = false) {
268 this->encode_string(field_id, reinterpret_cast<const char *>(data), len, force);
269 }
270 void encode_uint32(uint32_t field_id, uint32_t value, bool force = false) {
271 if (value == 0 && !force)
272 return;
273 this->encode_field_raw(field_id, 0); // type 0: Varint - uint32
274 this->encode_varint_raw(value);
275 }
276 void encode_uint64(uint32_t field_id, uint64_t value, bool force = false) {
277 if (value == 0 && !force)
278 return;
279 this->encode_field_raw(field_id, 0); // type 0: Varint - uint64
280 this->encode_varint_raw(ProtoVarInt(value));
281 }
282 void encode_bool(uint32_t field_id, bool value, bool force = false) {
283 if (!value && !force)
284 return;
285 this->encode_field_raw(field_id, 0); // type 0: Varint - bool
286 this->write(0x01);
287 }
288 void encode_fixed32(uint32_t field_id, uint32_t value, bool force = false) {
289 if (value == 0 && !force)
290 return;
291
292 this->encode_field_raw(field_id, 5); // type 5: 32-bit fixed32
293 this->write((value >> 0) & 0xFF);
294 this->write((value >> 8) & 0xFF);
295 this->write((value >> 16) & 0xFF);
296 this->write((value >> 24) & 0xFF);
297 }
298 // NOTE: Wire type 1 (64-bit fixed: double, fixed64, sfixed64) is intentionally
299 // not supported to reduce overhead on embedded systems. All ESPHome devices are
300 // 32-bit microcontrollers where 64-bit operations are expensive. If 64-bit support
301 // is needed in the future, the necessary encoding/decoding functions must be added.
302 void encode_float(uint32_t field_id, float value, bool force = false) {
303 if (value == 0.0f && !force)
304 return;
305
306 union {
307 float value;
308 uint32_t raw;
309 } val{};
310 val.value = value;
311 this->encode_fixed32(field_id, val.raw);
312 }
313 void encode_int32(uint32_t field_id, int32_t value, bool force = false) {
314 if (value < 0) {
315 // negative int32 is always 10 byte long
316 this->encode_int64(field_id, value, force);
317 return;
318 }
319 this->encode_uint32(field_id, static_cast<uint32_t>(value), force);
320 }
321 void encode_int64(uint32_t field_id, int64_t value, bool force = false) {
322 this->encode_uint64(field_id, static_cast<uint64_t>(value), force);
323 }
324 void encode_sint32(uint32_t field_id, int32_t value, bool force = false) {
325 this->encode_uint32(field_id, encode_zigzag32(value), force);
326 }
327 void encode_sint64(uint32_t field_id, int64_t value, bool force = false) {
328 this->encode_uint64(field_id, encode_zigzag64(value), force);
329 }
330 void encode_message(uint32_t field_id, const ProtoMessage &value, bool force = false);
331 std::vector<uint8_t> *get_buffer() const { return buffer_; }
332
333 protected:
334 std::vector<uint8_t> *buffer_;
335};
336
337// Forward declaration
338class ProtoSize;
339
341 public:
342 virtual ~ProtoMessage() = default;
343 // Default implementation for messages with no fields
344 virtual void encode(ProtoWriteBuffer buffer) const {}
345 // Default implementation for messages with no fields
346 virtual void calculate_size(ProtoSize &size) const {}
347#ifdef HAS_PROTO_MESSAGE_DUMP
348 std::string dump() const;
349 virtual void dump_to(std::string &out) const = 0;
350 virtual const char *message_name() const { return "unknown"; }
351#endif
352};
353
354// Base class for messages that support decoding
356 public:
357 void decode(const uint8_t *buffer, size_t length);
358
359 protected:
360 virtual bool decode_varint(uint32_t field_id, ProtoVarInt value) { return false; }
361 virtual bool decode_length(uint32_t field_id, ProtoLengthDelimited value) { return false; }
362 virtual bool decode_32bit(uint32_t field_id, Proto32Bit value) { return false; }
363 // NOTE: decode_64bit removed - wire type 1 not supported
364};
365
367 private:
368 uint32_t total_size_ = 0;
369
370 public:
389 ProtoSize() = default;
390
391 uint32_t get_size() const { return total_size_; }
392
399 static constexpr uint32_t varint(uint32_t value) {
400 // Optimized varint size calculation using leading zeros
401 // Each 7 bits requires one byte in the varint encoding
402 if (value < 128)
403 return 1; // 7 bits, common case for small values
404
405 // For larger values, count bytes needed based on the position of the highest bit set
406 if (value < 16384) {
407 return 2; // 14 bits
408 } else if (value < 2097152) {
409 return 3; // 21 bits
410 } else if (value < 268435456) {
411 return 4; // 28 bits
412 } else {
413 return 5; // 32 bits (maximum for uint32_t)
414 }
415 }
416
423 static constexpr uint32_t varint(uint64_t value) {
424 // Handle common case of values fitting in uint32_t (vast majority of use cases)
425 if (value <= UINT32_MAX) {
426 return varint(static_cast<uint32_t>(value));
427 }
428
429 // For larger values, determine size based on highest bit position
430 if (value < (1ULL << 35)) {
431 return 5; // 35 bits
432 } else if (value < (1ULL << 42)) {
433 return 6; // 42 bits
434 } else if (value < (1ULL << 49)) {
435 return 7; // 49 bits
436 } else if (value < (1ULL << 56)) {
437 return 8; // 56 bits
438 } else if (value < (1ULL << 63)) {
439 return 9; // 63 bits
440 } else {
441 return 10; // 64 bits (maximum for uint64_t)
442 }
443 }
444
454 static constexpr uint32_t varint(int32_t value) {
455 // Negative values are sign-extended to 64 bits in protocol buffers,
456 // which always results in a 10-byte varint for negative int32
457 if (value < 0) {
458 return 10; // Negative int32 is always 10 bytes long
459 }
460 // For non-negative values, use the uint32_t implementation
461 return varint(static_cast<uint32_t>(value));
462 }
463
470 static constexpr uint32_t varint(int64_t value) {
471 // For int64_t, we convert to uint64_t and calculate the size
472 // This works because the bit pattern determines the encoding size,
473 // and we've handled negative int32 values as a special case above
474 return varint(static_cast<uint64_t>(value));
475 }
476
484 static constexpr uint32_t field(uint32_t field_id, uint32_t type) {
485 uint32_t tag = (field_id << 3) | (type & 0b111);
486 return varint(tag);
487 }
488
506 inline void add_int32(uint32_t field_id_size, int32_t value) {
507 if (value != 0) {
508 add_int32_force(field_id_size, value);
509 }
510 }
511
515 inline void add_int32_force(uint32_t field_id_size, int32_t value) {
516 // Always calculate size when forced
517 // Negative values are encoded as 10-byte varints in protobuf
518 total_size_ += field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value)));
519 }
520
524 inline void add_uint32(uint32_t field_id_size, uint32_t value) {
525 if (value != 0) {
526 add_uint32_force(field_id_size, value);
527 }
528 }
529
533 inline void add_uint32_force(uint32_t field_id_size, uint32_t value) {
534 // Always calculate size when force is true
535 total_size_ += field_id_size + varint(value);
536 }
537
541 inline void add_bool(uint32_t field_id_size, bool value) {
542 if (value) {
543 // Boolean fields always use 1 byte when true
544 total_size_ += field_id_size + 1;
545 }
546 }
547
551 inline void add_bool_force(uint32_t field_id_size, bool value) {
552 // Always calculate size when force is true
553 // Boolean fields always use 1 byte
554 total_size_ += field_id_size + 1;
555 }
556
560 inline void add_float(uint32_t field_id_size, float value) {
561 if (value != 0.0f) {
562 total_size_ += field_id_size + 4;
563 }
564 }
565
566 // NOTE: add_double_field removed - wire type 1 (64-bit: double) not supported
567 // to reduce overhead on embedded systems
568
572 inline void add_fixed32(uint32_t field_id_size, uint32_t value) {
573 if (value != 0) {
574 total_size_ += field_id_size + 4;
575 }
576 }
577
578 // NOTE: add_fixed64_field removed - wire type 1 (64-bit: fixed64) not supported
579 // to reduce overhead on embedded systems
580
584 inline void add_sfixed32(uint32_t field_id_size, int32_t value) {
585 if (value != 0) {
586 total_size_ += field_id_size + 4;
587 }
588 }
589
590 // NOTE: add_sfixed64_field removed - wire type 1 (64-bit: sfixed64) not supported
591 // to reduce overhead on embedded systems
592
598 inline void add_sint32(uint32_t field_id_size, int32_t value) {
599 if (value != 0) {
600 add_sint32_force(field_id_size, value);
601 }
602 }
603
609 inline void add_sint32_force(uint32_t field_id_size, int32_t value) {
610 // Always calculate size when force is true
611 // ZigZag encoding for sint32
612 total_size_ += field_id_size + varint(encode_zigzag32(value));
613 }
614
618 inline void add_int64(uint32_t field_id_size, int64_t value) {
619 if (value != 0) {
620 add_int64_force(field_id_size, value);
621 }
622 }
623
627 inline void add_int64_force(uint32_t field_id_size, int64_t value) {
628 // Always calculate size when force is true
629 total_size_ += field_id_size + varint(value);
630 }
631
635 inline void add_uint64(uint32_t field_id_size, uint64_t value) {
636 if (value != 0) {
637 add_uint64_force(field_id_size, value);
638 }
639 }
640
644 inline void add_uint64_force(uint32_t field_id_size, uint64_t value) {
645 // Always calculate size when force is true
646 total_size_ += field_id_size + varint(value);
647 }
648
649 // NOTE: sint64 support functions (add_sint64_field, add_sint64_field_force) removed
650 // sint64 type is not supported by ESPHome API to reduce overhead on embedded systems
651
655 inline void add_length(uint32_t field_id_size, size_t len) {
656 if (len != 0) {
657 add_length_force(field_id_size, len);
658 }
659 }
660
665 inline void add_length_force(uint32_t field_id_size, size_t len) {
666 // Always calculate size when force is true
667 // Field ID + length varint + data bytes
668 total_size_ += field_id_size + varint(static_cast<uint32_t>(len)) + static_cast<uint32_t>(len);
669 }
670
679 inline void add_precalculated_size(uint32_t size) { total_size_ += size; }
680
689 inline void add_message_field(uint32_t field_id_size, uint32_t nested_size) {
690 if (nested_size != 0) {
691 add_message_field_force(field_id_size, nested_size);
692 }
693 }
694
700 inline void add_message_field_force(uint32_t field_id_size, uint32_t nested_size) {
701 // Always calculate size when force is true
702 // Field ID + length varint + nested message content
703 total_size_ += field_id_size + varint(nested_size) + nested_size;
704 }
705
715 inline void add_message_object(uint32_t field_id_size, const ProtoMessage &message) {
716 // Calculate nested message size by creating a temporary ProtoSize
717 ProtoSize nested_calc;
718 message.calculate_size(nested_calc);
719 uint32_t nested_size = nested_calc.get_size();
720
721 // Use the base implementation with the calculated nested_size
722 add_message_field(field_id_size, nested_size);
723 }
724
730 inline void add_message_object_force(uint32_t field_id_size, const ProtoMessage &message) {
731 // Calculate nested message size by creating a temporary ProtoSize
732 ProtoSize nested_calc;
733 message.calculate_size(nested_calc);
734 uint32_t nested_size = nested_calc.get_size();
735
736 // Use the base implementation with the calculated nested_size
737 add_message_field_force(field_id_size, nested_size);
738 }
739
749 template<typename MessageType>
750 inline void add_repeated_message(uint32_t field_id_size, const std::vector<MessageType> &messages) {
751 // Skip if the vector is empty
752 if (messages.empty()) {
753 return;
754 }
755
756 // Use the force version for all messages in the repeated field
757 for (const auto &message : messages) {
758 add_message_object_force(field_id_size, message);
759 }
760 }
761};
762
763// Implementation of encode_message - must be after ProtoMessage is defined
764inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessage &value, bool force) {
765 this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
766
767 // Calculate the message size first
768 ProtoSize msg_size;
769 value.calculate_size(msg_size);
770 uint32_t msg_length_bytes = msg_size.get_size();
771
772 // Calculate how many bytes the length varint needs
773 uint32_t varint_length_bytes = ProtoSize::varint(msg_length_bytes);
774
775 // Reserve exact space for the length varint
776 size_t begin = this->buffer_->size();
777 this->buffer_->resize(this->buffer_->size() + varint_length_bytes);
778
779 // Write the length varint directly
780 ProtoVarInt(msg_length_bytes).encode_to_buffer_unchecked(this->buffer_->data() + begin, varint_length_bytes);
781
782 // Now encode the message content - it will append to the buffer
783 value.encode(*this);
784
785 // Verify that the encoded size matches what we calculated
786 assert(this->buffer_->size() == begin + varint_length_bytes + msg_length_bytes);
787}
788
789// Implementation of decode_to_message - must be after ProtoDecodableMessage is defined
791 msg.decode(this->value_, this->length_);
792}
793
794template<typename T> const char *proto_enum_to_string(T value);
795
797 public:
798 protected:
799 virtual bool is_authenticated() = 0;
800 virtual bool is_connection_setup() = 0;
801 virtual void on_fatal_error() = 0;
802#ifdef USE_API_PASSWORD
803 virtual void on_unauthenticated_access() = 0;
804#endif
805 virtual void on_no_setup_connection() = 0;
813 virtual ProtoWriteBuffer create_buffer(uint32_t reserve_size) = 0;
814 virtual bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) = 0;
815 virtual void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) = 0;
816
817 // Optimized method that pre-allocates buffer based on message size
818 bool send_message_(const ProtoMessage &msg, uint8_t message_type) {
819 ProtoSize size;
820 msg.calculate_size(size);
821 uint32_t msg_size = size.get_size();
822
823 // Create a pre-sized buffer
824 auto buffer = this->create_buffer(msg_size);
825
826 // Encode message into the buffer
827 msg.encode(buffer);
828
829 // Send the buffer
830 return this->send_buffer(buffer, message_type);
831 }
832
833 // Authentication helper methods
835 if (!this->is_connection_setup()) {
837 return false;
838 }
839 return true;
840 }
841
842 inline bool check_authenticated_() {
843#ifdef USE_API_PASSWORD
844 if (!this->check_connection_setup_()) {
845 return false;
846 }
847 if (!this->is_authenticated()) {
849 return false;
850 }
851 return true;
852#else
853 return this->check_connection_setup_();
854#endif
855 }
856};
857
858} // 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:208
int32_t as_sfixed32() const
Definition proto.h:209
float as_float() const
Definition proto.h:210
const uint32_t value_
Definition proto.h:220
Proto32Bit(uint32_t value)
Definition proto.h:207
virtual bool decode_32bit(uint32_t field_id, Proto32Bit value)
Definition proto.h:362
virtual bool decode_varint(uint32_t field_id, ProtoVarInt value)
Definition proto.h:360
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:361
void decode_to_message(ProtoDecodableMessage &msg) const
Decode the length-delimited data into an existing ProtoDecodableMessage instance.
Definition proto.h:790
const uint8_t *const value_
Definition proto.h:201
const uint8_t * data() const
Definition proto.h:186
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:344
virtual const char * message_name() const
Definition proto.h:350
std::string dump() const
Definition proto.cpp:80
virtual ~ProtoMessage()=default
virtual void calculate_size(ProtoSize &size) const
Definition proto.h:346
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:818
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:715
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:399
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:700
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:730
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:560
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:484
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:454
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:584
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:533
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:515
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:470
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:627
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:598
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:689
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:551
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:618
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:541
uint32_t get_size() const
Definition proto.h:391
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:524
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:423
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:750
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:635
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:665
void add_int32(uint32_t field_id_size, int32_t value)
Common parameters for all add_*_field methods.
Definition proto.h:506
void add_precalculated_size(uint32_t size)
Adds a pre-calculated size directly to the total.
Definition proto.h:679
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:609
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:644
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:572
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:655
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:230
void encode_string(uint32_t field_id, const std::string &value, bool force=false)
Definition proto.h:261
void write(uint8_t value)
Definition proto.h:228
void encode_int64(uint32_t field_id, int64_t value, bool force=false)
Definition proto.h:321
void encode_float(uint32_t field_id, float value, bool force=false)
Definition proto.h:302
void encode_int32(uint32_t field_id, int32_t value, bool force=false)
Definition proto.h:313
void encode_sint64(uint32_t field_id, int64_t value, bool force=false)
Definition proto.h:327
void encode_string(uint32_t field_id, const char *string, size_t len, bool force=false)
Definition proto.h:247
void encode_bool(uint32_t field_id, bool value, bool force=false)
Definition proto.h:282
ProtoWriteBuffer(std::vector< uint8_t > *buffer)
Definition proto.h:227
void encode_uint64(uint32_t field_id, uint64_t value, bool force=false)
Definition proto.h:276
void encode_string(uint32_t field_id, const StringRef &ref, bool force=false)
Definition proto.h:264
void encode_uint32(uint32_t field_id, uint32_t value, bool force=false)
Definition proto.h:270
void encode_sint32(uint32_t field_id, int32_t value, bool force=false)
Definition proto.h:324
void encode_field_raw(uint32_t field_id, uint32_t type)
Encode a field key (tag/wire type combination).
Definition proto.h:243
void encode_message(uint32_t field_id, const ProtoMessage &value, bool force=false)
Definition proto.h:764
std::vector< uint8_t > * get_buffer() const
Definition proto.h:331
void encode_bytes(uint32_t field_id, const uint8_t *data, size_t len, bool force=false)
Definition proto.h:267
void encode_fixed32(uint32_t field_id, uint32_t value, bool force=false)
Definition proto.h:288
void encode_varint_raw(ProtoVarInt value)
Definition proto.h:229
std::vector< uint8_t > * buffer_
Definition proto.h:334
uint16_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:291
uint16_t length
Definition tt21100.cpp:0