From ce0c7bf535a9a462cda1b8118963dc4bc87af05f Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 23 Jul 2025 14:35:31 +0200 Subject: [PATCH 1/2] Refs #23504: Move is_plain() to TypeCdrAux Signed-off-by: Mario Dominguez --- .../idl/templates/DDSPubSubTypeHeader.stg | 97 +------------------ .../idl/templates/DDSPubSubTypeSource.stg | 36 ++++++- .../idl/templates/TypesCdrAuxHeader.stg | 37 +++++++ .../idl/templates/TypesCdrAuxHeaderImpl.stg | 48 +++++++++ 4 files changed, 119 insertions(+), 99 deletions(-) diff --git a/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg b/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg index 1aab22fd..4cc538f1 100644 --- a/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg +++ b/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg @@ -63,43 +63,6 @@ $typedefs : { typedef |typedef $typedef.typedefContentTypeCode.cppTypename$ $typ struct_type(ctx, parent, struct, member_list) ::= << $member_list$ -$if(struct.isPlain)$ -$if(struct.members)$ -#ifndef SWIG -namespace detail { - -template -struct $struct.name$_rob -{ - friend constexpr typename Tag::type get( - Tag) - { - return M; - } - -}; - -struct $struct.name$_f -{ - typedef $last(struct.members).typecode.cppTypename$ $struct.name$::* type; - friend constexpr type get( - $struct.name$_f); -}; - -template struct $struct.name$_rob<$struct.name$_f, &$struct.name$::m_$last(struct.members).name$>; - -template -inline size_t constexpr $struct.name$_offset_of() -{ - return ((::size_t) &reinterpret_cast((((T*)0)->*get(Tag())))); -} - -} // namespace detail -#endif // ifndef SWIG - -$endif$ -$endif$ - $if(!struct.parent.annotatedAsNested)$ /*! * @brief This class represents the TopicDataType of the type $struct.name$ defined by the user in the IDL file. @@ -156,23 +119,8 @@ public: #ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN - eProsima_user_DllExport inline bool is_plain( - eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override - { - $if(struct.isPlain)$ - if (data_representation == eprosima::fastdds::dds::DataRepresentationId_t::XCDR2_DATA_REPRESENTATION) - { - return is_plain_xcdrv2_impl(); - } - else - { - return is_plain_xcdrv1_impl(); - } - $else$ - static_cast(data_representation); - return false; - $endif$ - } + eProsima_user_DllExport bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override; #endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN @@ -191,47 +139,6 @@ private: eprosima::fastdds::MD5 md5_; unsigned char* key_buffer_; -$if(struct.isPlain)$ - - static constexpr bool is_plain_xcdrv1_impl() - { - $if(struct.members)$ - return $struct.maxXCDRv1PlainTypeSerializedSize$ULL == - (detail::$struct.name$_offset_of<$struct.name$, detail::$struct.name$_f>() + - sizeof($last(struct.members).typecode.cppTypename$)); - $elseif(struct.inheritance)$ - $if(struct.inheritance.isPlain)$ - return $struct.maxXCDRv1PlainTypeSerializedSize$ULL == - (detail::$struct.inheritance.name$_offset_of<$struct.inheritance.name$, detail::$struct.inheritance.name$_f>() + - sizeof($last(struct.inheritance.members).typecode.cppTypename$)); - $else$ - return true; - $endif$ - $else$ - return true; - $endif$ - } - - static constexpr bool is_plain_xcdrv2_impl() - { - $if(struct.members)$ - return $struct.maxXCDRv2PlainTypeSerializedSize$ULL == - (detail::$struct.name$_offset_of<$struct.name$, detail::$struct.name$_f>() + - sizeof($last(struct.members).typecode.cppTypename$)); - $elseif(struct.inheritance)$ - $if(struct.inheritance.isPlain)$ - return $struct.maxXCDRv2PlainTypeSerializedSize$ULL == - (detail::$struct.inheritance.name$_offset_of<$struct.inheritance.name$, detail::$struct.inheritance.name$_f>() + - sizeof($last(struct.inheritance.members).typecode.cppTypename$)); - $else$ - return true; - $endif$ - $else$ - return true; - $endif$ - } - -$endif$ }; $endif$ >> diff --git a/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeSource.stg b/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeSource.stg index 0df5d749..b906b3f1 100644 --- a/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeSource.stg +++ b/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeSource.stg @@ -33,6 +33,19 @@ using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; +$if(ctx.anyCdr)$ +namespace eprosima { +namespace fastcdr { + +$ctx.types:{ type | $if(type.inScope)$$if(type.typeCode.isStructType)$ +bool is_$type.typeCode.cScopedname$_cdr_plain( + DataRepresentationId_t data_representation); +$endif$$endif$ +}; separator="\n"$ +} // namespace fastcdr +} // namespace eprosima +$endif$ + $definitions; separator="\n"$ $if(ctx.thereIsStructOrUnion || ctx.thereIsInterface)$ @@ -170,6 +183,21 @@ void $struct.name$PubSubType::delete_data( delete(reinterpret_cast<::$struct.scopedname$*>(data)); } +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + bool $struct.name$PubSubType::is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const + { + $if(struct.isPlain)$ + return eprosima::fastcdr::is_$struct.cScopedname$_cdr_plain(data_representation); + $else$ + static_cast(data_representation); + return false; + $endif$ + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + bool $struct.name$PubSubType::compute_key( SerializedPayload_t& payload, InstanceHandle_t& handle, @@ -330,17 +358,17 @@ public: { // Convert DATA to pointer of your type type* p_type = static_cast(data); - + // Object that manages the raw buffer. eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); - + // Object that deserializes the data. eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); - + // Deserialize encapsulation. deser.read_encapsulation(); payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; - + // Deserialize the object. deser \>> *p_type; } diff --git a/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeader.stg b/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeader.stg index 666d1c84..34083c65 100644 --- a/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeader.stg +++ b/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeader.stg @@ -57,4 +57,41 @@ eProsima_user_DllExport void serialize_key( eprosima::fastcdr::Cdr& scdr, const $struct.scopedname$& data); +$if(struct.isPlain)$ +$if(struct.members)$ +#ifndef SWIG +namespace detail { + +template +struct $struct.name$_rob +{ + friend constexpr typename Tag::type get( + Tag) + { + return M; + } + +}; + +struct $struct.name$_f +{ + typedef $last(struct.members).typecode.cppTypename$ $struct.scopedname$::* type; + friend constexpr type get( + $struct.name$_f); +}; + +template struct $struct.name$_rob<$struct.name$_f, &$struct.scopedname$::m_$last(struct.members).name$>; + +template +inline std::size_t constexpr $struct.name$_offset_of() +{ + return ((std::size_t) &reinterpret_cast((((T*)0)->*get(Tag())))); +} + +} // namespace detail +#endif // ifndef SWIG + +$endif$ +$endif$ + >> diff --git a/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg b/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg index 54053713..9d962410 100644 --- a/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg +++ b/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg @@ -29,6 +29,7 @@ $if(ctx.cdr)$ #include #include +#include $endif$ #include @@ -49,6 +50,53 @@ $"\n"$ struct_type(ctx, parent, struct, extensions, member_list) ::= << $member_list$ $if(ctx.anyCdr)$ + +eProsima_user_DllExport bool is_$struct.cScopedname$_cdr_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) +{ + $if(struct.isPlain)$ + if (data_representation == eprosima::fastdds::dds::DataRepresentationId_t::XCDR2_DATA_REPRESENTATION) + { + $if(struct.members)$ + return $struct.maxXCDRv2PlainTypeSerializedSize$ULL == + (detail::$struct.name$_offset_of<$struct.scopedname$, detail::$struct.name$_f>() + + sizeof($last(struct.members).typecode.cppTypename$)); + $elseif(struct.inheritance)$ + $if(struct.inheritance.isPlain)$ + return $struct.maxXCDRv2PlainTypeSerializedSize$ULL == + (detail::$struct.inheritance.name$_offset_of<$struct.inheritance.scopedname$, detail::$struct.inheritance.name$_f>() + + sizeof($last(struct.inheritance.members).typecode.cppTypename$)); + $else$ + return true; + $endif$ + $else$ + return true; + $endif$ + } + else + { + $if(struct.members)$ + return $struct.maxXCDRv1PlainTypeSerializedSize$ULL == + (detail::$struct.name$_offset_of<$struct.scopedname$, detail::$struct.name$_f>() + + sizeof($last(struct.members).typecode.cppTypename$)); + $elseif(struct.inheritance)$ + $if(struct.inheritance.isPlain)$ + return $struct.maxXCDRv1PlainTypeSerializedSize$ULL == + (detail::$struct.inheritance.name$_offset_of<$struct.inheritance.scopedname$, detail::$struct.inheritance.name$_f>() + + sizeof($last(struct.inheritance.members).typecode.cppTypename$)); + $else$ + return true; + $endif$ + $else$ + return true; + $endif$ + } + $else$ + static_cast(data_representation); + return false; + $endif$ +} + template<> eProsima_user_DllExport size_t calculate_serialized_size( eprosima::fastcdr::CdrSizeCalculator& calculator, From 71126b1f67a4fc712b63198f30d0d4603da37c23 Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Wed, 23 Jul 2025 14:36:50 +0200 Subject: [PATCH 2/2] Refs #23504: specialize the new (de)serialize_array() methods for structs, unions and bitsets Signed-off-by: Mario Dominguez --- .../idl/templates/TypesCdrAuxHeaderImpl.stg | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg b/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg index 9d962410..8b6c2fc2 100644 --- a/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg +++ b/src/main/java/com/eprosima/fastdds/idl/templates/TypesCdrAuxHeaderImpl.stg @@ -156,6 +156,44 @@ eProsima_user_DllExport void serialize( scdr.end_serialize_type(current_state); } +#if FASTCDR_VERSION_MAJOR > 2 +template<> +eProsima_user_DllExport void serialize_array( + eprosima::fastcdr::Cdr& scdr, + const $struct.scopedname$* array_ptr, + const std::size_t array_size) +{ + if (array_size > 0) + { + using namespace ::eprosima::fastdds::dds; + DataRepresentationId_t data_representation = (scdr.get_cdr_version() == eprosima::fastcdr::CdrVersion::XCDRv1 ? + DataRepresentationId_t::XCDR_DATA_REPRESENTATION : DataRepresentationId_t::XCDR2_DATA_REPRESENTATION); + + if (is_$struct.cScopedname$_cdr_plain(data_representation) && + sizeof($struct.scopedname$) == $struct.cScopedname$_max_cdr_typesize) + { + // Serialize the first element + // to ensure correct alignment + scdr.serialize( + array_ptr[0]); + + ++array_ptr; + + std::memcpy( + scdr.get_current_position(), + array_ptr, + (array_size - 1) * sizeof($struct.scopedname$)); + + scdr.jump((array_size -1) * sizeof($struct.scopedname$)); + } + else + { + scdr.serialize_array(array_ptr, array_size); + } + } +} +#endif // FASTCDR_VERSION_MAJOR > 2 + template<> eProsima_user_DllExport void deserialize( eprosima::fastcdr::Cdr& cdr, @@ -195,6 +233,42 @@ eProsima_user_DllExport void deserialize( }); } +#if FASTCDR_VERSION_MAJOR > 2 +template<> +eProsima_user_DllExport void deserialize_array( + eprosima::fastcdr::Cdr& scdr, + $struct.scopedname$* array_ptr, + const std::size_t array_size) +{ + if (array_size > 0) + { + using namespace ::eprosima::fastdds::dds; + DataRepresentationId_t data_representation = (scdr.get_cdr_version() == eprosima::fastcdr::CdrVersion::XCDRv1 ? + DataRepresentationId_t::XCDR_DATA_REPRESENTATION : DataRepresentationId_t::XCDR2_DATA_REPRESENTATION); + + if (is_$struct.cScopedname$_cdr_plain(data_representation) && + sizeof($struct.scopedname$) == $struct.cScopedname$_max_cdr_typesize) + { + // Deserialize the first element + // accounting for alignment + scdr.deserialize_array(&array_ptr[0], 1); + ++array_ptr; + + std::memcpy( + reinterpret_cast(array_ptr), + scdr.get_current_position(), + (array_size - 1) * sizeof($struct.scopedname$)); + + scdr.jump((array_size - 1) * sizeof($struct.scopedname$)); + } + else + { + scdr.deserialize_array(array_ptr, array_size); + } + } +} +#endif // FASTCDR_VERSION_MAJOR > 2 + void serialize_key( eprosima::fastcdr::Cdr& scdr, const $struct.scopedname$& data) @@ -293,6 +367,19 @@ eProsima_user_DllExport void serialize( scdr << bitset; } +#if FASTCDR_VERSION_MAJOR > 2 +template<> +eProsima_user_DllExport void serialize_array( + eprosima::fastcdr::Cdr& scdr, + const $bitset.scopedname$* array_ptr, + const std::size_t array_size) +{ + // Optimization for serialization + // of arrays of bitsets not yet supported + scdr.serialize_array(array_ptr, array_size); +} +#endif // FASTCDR_VERSION_MAJOR > 2 + template<> eProsima_user_DllExport void deserialize( eprosima::fastcdr::Cdr& dcdr, @@ -312,6 +399,19 @@ eProsima_user_DllExport void deserialize( bitset \>>= $bitfield.spec.bitSize$; }; separator="\n"$ } + +#if FASTCDR_VERSION_MAJOR > 2 +template<> +eProsima_user_DllExport void deserialize_array( + eprosima::fastcdr::Cdr& scdr, + $bitset.scopedname$* array_ptr, + const std::size_t array_size) +{ + // Optimization for deserialization + // of arrays of bitsets not yet supported + scdr.deserialize_array(array_ptr, array_size); +} +#endif // FASTCDR_VERSION_MAJOR > 2 $endif$ >> @@ -397,6 +497,19 @@ eProsima_user_DllExport void serialize( scdr.end_serialize_type(current_state); } +#if FASTCDR_VERSION_MAJOR > 2 +template<> +eProsima_user_DllExport void serialize_array( + eprosima::fastcdr::Cdr& scdr, + const $union.scopedname$* array_ptr, + const std::size_t array_size) +{ + // Optimization for serialization + // of arrays of unions not yet supported + scdr.serialize_array(array_ptr, array_size); +} +#endif // FASTCDR_VERSION_MAJOR > 2 + template<> eProsima_user_DllExport void deserialize( eprosima::fastcdr::Cdr& cdr, @@ -462,6 +575,19 @@ eProsima_user_DllExport void deserialize( return ret_value; }); } + +#if FASTCDR_VERSION_MAJOR > 2 +template<> +eProsima_user_DllExport void deserialize_array( + eprosima::fastcdr::Cdr& scdr, + $union.scopedname$* array_ptr, + const std::size_t array_size) +{ + // Optimization for deserialization + // of arrays of unions not yet supported + scdr.deserialize_array(array_ptr, array_size); +} +#endif // FASTCDR_VERSION_MAJOR > 2 $endif$ >>