libcamera: ipa_data_serializer: Add specialization for enums
Instead of handling enums specially in the code generation templates, create a specialization of `IPADataSerializer` that handles enums. Every enum is serialized as a `uint32_t`, with `static_assert` to ensure that every possible value fits. Previously, enums were (de)serialized in `(de)serializer_field()` based on the size of their underlying types. Afer this change, every enum is uniformly handled as a `uint32_t`. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
This commit is contained in:
@@ -61,7 +61,7 @@ T readPOD(std::vector<uint8_t> &vec, size_t pos)
|
||||
|
||||
} /* namespace */
|
||||
|
||||
template<typename T>
|
||||
template<typename T, typename = void>
|
||||
class IPADataSerializer
|
||||
{
|
||||
public:
|
||||
@@ -344,6 +344,52 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<typename E>
|
||||
class IPADataSerializer<E, std::enable_if_t<std::is_enum_v<E>>>
|
||||
{
|
||||
using U = uint32_t;
|
||||
static_assert(sizeof(E) <= sizeof(U));
|
||||
|
||||
public:
|
||||
static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
|
||||
serialize(const E &data, [[maybe_unused]] ControlSerializer *cs = nullptr)
|
||||
{
|
||||
std::vector<uint8_t> dataVec;
|
||||
appendPOD<U>(dataVec, static_cast<U>(data));
|
||||
|
||||
return { dataVec, {} };
|
||||
}
|
||||
|
||||
static E deserialize(std::vector<uint8_t> &data,
|
||||
[[maybe_unused]] ControlSerializer *cs = nullptr)
|
||||
{
|
||||
return deserialize(data.cbegin(), data.cend());
|
||||
}
|
||||
|
||||
static E deserialize(std::vector<uint8_t>::const_iterator dataBegin,
|
||||
std::vector<uint8_t>::const_iterator dataEnd,
|
||||
[[maybe_unused]] ControlSerializer *cs = nullptr)
|
||||
{
|
||||
return static_cast<E>(readPOD<U>(dataBegin, 0, dataEnd));
|
||||
}
|
||||
|
||||
static E deserialize(std::vector<uint8_t> &data,
|
||||
[[maybe_unused]] std::vector<SharedFD> &fds,
|
||||
[[maybe_unused]] ControlSerializer *cs = nullptr)
|
||||
{
|
||||
return deserialize(data.cbegin(), data.cend());
|
||||
}
|
||||
|
||||
static E deserialize(std::vector<uint8_t>::const_iterator dataBegin,
|
||||
std::vector<uint8_t>::const_iterator dataEnd,
|
||||
[[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,
|
||||
[[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
|
||||
[[maybe_unused]] ControlSerializer *cs = nullptr)
|
||||
{
|
||||
return deserialize(dataBegin, dataEnd);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* __DOXYGEN__ */
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
||||
@@ -52,9 +52,6 @@
|
||||
#}
|
||||
{%- macro serialize_call(params, buf, fds) %}
|
||||
{%- for param in params %}
|
||||
{%- if param|is_enum %}
|
||||
static_assert(sizeof({{param|name_full}}) <= 4);
|
||||
{%- endif %}
|
||||
std::vector<uint8_t> {{param.mojom_name}}Buf;
|
||||
{%- if param|has_fd %}
|
||||
std::vector<SharedFD> {{param.mojom_name}}Fds;
|
||||
@@ -62,13 +59,7 @@
|
||||
{%- else %}
|
||||
std::tie({{param.mojom_name}}Buf, std::ignore) =
|
||||
{%- endif %}
|
||||
{%- if param|is_flags %}
|
||||
IPADataSerializer<{{param|name_full}}>::serialize({{param.mojom_name}}
|
||||
{%- elif param|is_enum %}
|
||||
IPADataSerializer<uint32_t>::serialize(static_cast<uint32_t>({{param.mojom_name}})
|
||||
{%- else %}
|
||||
IPADataSerializer<{{param|name}}>::serialize({{param.mojom_name}}
|
||||
{% endif -%}
|
||||
{{- ", &controlSerializer_" if param|needs_control_serializer -}}
|
||||
);
|
||||
{%- endfor %}
|
||||
@@ -107,13 +98,7 @@
|
||||
#}
|
||||
{%- macro deserialize_param(param, pointer, loop, buf, fds, iter, data_size) -%}
|
||||
{{"*" if pointer}}{{param.mojom_name}} =
|
||||
{%- if param|is_flags %}
|
||||
IPADataSerializer<{{param|name_full}}>::deserialize(
|
||||
{%- elif param|is_enum %}
|
||||
static_cast<{{param|name_full}}>(IPADataSerializer<uint32_t>::deserialize(
|
||||
{%- else %}
|
||||
IPADataSerializer<{{param|name}}>::deserialize(
|
||||
{%- endif %}
|
||||
{{buf}}{{- ".cbegin()" if not iter}} + {{param.mojom_name}}Start,
|
||||
{%- if loop.last and not iter %}
|
||||
{{buf}}.cend()
|
||||
@@ -137,7 +122,7 @@ IPADataSerializer<{{param|name}}>::deserialize(
|
||||
{%- if param|needs_control_serializer %}
|
||||
&controlSerializer_
|
||||
{%- endif -%}
|
||||
){{")" if param|is_enum and not param|is_flags}};
|
||||
);
|
||||
{%- endmacro -%}
|
||||
|
||||
|
||||
|
||||
@@ -32,15 +32,7 @@
|
||||
{%- if field|is_pod or field|is_enum %}
|
||||
std::vector<uint8_t> {{field.mojom_name}};
|
||||
std::tie({{field.mojom_name}}, std::ignore) =
|
||||
{%- if field|is_pod %}
|
||||
IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}});
|
||||
{%- elif field|is_flags %}
|
||||
IPADataSerializer<{{field|name_full}}>::serialize(data.{{field.mojom_name}});
|
||||
{%- elif field|is_enum_scoped %}
|
||||
IPADataSerializer<uint{{field|bit_width}}_t>::serialize(static_cast<uint{{field|bit_width}}_t>(data.{{field.mojom_name}}));
|
||||
{%- elif field|is_enum %}
|
||||
IPADataSerializer<uint{{field|bit_width}}_t>::serialize(data.{{field.mojom_name}});
|
||||
{%- endif %}
|
||||
retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end());
|
||||
{%- elif field|is_fd %}
|
||||
std::vector<uint8_t> {{field.mojom_name}};
|
||||
@@ -98,13 +90,7 @@
|
||||
{% if field|is_pod or field|is_enum %}
|
||||
{%- set field_size = (field|bit_width|int / 8)|int %}
|
||||
{{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}}
|
||||
{%- if field|is_pod %}
|
||||
ret.{{field.mojom_name}} = IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field_size}});
|
||||
{%- elif field|is_flags %}
|
||||
ret.{{field.mojom_name}} = IPADataSerializer<{{field|name_full}}>::deserialize(m, m + {{field_size}});
|
||||
{%- else %}
|
||||
ret.{{field.mojom_name}} = static_cast<{{field|name_full}}>(IPADataSerializer<uint{{field|bit_width}}_t>::deserialize(m, m + {{field_size}}));
|
||||
{%- endif %}
|
||||
{%- if not loop.last %}
|
||||
m += {{field_size}};
|
||||
dataSize -= {{field_size}};
|
||||
|
||||
Reference in New Issue
Block a user