mirror of
https://github.com/esphome/esphome.git
synced 2025-09-06 21:32:21 +01:00
zero copy cleanup
This commit is contained in:
@@ -325,6 +325,10 @@ def create_field_type_info(field: descriptor.FieldDescriptorProto) -> TypeInfo:
|
||||
):
|
||||
return FixedArrayBytesType(field, fixed_size)
|
||||
|
||||
# Check for zero_copy option on bytes fields
|
||||
if field.type == 12 and get_field_opt(field, pb.zero_copy, default=False):
|
||||
return ZeroCopyBytesType(field)
|
||||
|
||||
validate_field_type(field.type, field.name)
|
||||
return TYPE_INFO[field.type](field)
|
||||
|
||||
@@ -608,6 +612,45 @@ class BytesType(TypeInfo):
|
||||
return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical bytes
|
||||
|
||||
|
||||
class ZeroCopyBytesType(TypeInfo):
|
||||
"""Special type for zero-copy bytes fields that only accepts const uint8_t* data."""
|
||||
|
||||
cpp_type = "std::string" # Still store as string for compatibility
|
||||
default_value = ""
|
||||
reference_type = "std::string &"
|
||||
const_reference_type = "const std::string &"
|
||||
encode_func = "encode_bytes"
|
||||
wire_type = WireType.LENGTH_DELIMITED
|
||||
decode_length = "value.as_string()"
|
||||
|
||||
@property
|
||||
def public_content(self) -> list[str]:
|
||||
# Store both pointer and length for zero-copy encoding, plus setter method
|
||||
return [
|
||||
f"const uint8_t* {self.field_name}_ptr_{{nullptr}};",
|
||||
f"size_t {self.field_name}_len_{{0}};",
|
||||
f"void set_{self.field_name}(const uint8_t* data, size_t len) {{",
|
||||
f" this->{self.field_name}_ptr_ = data;",
|
||||
f" this->{self.field_name}_len_ = len;",
|
||||
"}",
|
||||
]
|
||||
|
||||
@property
|
||||
def encode_content(self) -> str:
|
||||
# Encode directly from pointer without nullptr check (like original)
|
||||
return f"buffer.encode_bytes({self.number}, this->{self.field_name}_ptr_, this->{self.field_name}_len_);"
|
||||
|
||||
def dump(self, name: str) -> str:
|
||||
return f"out.append(format_hex_pretty(this->{self.field_name}_ptr_, this->{self.field_name}_len_));"
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
# Use the new add_bytes_field helper
|
||||
return f"ProtoSize::add_bytes_field(total_size, {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
|
||||
|
||||
|
||||
class FixedArrayBytesType(TypeInfo):
|
||||
"""Special type for fixed-size byte arrays."""
|
||||
|
||||
|
Reference in New Issue
Block a user