See More

// Copyright 2020 Open Source Robotics Foundation, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "rclcpp/serialized_message.hpp" #include #include "rclcpp/exceptions.hpp" #include "rclcpp/logging.hpp" #include "rmw/types.h" namespace rclcpp { inline void copy_rcl_message(const rcl_serialized_message_t & from, rcl_serialized_message_t & to) { const auto ret = rmw_serialized_message_init( &to, from.buffer_capacity, &from.allocator); if (RCL_RET_OK != ret) { rclcpp::exceptions::throw_from_rcl_error(ret); } // do not call memcpy if the pointer is "static" if (to.buffer != from.buffer) { std::memcpy(to.buffer, from.buffer, from.buffer_length); } to.buffer_length = from.buffer_length; } /// Object oriented version of rcl_serialized_message_t with destructor to avoid memory leaks SerializedMessage::SerializedMessage(const rcl_allocator_t & allocator) : SerializedMessage(0u, allocator) {} SerializedMessage::SerializedMessage( size_t initial_capacity, const rcl_allocator_t & allocator) : serialized_message_(rmw_get_zero_initialized_serialized_message()) { const auto ret = rmw_serialized_message_init( &serialized_message_, initial_capacity, &allocator); if (RCL_RET_OK != ret) { rclcpp::exceptions::throw_from_rcl_error(ret); } } SerializedMessage::SerializedMessage(const SerializedMessage & other) : SerializedMessage(other.serialized_message_) {} SerializedMessage::SerializedMessage(const rcl_serialized_message_t & other) : serialized_message_(rmw_get_zero_initialized_serialized_message()) { copy_rcl_message(other, serialized_message_); } SerializedMessage::SerializedMessage(SerializedMessage && other) : serialized_message_( std::exchange(other.serialized_message_, rmw_get_zero_initialized_serialized_message())) {} SerializedMessage::SerializedMessage(rcl_serialized_message_t && other) : serialized_message_( std::exchange(other, rmw_get_zero_initialized_serialized_message())) {} SerializedMessage & SerializedMessage::operator=(const SerializedMessage & other) { if (this != &other) { serialized_message_ = rmw_get_zero_initialized_serialized_message(); copy_rcl_message(other.serialized_message_, serialized_message_); } return *this; } SerializedMessage & SerializedMessage::operator=(const rcl_serialized_message_t & other) { if (&serialized_message_ != &other) { serialized_message_ = rmw_get_zero_initialized_serialized_message(); copy_rcl_message(other, serialized_message_); } return *this; } SerializedMessage & SerializedMessage::operator=(SerializedMessage && other) { if (this != &other) { serialized_message_ = std::exchange(other.serialized_message_, rmw_get_zero_initialized_serialized_message()); } return *this; } SerializedMessage & SerializedMessage::operator=(rcl_serialized_message_t && other) { if (&serialized_message_ != &other) { serialized_message_ = std::exchange(other, rmw_get_zero_initialized_serialized_message()); } return *this; } SerializedMessage::~SerializedMessage() { if (nullptr != serialized_message_.buffer) { const auto fini_ret = rmw_serialized_message_fini(&serialized_message_); if (RCL_RET_OK != fini_ret) { RCLCPP_ERROR( get_logger("rclcpp"), "Failed to destroy serialized message: %s", rcl_get_error_string().str); } } } rcl_serialized_message_t & SerializedMessage::get_rcl_serialized_message() { return serialized_message_; } const rcl_serialized_message_t & SerializedMessage::get_rcl_serialized_message() const { return serialized_message_; } size_t SerializedMessage::size() const { return serialized_message_.buffer_length; } size_t SerializedMessage::capacity() const { return serialized_message_.buffer_capacity; } void SerializedMessage::reserve(size_t capacity) { auto ret = rmw_serialized_message_resize(&serialized_message_, capacity); if (RCL_RET_OK != ret) { rclcpp::exceptions::throw_from_rcl_error(ret); } } rcl_serialized_message_t SerializedMessage::release_rcl_serialized_message() { auto ret = serialized_message_; serialized_message_ = rmw_get_zero_initialized_serialized_message(); return ret; } } // namespace rclcpp