[api] Add encode_progmem_string for progmem string fields

Generated code passes the ProgmemStringRef instead of spelling out the cast.
This commit is contained in:
J. Nick Koston
2026-10-08 20:17:55 -10:00
parent 7b5a1f9de9
commit 1fa844a5d2
4 changed files with 20 additions and 17 deletions
+5 -12
View File
@@ -1324,17 +1324,13 @@ void GetTimeResponse::decode_field(void *self, uint32_t tag, const uint8_t *data
uint8_t *ListEntitiesServicesArgument::encode_msg(const void *self,
uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM) {
const auto &msg = *static_cast<const ListEntitiesServicesArgument *>(self);
pos = ProtoEncode::encode_progmem_bytes(pos PROTO_ENCODE_DEBUG_ARG, 1,
reinterpret_cast<const uint8_t *>(msg.name.progmem_ptr()), msg.name.size());
pos = ProtoEncode::encode_progmem_string(pos PROTO_ENCODE_DEBUG_ARG, 1, msg.name);
pos = ProtoEncode::encode_uint32(pos PROTO_ENCODE_DEBUG_ARG, 2, static_cast<uint32_t>(msg.type));
#ifdef USE_API_USER_DEFINED_ACTION_METADATA
pos = ProtoEncode::encode_progmem_bytes(pos PROTO_ENCODE_DEBUG_ARG, 3,
reinterpret_cast<const uint8_t *>(msg.description.progmem_ptr()),
msg.description.size());
pos = ProtoEncode::encode_progmem_string(pos PROTO_ENCODE_DEBUG_ARG, 3, msg.description);
#endif
#ifdef USE_API_USER_DEFINED_ACTION_METADATA
pos = ProtoEncode::encode_progmem_bytes(
pos PROTO_ENCODE_DEBUG_ARG, 4, reinterpret_cast<const uint8_t *>(msg.example.progmem_ptr()), msg.example.size());
pos = ProtoEncode::encode_progmem_string(pos PROTO_ENCODE_DEBUG_ARG, 4, msg.example);
#endif
return pos;
}
@@ -1354,17 +1350,14 @@ uint32_t ListEntitiesServicesArgument::calc_size_msg(const void *self) {
uint8_t *ListEntitiesServicesResponse::encode_msg(const void *self,
uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM) {
const auto &msg = *static_cast<const ListEntitiesServicesResponse *>(self);
pos = ProtoEncode::encode_progmem_bytes(pos PROTO_ENCODE_DEBUG_ARG, 1,
reinterpret_cast<const uint8_t *>(msg.name.progmem_ptr()), msg.name.size());
pos = ProtoEncode::encode_progmem_string(pos PROTO_ENCODE_DEBUG_ARG, 1, msg.name);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
for (auto &it : msg.args) {
pos = ProtoEncode::encode_sub_message(pos PROTO_ENCODE_DEBUG_ARG, 3, it);
}
pos = ProtoEncode::encode_uint32(pos PROTO_ENCODE_DEBUG_ARG, 4, static_cast<uint32_t>(msg.supports_response));
#ifdef USE_API_USER_DEFINED_ACTION_METADATA
pos = ProtoEncode::encode_progmem_bytes(pos PROTO_ENCODE_DEBUG_ARG, 5,
reinterpret_cast<const uint8_t *>(msg.description.progmem_ptr()),
msg.description.size());
pos = ProtoEncode::encode_progmem_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.description);
#endif
return pos;
}
+11
View File
@@ -498,6 +498,17 @@ class ProtoEncode {
progmem_memcpy(pos, data, len);
return pos + len;
}
/// encode_progmem_bytes for a string field that may be in flash.
[[nodiscard]] static inline uint8_t *encode_progmem_string(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM,
uint32_t field_id, const ProgmemStringRef &ref) {
return encode_progmem_bytes(pos PROTO_ENCODE_DEBUG_ARG, field_id,
reinterpret_cast<const uint8_t *>(ref.progmem_ptr()), ref.size());
}
[[nodiscard]] static inline uint8_t *encode_progmem_string_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM,
uint32_t field_id, const ProgmemStringRef &ref) {
return encode_progmem_bytes_force(pos PROTO_ENCODE_DEBUG_ARG, field_id,
reinterpret_cast<const uint8_t *>(ref.progmem_ptr()), ref.size());
}
[[nodiscard]] static inline uint8_t *encode_uint32_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM,
uint32_t field_id, uint32_t value) {
pos = encode_field_raw(pos PROTO_ENCODE_DEBUG_ARG, field_id, 0);
+2 -3
View File
@@ -1285,10 +1285,9 @@ class PointerToStringBufferType(PointerToBufferTypeBase):
return _encode_call(encode_fn, str(tag), f"this->{self.field_name}")
if self.progmem:
return _encode_call(
"encode_progmem_bytes",
"encode_progmem_string",
str(self.number),
f"reinterpret_cast<const uint8_t *>(this->{self.field_name}.progmem_ptr())",
f"this->{self.field_name}.size()",
f"this->{self.field_name}",
force=self.force,
)
if result := self._encode_bytes_with_precomputed_tag(
@@ -419,8 +419,8 @@ def test_progmem_rejected_on_non_bytes_field() -> None:
("force", "max_len", "encode_fn"),
[
(True, 120, "encode_short_progmem_string_force("),
(False, None, "encode_progmem_bytes("),
(True, None, "encode_progmem_bytes_force("),
(False, None, "encode_progmem_string("),
(True, None, "encode_progmem_string_force("),
],
)
def test_progmem_string_field_copies_from_flash(