ROS 2 rclcpp + rcl - kilted  kilted
ROS 2 C++ Client Library with ROS Client Library
serialized_message.cpp
1 // Copyright 2020 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "rclcpp/serialized_message.hpp"
16 
17 #include <cstring>
18 
19 #include "rclcpp/exceptions.hpp"
20 #include "rclcpp/logging.hpp"
21 
22 #include "rmw/types.h"
23 
24 namespace rclcpp
25 {
26 
27 inline void copy_rcl_message(const rcl_serialized_message_t & from, rcl_serialized_message_t & to)
28 {
29  auto ret = RCL_RET_ERROR;
30  if (nullptr == to.buffer) {
31  ret = rmw_serialized_message_init(&to, from.buffer_capacity, &from.allocator);
32  } else {
33  ret = rmw_serialized_message_resize(&to, from.buffer_capacity);
34  }
35 
36  if (RCL_RET_OK != ret) {
37  rclcpp::exceptions::throw_from_rcl_error(ret);
38  }
39 
40  // do not call memcpy if the pointer is "static"
41  if (to.buffer != from.buffer) {
42  std::memcpy(to.buffer, from.buffer, from.buffer_length);
43  }
44  to.buffer_length = from.buffer_length;
45 }
46 
49 : SerializedMessage(0u, allocator)
50 {}
51 
53  size_t initial_capacity, const rcl_allocator_t & allocator)
54 : serialized_message_(rmw_get_zero_initialized_serialized_message())
55 {
56  const auto ret = rmw_serialized_message_init(
57  &serialized_message_, initial_capacity, &allocator);
58  if (RCL_RET_OK != ret) {
59  rclcpp::exceptions::throw_from_rcl_error(ret);
60  }
61 }
62 
64 : SerializedMessage(other.serialized_message_)
65 {}
66 
68 : serialized_message_(rmw_get_zero_initialized_serialized_message())
69 {
70  copy_rcl_message(other, serialized_message_);
71 }
72 
74 : serialized_message_(
75  std::exchange(other.serialized_message_, rmw_get_zero_initialized_serialized_message()))
76 {}
77 
79 : serialized_message_(
80  std::exchange(other, rmw_get_zero_initialized_serialized_message()))
81 {}
82 
84 {
85  if (this != &other) {
86  copy_rcl_message(other.serialized_message_, serialized_message_);
87  }
88 
89  return *this;
90 }
91 
93 {
94  if (&serialized_message_ != &other) {
95  copy_rcl_message(other, serialized_message_);
96  }
97 
98  return *this;
99 }
100 
102 {
103  if (this != &other) {
104  if (nullptr != serialized_message_.buffer) {
105  const auto fini_ret = rmw_serialized_message_fini(&serialized_message_);
106  if (RCL_RET_OK != fini_ret) {
107  RCLCPP_ERROR(
108  get_logger("rclcpp"),
109  "Failed to destroy serialized message: %s", rcl_get_error_string().str);
110  }
111  }
112  serialized_message_ =
113  std::exchange(other.serialized_message_, rmw_get_zero_initialized_serialized_message());
114  }
115 
116  return *this;
117 }
118 
120 {
121  if (&serialized_message_ != &other) {
122  if (nullptr != serialized_message_.buffer) {
123  const auto fini_ret = rmw_serialized_message_fini(&serialized_message_);
124  if (RCL_RET_OK != fini_ret) {
125  RCLCPP_ERROR(
126  get_logger("rclcpp"),
127  "Failed to destroy serialized message: %s", rcl_get_error_string().str);
128  }
129  }
130  serialized_message_ =
131  std::exchange(other, rmw_get_zero_initialized_serialized_message());
132  }
133  return *this;
134 }
135 
137 {
138  if (nullptr != serialized_message_.buffer) {
139  const auto fini_ret = rmw_serialized_message_fini(&serialized_message_);
140  if (RCL_RET_OK != fini_ret) {
141  RCLCPP_ERROR(
142  get_logger("rclcpp"),
143  "Failed to destroy serialized message: %s", rcl_get_error_string().str);
144  rcl_reset_error();
145  }
146  }
147 }
148 
150 {
151  return serialized_message_;
152 }
153 
155 {
156  return serialized_message_;
157 }
158 
160 {
161  return serialized_message_.buffer_length;
162 }
163 
165 {
166  return serialized_message_.buffer_capacity;
167 }
168 
169 void SerializedMessage::reserve(size_t capacity)
170 {
171  auto ret = rmw_serialized_message_resize(&serialized_message_, capacity);
172  if (RCL_RET_OK != ret) {
173  rclcpp::exceptions::throw_from_rcl_error(ret);
174  }
175 }
176 
178 {
179  auto ret = serialized_message_;
180  serialized_message_ = rmw_get_zero_initialized_serialized_message();
181 
182  return ret;
183 }
184 } // namespace rclcpp
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
Definition: allocator.h:31
Object oriented version of rcl_serialized_message_t with destructor to avoid memory leaks.
rcl_serialized_message_t release_rcl_serialized_message()
Release the underlying rcl_serialized_message_t.
size_t size() const
Get the size of the serialized data buffer.
virtual ~SerializedMessage()
Destructor for a SerializedMessage.
void reserve(size_t capacity)
Allocate memory in the data buffer.
rcl_serialized_message_t & get_rcl_serialized_message()
Get the underlying rcl_serialized_t handle.
SerializedMessage(const rcl_allocator_t &allocator=rcl_get_default_allocator())
Default constructor for a SerializedMessage.
SerializedMessage & operator=(const SerializedMessage &other)
Copy assignment operator.
size_t capacity() const
Get the size of allocated memory for the data buffer.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Definition: logger.cpp:34
#define RCL_RET_OK
Success return code.
Definition: types.h:27
#define RCL_RET_ERROR
Unspecified error return code.
Definition: types.h:29
rmw_serialized_message_t rcl_serialized_message_t
typedef for rmw_serialized_message_t;
Definition: types.h:152