mirror of
https://github.com/esphome/esphome.git
synced 2025-09-05 21:02:20 +01:00
Make ProtoSize an object
This commit is contained in:
@@ -281,7 +281,7 @@ class TypeInfo(ABC):
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
method = f"{base_method}_repeated" if force else base_method
|
||||
value = value_expr if value_expr else name
|
||||
return f"ProtoSize::{method}(total_size, {field_id_size}, {value});"
|
||||
return f"size.{method}({field_id_size}, {value});"
|
||||
|
||||
@abstractmethod
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
@@ -389,7 +389,7 @@ class DoubleType(TypeInfo):
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return f"ProtoSize::add_double_field(total_size, {field_id_size}, {name});"
|
||||
return f"size.add_double_field({field_id_size}, {name});"
|
||||
|
||||
def get_fixed_size_bytes(self) -> int:
|
||||
return 8
|
||||
@@ -413,7 +413,7 @@ class FloatType(TypeInfo):
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return f"ProtoSize::add_float_field(total_size, {field_id_size}, {name});"
|
||||
return f"size.add_float_field({field_id_size}, {name});"
|
||||
|
||||
def get_fixed_size_bytes(self) -> int:
|
||||
return 4
|
||||
@@ -497,7 +497,7 @@ class Fixed64Type(TypeInfo):
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return f"ProtoSize::add_fixed64_field(total_size, {field_id_size}, {name});"
|
||||
return f"size.add_fixed64_field({field_id_size}, {name});"
|
||||
|
||||
def get_fixed_size_bytes(self) -> int:
|
||||
return 8
|
||||
@@ -521,7 +521,7 @@ class Fixed32Type(TypeInfo):
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return f"ProtoSize::add_fixed32_field(total_size, {field_id_size}, {name});"
|
||||
return f"size.add_fixed32_field({field_id_size}, {name});"
|
||||
|
||||
def get_fixed_size_bytes(self) -> int:
|
||||
return 4
|
||||
@@ -631,11 +631,11 @@ class StringType(TypeInfo):
|
||||
if name == "it":
|
||||
# For repeated fields, we need to use add_string_field_repeated which includes field ID
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return f"ProtoSize::add_string_field_repeated(total_size, {field_id_size}, it);"
|
||||
return f"size.add_string_field_repeated({field_id_size}, it);"
|
||||
|
||||
# For messages that need encoding, use the StringRef size
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return f"ProtoSize::add_string_field(total_size, {field_id_size}, this->{self.field_name}_ref_.size());"
|
||||
return f"size.add_string_field({field_id_size}, this->{self.field_name}_ref_.size());"
|
||||
|
||||
def get_estimated_size(self) -> int:
|
||||
return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical string
|
||||
@@ -770,7 +770,7 @@ class BytesType(TypeInfo):
|
||||
return o
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
return f"ProtoSize::add_bytes_field(total_size, {self.calculate_field_id_size()}, this->{self.field_name}_len_);"
|
||||
return f"size.add_bytes_field({self.calculate_field_id_size()}, this->{self.field_name}_len_);"
|
||||
|
||||
def get_estimated_size(self) -> int:
|
||||
return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical bytes
|
||||
@@ -845,15 +845,11 @@ class FixedArrayBytesType(TypeInfo):
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
|
||||
if force:
|
||||
# For repeated fields, always calculate size
|
||||
return f"total_size += {field_id_size} + ProtoSize::varint(static_cast<uint32_t>({length_field})) + {length_field};"
|
||||
# For repeated fields, always calculate size (no zero check)
|
||||
return f"size.add_bytes_field_repeated({field_id_size}, {length_field});"
|
||||
else:
|
||||
# For non-repeated fields, skip if length is 0 (matching encode_string behavior)
|
||||
return (
|
||||
f"if ({length_field} != 0) {{\n"
|
||||
f" total_size += {field_id_size} + ProtoSize::varint(static_cast<uint32_t>({length_field})) + {length_field};\n"
|
||||
f"}}"
|
||||
)
|
||||
# For non-repeated fields, add_bytes_field already checks for zero
|
||||
return f"size.add_bytes_field({field_id_size}, {length_field});"
|
||||
|
||||
def get_estimated_size(self) -> int:
|
||||
# Estimate based on typical BLE advertisement size
|
||||
@@ -939,7 +935,7 @@ class SFixed32Type(TypeInfo):
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return f"ProtoSize::add_sfixed32_field(total_size, {field_id_size}, {name});"
|
||||
return f"size.add_sfixed32_field({field_id_size}, {name});"
|
||||
|
||||
def get_fixed_size_bytes(self) -> int:
|
||||
return 4
|
||||
@@ -963,7 +959,7 @@ class SFixed64Type(TypeInfo):
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return f"ProtoSize::add_sfixed64_field(total_size, {field_id_size}, {name});"
|
||||
return f"size.add_sfixed64_field({field_id_size}, {name});"
|
||||
|
||||
def get_fixed_size_bytes(self) -> int:
|
||||
return 8
|
||||
@@ -1240,7 +1236,7 @@ class RepeatedTypeInfo(TypeInfo):
|
||||
if isinstance(self._ti, MessageType):
|
||||
# For repeated messages, use the dedicated helper that handles iteration internally
|
||||
field_id_size = self._ti.calculate_field_id_size()
|
||||
o = f"ProtoSize::add_repeated_message(total_size, {field_id_size}, {name});"
|
||||
o = f"size.add_repeated_message({field_id_size}, {name});"
|
||||
return o
|
||||
|
||||
# For other repeated types, use the underlying type's size calculation with force=True
|
||||
@@ -1253,7 +1249,9 @@ class RepeatedTypeInfo(TypeInfo):
|
||||
field_id_size = self._ti.calculate_field_id_size()
|
||||
# Pre-calculate the total bytes per element
|
||||
bytes_per_element = field_id_size + num_bytes
|
||||
o += f" total_size += {name}.size() * {bytes_per_element};\n"
|
||||
o += (
|
||||
f" size.add_precalculated_size({name}.size() * {bytes_per_element});\n"
|
||||
)
|
||||
else:
|
||||
# Other types need the actual value
|
||||
o += f" for (const auto {'' if self._ti_is_bool else '&'}it : {name}) {{\n"
|
||||
@@ -1685,7 +1683,7 @@ def build_message_type(
|
||||
if needs_encode and encode:
|
||||
o = f"void {desc.name}::encode(ProtoWriteBuffer buffer) const {{"
|
||||
if len(encode) == 1 and len(encode[0]) + len(o) + 3 < 120:
|
||||
o += f" {encode[0]} "
|
||||
o += f" {encode[0]} }}\n"
|
||||
else:
|
||||
o += "\n"
|
||||
o += indent("\n".join(encode)) + "\n"
|
||||
@@ -1697,17 +1695,17 @@ def build_message_type(
|
||||
|
||||
# Add calculate_size method only if this message needs encoding and has fields
|
||||
if needs_encode and size_calc:
|
||||
o = f"void {desc.name}::calculate_size(uint32_t &total_size) const {{"
|
||||
o = f"void {desc.name}::calculate_size(ProtoSize &size) const {{"
|
||||
# For a single field, just inline it for simplicity
|
||||
if len(size_calc) == 1 and len(size_calc[0]) + len(o) + 3 < 120:
|
||||
o += f" {size_calc[0]} "
|
||||
o += f" {size_calc[0]} }}\n"
|
||||
else:
|
||||
# For multiple fields
|
||||
o += "\n"
|
||||
o += indent("\n".join(size_calc)) + "\n"
|
||||
o += "}\n"
|
||||
cpp += o
|
||||
prot = "void calculate_size(uint32_t &total_size) const override;"
|
||||
prot = "void calculate_size(ProtoSize &size) const override;"
|
||||
public_content.append(prot)
|
||||
# If no fields to calculate size for or message doesn't need encoding, the default implementation in ProtoMessage will be used
|
||||
|
||||
|
Reference in New Issue
Block a user