diff --git a/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/TypeSupport.hpp b/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/TypeSupport.hpp index 6323ca35a0..762d888017 100644 --- a/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/TypeSupport.hpp +++ b/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/TypeSupport.hpp @@ -42,6 +42,9 @@ class TypeSupport : public rmw_fastrtps_shared_cpp::TypeSupport bool deserializeROSmessage( eprosima::fastcdr::Cdr & deser, void * ros_message, const void * impl) const override; + bool getKeyHashFromROSmessage( + void * ros_message, eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, bool force_md5, const void * impl) const override; + TypeSupport(); protected: @@ -49,6 +52,7 @@ class TypeSupport : public rmw_fastrtps_shared_cpp::TypeSupport private: const message_type_support_callbacks_t * members_; + message_type_support_key_callbacks_t key_callbacks_; bool has_data_; }; diff --git a/rmw_fastrtps_cpp/src/type_support_common.cpp b/rmw_fastrtps_cpp/src/type_support_common.cpp index 4e5dff1dc1..79d5e58122 100644 --- a/rmw_fastrtps_cpp/src/type_support_common.cpp +++ b/rmw_fastrtps_cpp/src/type_support_common.cpp @@ -28,11 +28,14 @@ TypeSupport::TypeSupport() m_isGetKeyDefined = false; max_size_bound_ = false; is_plain_ = false; + key_is_unbounded_ = false; + key_max_serialized_size_ = 0; } void TypeSupport::set_members(const message_type_support_callbacks_t * members) { members_ = members; + m_isGetKeyDefined = members->get_key_type_support(&this->key_callbacks_); #ifdef ROSIDL_TYPESUPPORT_FASTRTPS_HAS_PLAIN_TYPES char bounds_info; @@ -53,6 +56,23 @@ void TypeSupport::set_members(const message_type_support_callbacks_t * members) has_data_ = true; } + if (m_isGetKeyDefined) + { + std::cout << "Calculating max_serialized_key_size " << (&key_callbacks_.max_serialized_key_size) << std::endl; + this->key_max_serialized_size_ = this->key_callbacks_.max_serialized_key_size(0, this->key_is_unbounded_); + std::cout << "FInishing max_serialized_key_size" << std::endl; + if (!this->key_is_unbounded_) + { + this->key_buffer_.reserve(this->key_max_serialized_size_); + } + else + { + std::cout << "KEY is UNBOUNDED" << std::endl; + } + + std::cout << "this->key_max_serialized_size_ " << this->key_max_serialized_size_ << std::endl; + } + // Total size is encapsulation size + data size m_typeSize = 4 + data_size; // Account for RTPS submessage alignment @@ -124,6 +144,71 @@ bool TypeSupport::deserializeROSmessage( return true; } +bool TypeSupport::getKeyHashFromROSmessage( + void * ros_message, + eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, + bool force_md5, + const void * impl) const +{ + assert(ros_message); + (void)impl; + + /*if (capacity < 16) + { + throw std::runtime_error("Not enough capacity to serialize key"); + }*/ + + //! retrieve estimated serialized size in case key is unbounded + if (this->key_is_unbounded_) + { + std::cout << "Static Re-stimating serialize size. Before " << this->key_max_serialized_size_ << std::endl; + this->key_max_serialized_size_ = key_callbacks_.get_serialized_key_size(ros_message, 0); + std::cout << "Static Re-stimating serialize size. After " << this->key_max_serialized_size_ << std::endl; + this->key_buffer_.reserve(this->key_max_serialized_size_); + std::cout << "Static New key buffer capacity " << this->key_buffer_.capacity() << std::endl; + } + + eprosima::fastcdr::FastBuffer fast_buffer( + reinterpret_cast(this->key_buffer_.data()), + this->key_max_serialized_size_); + + eprosima::fastcdr::Cdr ser( + fast_buffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, eprosima::fastcdr::Cdr::DDS_CDR); + + key_callbacks_.cdr_serialize_key(ros_message, ser); + + //! check for md5 + if (force_md5 || this->key_max_serialized_size_ > 16) + { + + this->md5_.init(); + +#if FASTCDR_VERSION_MAJOR == 1 + this->md5_.update(this->key_buffer_.data(), static_cast(ser.getSerializedDataLength())); +#else + this->md5_.update(this->key_buffer_.data(), static_cast(ser.get_serialized_data_length())); +#endif // FASTCDR_VERSION_MAJOR == 1 + + this->md5_.finalize(); + + for (uint8_t i = 0; i < 16; ++i) + { + ihandle->value[i] = md5_.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + ihandle->value[i] = this->key_buffer_[i]; + } + } + + std::cout << "\nFinishing static::getKeyHashFromROSmessage() " << ihandle->value << std::endl; + + return true; +} + MessageTypeSupport::MessageTypeSupport(const message_type_support_callbacks_t * members) { assert(members); diff --git a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/MessageTypeSupport_impl.hpp b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/MessageTypeSupport_impl.hpp index 95f48e996f..6e9e11c3f0 100644 --- a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/MessageTypeSupport_impl.hpp +++ b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/MessageTypeSupport_impl.hpp @@ -56,10 +56,17 @@ MessageTypeSupport::MessageTypeSupport( // Encapsulation size this->m_typeSize = 4; if (this->members_->member_count_ != 0) { - this->m_typeSize += static_cast(this->calculateMaxSerializedSize(members, 0)); + this->m_typeSize += static_cast(this->calculateMaxSerializedSize(members, 0, this->key_max_serialized_size_)); } else { this->m_typeSize++; } + + if (this->key_max_serialized_size_ != 0) + { + this->m_isGetKeyDefined = true; + this->key_buffer_.reserve(this->key_max_serialized_size_); + } + // Account for RTPS submessage alignment this->m_typeSize = (this->m_typeSize + 3) & ~3; } diff --git a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/ServiceTypeSupport_impl.hpp b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/ServiceTypeSupport_impl.hpp index 45e3fc6028..2eaf321558 100644 --- a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/ServiceTypeSupport_impl.hpp +++ b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/ServiceTypeSupport_impl.hpp @@ -55,10 +55,17 @@ RequestTypeSupport::RequestTypeSupport( // Encapsulation size this->m_typeSize = 4; if (this->members_->member_count_ != 0) { - this->m_typeSize += static_cast(this->calculateMaxSerializedSize(this->members_, 0)); + this->m_typeSize += static_cast(this->calculateMaxSerializedSize(this->members_, 0, this->key_max_serialized_size_)); } else { this->m_typeSize++; } + + if (this->key_max_serialized_size_ != 0) + { + this->m_isGetKeyDefined = true; + this->key_buffer_.reserve(this->key_max_serialized_size_); + } + // Account for RTPS submessage alignment this->m_typeSize = (this->m_typeSize + 3) & ~3; } @@ -88,10 +95,17 @@ ResponseTypeSupport::ResponseTypeSupport // Encapsulation size this->m_typeSize = 4; if (this->members_->member_count_ != 0) { - this->m_typeSize += static_cast(this->calculateMaxSerializedSize(this->members_, 0)); + this->m_typeSize += static_cast(this->calculateMaxSerializedSize(this->members_, 0, this->key_max_serialized_size_)); } else { this->m_typeSize++; } + + if (this->key_max_serialized_size_ != 0) + { + this->m_isGetKeyDefined = true; + this->key_buffer_.reserve(this->key_max_serialized_size_); + } + // Account for RTPS submessage alignment this->m_typeSize = (this->m_typeSize + 3) & ~3; } diff --git a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/TypeSupport.hpp b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/TypeSupport.hpp index 270839275e..84142f41c2 100644 --- a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/TypeSupport.hpp +++ b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/TypeSupport.hpp @@ -138,6 +138,10 @@ class TypeSupportProxy : public rmw_fastrtps_shared_cpp::TypeSupport bool deserializeROSmessage( eprosima::fastcdr::Cdr & deser, void * ros_message, const void * impl) const override; + + bool getKeyHashFromROSmessage( + void * ros_message, eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, bool force_md5, const void * impl) const override; + }; class BaseTypeSupport : public rmw_fastrtps_shared_cpp::TypeSupport @@ -170,10 +174,13 @@ class TypeSupport : public BaseTypeSupport bool deserializeROSmessage( eprosima::fastcdr::Cdr & deser, void * ros_message, const void * impl) const override; + bool getKeyHashFromROSmessage( + void * ros_message, eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, bool force_md5, const void * impl) const override; + protected: explicit TypeSupport(const void * ros_type_support); - size_t calculateMaxSerializedSize(const MembersType * members, size_t current_alignment); + size_t calculateMaxSerializedSize(const MembersType * members, size_t current_alignment, size_t& max_key_size); const MembersType * members_; @@ -181,7 +188,8 @@ class TypeSupport : public BaseTypeSupport size_t getEstimatedSerializedSize( const MembersType * members, const void * ros_message, - size_t current_alignment) const; + size_t current_alignment, + bool compute_key_members_only = false) const; bool serializeROSmessage( eprosima::fastcdr::Cdr & ser, @@ -192,6 +200,18 @@ class TypeSupport : public BaseTypeSupport eprosima::fastcdr::Cdr & deser, const MembersType * members, void * ros_message) const; + + bool serializeKeyROSmessage( + eprosima::fastcdr::Cdr & ser, + const MembersType * members, + void * ros_message, + bool check_if_member_is_key) const; + + bool getKeyHashFromROSmessage( + const MembersType * members, + void * ros_message, + eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, + bool force_md5) const; }; } // namespace rmw_fastrtps_dynamic_cpp diff --git a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/TypeSupport_impl.hpp b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/TypeSupport_impl.hpp index f673fe0735..ae428ffe98 100644 --- a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/TypeSupport_impl.hpp +++ b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/TypeSupport_impl.hpp @@ -67,6 +67,8 @@ TypeSupport::TypeSupport(const void * ros_type_support) m_isGetKeyDefined = false; max_size_bound_ = false; is_plain_ = false; + key_max_serialized_size_ = 0; + key_is_unbounded_ = false; } // C++ specialization @@ -299,6 +301,165 @@ bool TypeSupport::serializeROSmessage( return true; } +template +bool TypeSupport::serializeKeyROSmessage( + eprosima::fastcdr::Cdr & ser, + const MembersType * members, + void * ros_message, + bool check_if_member_is_key) const +{ + for (uint32_t i = 0; i < members->member_count_; ++i) { + const auto member = members->members_ + i; + + if (check_if_member_is_key && !member->is_key_) + { + continue; + } + + void * field = const_cast(static_cast(ros_message)) + member->offset_; + switch (member->type_id_) { + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BOOL: + if (!member->is_array_) { + // don't cast to bool here because if the bool is + // uninitialized the random value can't be deserialized + ser << (*static_cast(field) ? true : false); + } else { + serialize_field(member, field, ser); + } + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BYTE: + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT8: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_CHAR: + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT8: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT32: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT64: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT16: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT16: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT32: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT32: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT64: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT64: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_WSTRING: + serialize_field(member, field, ser); + break; + case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE: + { + auto sub_members = static_cast(member->members_->data); + if (!member->is_array_) { + serializeKeyROSmessage(ser, sub_members, field, false); + } else { + size_t array_size = 0; + + if (member->array_size_ && !member->is_upper_bound_) { + array_size = member->array_size_; + } else { + if (!member->size_function) { + RMW_SET_ERROR_MSG("unexpected error: size function is null"); + return false; + } + array_size = member->size_function(field); + + // Serialize length + ser << (uint32_t)array_size; + } + + if (array_size != 0 && !member->get_function) { + RMW_SET_ERROR_MSG("unexpected error: get_function function is null"); + return false; + } + for (size_t index = 0; index < array_size; ++index) { + serializeKeyROSmessage(ser, sub_members, member->get_function(field, index), false); + } + } + } + break; + default: + throw std::runtime_error("unknown type"); + } + } + + return true; +} + +template +bool TypeSupport::getKeyHashFromROSmessage( + const MembersType * members, + void * ros_message, + eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, + bool force_md5) const +{ + assert(members); + assert(ros_message); + + // get estimated serialized size in case key is unbounded + if (this->key_is_unbounded_) + { + this->key_max_serialized_size_ = this->getEstimatedSerializedSize(members, ros_message, 0, true); + key_buffer_.reserve(this->key_max_serialized_size_); + } + + eprosima::fastcdr::FastBuffer buffer( + reinterpret_cast(this->key_buffer_.data()), + this->key_max_serialized_size_); + + eprosima::fastcdr::Cdr ser( + buffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, eprosima::fastcdr::Cdr::DDS_CDR); + + // serialize + serializeKeyROSmessage(ser, members_, ros_message, true); + + // check for md5 + if (force_md5 || this->key_max_serialized_size_ > 16) + { + md5_.init(); + +#if FASTCDR_VERSION_MAJOR == 1 + md5_.update(this->key_buffer_.data(), static_cast(ser.getSerializedDataLength())); +#else + md5_.update(this->key_buffer_.data(), static_cast(ser.get_serialized_data_length())); +#endif // FASTCDR_VERSION_MAJOR == 1 + + md5_.finalize(); + + for (uint8_t i = 0; i < 16; ++i) + { + ihandle->value[i] = md5_.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + ihandle->value[i] = this->key_buffer_[i]; + } + } + + return true; +} + // C++ specialization template size_t next_field_align( @@ -465,7 +626,8 @@ template size_t TypeSupport::getEstimatedSerializedSize( const MembersType * members, const void * ros_message, - size_t current_alignment) const + size_t current_alignment, + bool compute_key_members_only) const { assert(members); assert(ros_message); @@ -475,6 +637,12 @@ size_t TypeSupport::getEstimatedSerializedSize( for (uint32_t i = 0; i < members->member_count_; ++i) { const auto member = members->members_ + i; void * field = const_cast(static_cast(ros_message)) + member->offset_; + + if (compute_key_members_only && !member->is_key_) + { + continue; + } + switch (member->type_id_) { case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_BOOL: current_alignment = next_field_align(member, field, current_alignment); @@ -521,7 +689,7 @@ size_t TypeSupport::getEstimatedSerializedSize( { auto sub_members = static_cast(member->members_->data); if (!member->is_array_) { - current_alignment += getEstimatedSerializedSize(sub_members, field, current_alignment); + current_alignment += getEstimatedSerializedSize(sub_members, field, current_alignment, compute_key_members_only); } else { size_t array_size = 0; @@ -546,7 +714,8 @@ size_t TypeSupport::getEstimatedSerializedSize( current_alignment += getEstimatedSerializedSize( sub_members, member->get_function(field, index), - current_alignment); + current_alignment, + compute_key_members_only); } } } @@ -816,7 +985,7 @@ bool TypeSupport::deserializeROSmessage( template size_t TypeSupport::calculateMaxSerializedSize( - const MembersType * members, size_t current_alignment) + const MembersType * members, size_t current_alignment, size_t& max_serialized_key_size) { assert(members); @@ -829,6 +998,13 @@ size_t TypeSupport::calculateMaxSerializedSize( const auto * member = members->members_ + i; size_t array_size = 1; + bool member_is_key = false; + + if (member->is_key_) + { + member_is_key = true; + } + if (member->is_array_) { array_size = member->array_size_; @@ -842,6 +1018,12 @@ size_t TypeSupport::calculateMaxSerializedSize( this->is_plain_ = false; current_alignment += padding + eprosima::fastcdr::Cdr::alignment(current_alignment, padding); + + if (member_is_key) + { + max_serialized_key_size += padding + + eprosima::fastcdr::Cdr::alignment(max_serialized_key_size, padding); + } } } @@ -854,12 +1036,22 @@ size_t TypeSupport::calculateMaxSerializedSize( case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT8: last_member_size = array_size * sizeof(int8_t); current_alignment += array_size * sizeof(int8_t); + if (member_is_key) + { + max_serialized_key_size += array_size * sizeof(uint8_t) + + eprosima::fastcdr::Cdr::alignment(max_serialized_key_size, sizeof(uint8_t)); + } break; case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT16: case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_UINT16: last_member_size = array_size * sizeof(uint16_t); current_alignment += array_size * sizeof(uint16_t) + eprosima::fastcdr::Cdr::alignment(current_alignment, sizeof(uint16_t)); + if (member_is_key) + { + max_serialized_key_size += array_size * sizeof(uint16_t) + + eprosima::fastcdr::Cdr::alignment(max_serialized_key_size, sizeof(uint16_t)); + } break; case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT32: case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT32: @@ -867,6 +1059,11 @@ size_t TypeSupport::calculateMaxSerializedSize( last_member_size = array_size * sizeof(uint32_t); current_alignment += array_size * sizeof(uint32_t) + eprosima::fastcdr::Cdr::alignment(current_alignment, sizeof(uint32_t)); + if (member_is_key) + { + max_serialized_key_size += array_size * sizeof(uint32_t) + + eprosima::fastcdr::Cdr::alignment(max_serialized_key_size, sizeof(uint32_t)); + } break; case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_FLOAT64: case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_INT64: @@ -874,6 +1071,11 @@ size_t TypeSupport::calculateMaxSerializedSize( last_member_size = array_size * sizeof(uint64_t); current_alignment += array_size * sizeof(uint64_t) + eprosima::fastcdr::Cdr::alignment(current_alignment, sizeof(uint64_t)); + if (member_is_key) + { + max_serialized_key_size += array_size * sizeof(uint64_t) + + eprosima::fastcdr::Cdr::alignment(max_serialized_key_size, sizeof(uint64_t)); + } break; case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING: case ::rosidl_typesupport_introspection_cpp::ROS_TYPE_WSTRING: @@ -886,6 +1088,13 @@ size_t TypeSupport::calculateMaxSerializedSize( current_alignment += padding + eprosima::fastcdr::Cdr::alignment(current_alignment, padding) + character_size * (member->string_upper_bound_ + 1); + if (member_is_key) + { + key_is_unbounded_ = true; + max_serialized_key_size += padding + + eprosima::fastcdr::Cdr::alignment(max_serialized_key_size, padding) + + character_size * (member->string_upper_bound_ + 1); + } } } break; @@ -893,9 +1102,16 @@ size_t TypeSupport::calculateMaxSerializedSize( { auto sub_members = static_cast(member->members_->data); for (size_t index = 0; index < array_size; ++index) { - size_t curr = calculateMaxSerializedSize(sub_members, current_alignment); + // We set the type as keyed + // if any of the parent struct members are keyed + size_t dummy_max_serialized_key_size; + size_t curr = calculateMaxSerializedSize(sub_members, current_alignment, dummy_max_serialized_key_size); current_alignment += curr; last_member_size += curr; + if (member_is_key) + { + max_serialized_key_size += curr; + } } } break; @@ -988,6 +1204,25 @@ bool TypeSupport::deserializeROSmessage( return true; } +template +bool TypeSupport::getKeyHashFromROSmessage( + void * ros_message, eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, bool force_md5, const void * impl) const +{ + + assert(ros_message); + assert(members_); + + bool ret = false; + + (void)impl; + if (members_->member_count_ != 0) + { + ret = TypeSupport::getKeyHashFromROSmessage(members_, ros_message, ihandle, force_md5); + } + + return ret; +} + } // namespace rmw_fastrtps_dynamic_cpp #endif // RMW_FASTRTPS_DYNAMIC_CPP__TYPESUPPORT_IMPL_HPP_ diff --git a/rmw_fastrtps_dynamic_cpp/src/type_support_proxy.cpp b/rmw_fastrtps_dynamic_cpp/src/type_support_proxy.cpp index 43c3b0ac42..14a478d127 100644 --- a/rmw_fastrtps_dynamic_cpp/src/type_support_proxy.cpp +++ b/rmw_fastrtps_dynamic_cpp/src/type_support_proxy.cpp @@ -23,6 +23,7 @@ TypeSupportProxy::TypeSupportProxy(rmw_fastrtps_shared_cpp::TypeSupport * inner_ m_typeSize = inner_type->m_typeSize; is_plain_ = inner_type->is_plain(); max_size_bound_ = inner_type->is_bounded(); + m_isGetKeyDefined = inner_type->m_isGetKeyDefined; } size_t TypeSupportProxy::getEstimatedSerializedSize( @@ -46,4 +47,11 @@ bool TypeSupportProxy::deserializeROSmessage( return type_impl->deserializeROSmessage(deser, ros_message, impl); } +bool TypeSupportProxy::getKeyHashFromROSmessage( + void * ros_message, eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, bool force_md5, const void * impl) const +{ + auto type_impl = static_cast(impl); + return type_impl->getKeyHashFromROSmessage(ros_message, ihandle, force_md5, impl); +} + } // namespace rmw_fastrtps_dynamic_cpp diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/TypeSupport.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/TypeSupport.hpp index 7da7a0d640..6812842bfa 100644 --- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/TypeSupport.hpp +++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/TypeSupport.hpp @@ -25,6 +25,7 @@ #include "fastcdr/FastBuffer.h" #include "fastcdr/Cdr.h" +#include "fastrtps/utils/md5.h" #include "rcutils/logging_macros.h" @@ -61,15 +62,14 @@ class TypeSupport : public eprosima::fastdds::dds::TopicDataType virtual bool deserializeROSmessage( eprosima::fastcdr::Cdr & deser, void * ros_message, const void * impl) const = 0; + virtual bool getKeyHashFromROSmessage( + void * ros_message, eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, bool force_md5, const void * impl) const = 0; + RMW_FASTRTPS_SHARED_CPP_PUBLIC bool getKey( void * data, eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, - bool force_md5 = false) override - { - (void)data; (void)ihandle; (void)force_md5; - return false; - } + bool force_md5 = false) override; RMW_FASTRTPS_SHARED_CPP_PUBLIC bool serialize(void * data, eprosima::fastrtps::rtps::SerializedPayload_t * payload) override; @@ -113,6 +113,10 @@ class TypeSupport : public eprosima::fastdds::dds::TopicDataType bool max_size_bound_; bool is_plain_; + bool key_is_unbounded_; + mutable size_t key_max_serialized_size_; + mutable MD5 md5_; + mutable std::vector key_buffer_; }; RMW_FASTRTPS_SHARED_CPP_PUBLIC diff --git a/rmw_fastrtps_shared_cpp/src/TypeSupport_impl.cpp b/rmw_fastrtps_shared_cpp/src/TypeSupport_impl.cpp index f357dd28eb..05766ea56c 100644 --- a/rmw_fastrtps_shared_cpp/src/TypeSupport_impl.cpp +++ b/rmw_fastrtps_shared_cpp/src/TypeSupport_impl.cpp @@ -64,6 +64,50 @@ void * TypeSupport::createData() return new eprosima::fastcdr::FastBuffer(); } +bool TypeSupport::getKey( + void * data, + eprosima::fastrtps::rtps::InstanceHandle_t * ihandle, + bool force_md5) +{ + assert(data); + + bool ret = false; + + if (!m_isGetKeyDefined) + { + return ret; + } + + auto ser_data = static_cast(data); + + switch (ser_data->type) + { + case FASTRTPS_SERIALIZED_DATA_TYPE_ROS_MESSAGE: + { + ret = this->getKeyHashFromROSmessage(ser_data->data, ihandle, force_md5, ser_data->impl); + break; + } + + case FASTRTPS_SERIALIZED_DATA_TYPE_CDR_BUFFER: + { + //! TODO + break; + } + + case FASTRTPS_SERIALIZED_DATA_TYPE_DYNAMIC_MESSAGE: + { + //! TODO + break; + } + default: + { + break; + } + } + + return ret; +} + bool TypeSupport::serialize( void * data, eprosima::fastrtps::rtps::SerializedPayload_t * payload) {