ROS 2 rclcpp + rcl - rolling  rolling-e615c7c3
ROS 2 C++ Client Library with ROS Client Library
type_description_conversions.c
1 // Copyright 2023 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 "rcl/error_handling.h"
16 #include "rcl/type_description_conversions.h"
17 
18 #include "rosidl_runtime_c/string_functions.h"
19 #include "rosidl_runtime_c/type_description/field__functions.h"
20 #include "rosidl_runtime_c/type_description/individual_type_description__functions.h"
21 #include "rosidl_runtime_c/type_description/type_description__functions.h"
22 #include "rosidl_runtime_c/type_description/type_source__functions.h"
23 #include "type_description_interfaces/msg/detail/field__functions.h"
24 #include "type_description_interfaces/msg/individual_type_description.h"
25 
26 static bool individual_type_description_runtime_to_msg(
27  const rosidl_runtime_c__type_description__IndividualTypeDescription * in,
28  type_description_interfaces__msg__IndividualTypeDescription * out)
29 {
30  RCL_CHECK_ARGUMENT_FOR_NULL(in, false);
31  RCL_CHECK_ARGUMENT_FOR_NULL(out, false);
32 
33  const bool success =
34  rosidl_runtime_c__String__copy(&in->type_name, &out->type_name) &&
35  type_description_interfaces__msg__Field__Sequence__init(
36  &out->fields,
37  in->fields.size);
38  if (!success) {
39  goto error;
40  }
41 
42  for (size_t i = 0; i < in->fields.size; ++i) {
43  if (!rosidl_runtime_c__String__copy(
44  &(in->fields.data[i].name),
45  &(out->fields.data[i].name)))
46  {
47  goto error;
48  }
49 
50  if (in->fields.data[i].default_value.size) {
51  if (!rosidl_runtime_c__String__copy(
52  &(in->fields.data[i].default_value),
53  &(out->fields.data[i].default_value)))
54  {
55  goto error;
56  }
57  }
58 
59  // type_id
60  out->fields.data[i].type.type_id = in->fields.data[i].type.type_id;
61  // capacity
62  out->fields.data[i].type.capacity = in->fields.data[i].type.capacity;
63  // string_capacity
64  out->fields.data[i].type.string_capacity =
65  in->fields.data[i].type.string_capacity;
66 
67  // nested_type_name
68  if (in->fields.data[i].type.nested_type_name.size) {
69  if (!rosidl_runtime_c__String__copy(
70  &(in->fields.data[i].type.nested_type_name),
71  &(out->fields.data[i].type.nested_type_name)))
72  {
73  goto error;
74  }
75  }
76  }
77 
78  return true;
79 
80 error:
81  type_description_interfaces__msg__IndividualTypeDescription__fini(out);
82  return false;
83 }
84 
85 static bool individual_type_description_msg_to_runtime(
86  const type_description_interfaces__msg__IndividualTypeDescription * in,
87  rosidl_runtime_c__type_description__IndividualTypeDescription * out)
88 {
89  RCL_CHECK_ARGUMENT_FOR_NULL(in, false);
90  RCL_CHECK_ARGUMENT_FOR_NULL(out, false);
91 
92  const bool success =
93  rosidl_runtime_c__String__copy(&in->type_name, &out->type_name) &&
94  rosidl_runtime_c__type_description__Field__Sequence__init(
95  &out->fields, in->fields.size);
96  if (!success) {
97  goto error;
98  }
99 
100  for (size_t i = 0; i < in->fields.size; ++i) {
101  if (!rosidl_runtime_c__String__copy(
102  &(in->fields.data[i].name),
103  &(out->fields.data[i].name)))
104  {
105  goto error;
106  }
107 
108  if (in->fields.data[i].default_value.size) {
109  if (!rosidl_runtime_c__String__copy(
110  &(in->fields.data[i].default_value),
111  &(out->fields.data[i].default_value)))
112  {
113  goto error;
114  }
115  }
116 
117  // type_id
118  out->fields.data[i].type.type_id = in->fields.data[i].type.type_id;
119  // capacity
120  out->fields.data[i].type.capacity = in->fields.data[i].type.capacity;
121  // string_capacity
122  out->fields.data[i].type.string_capacity =
123  in->fields.data[i].type.string_capacity;
124 
125  // nested_type_name
126  if (in->fields.data[i].type.nested_type_name.size) {
127  if (!rosidl_runtime_c__String__copy(
128  &(in->fields.data[i].type.nested_type_name),
129  &(out->fields.data[i].type.nested_type_name)))
130  {
131  goto error;
132  }
133  }
134  }
135 
136  return true;
137 
138 error:
139  rosidl_runtime_c__type_description__IndividualTypeDescription__init(out);
140  return false;
141 }
142 
143 type_description_interfaces__msg__TypeDescription *
144 rcl_convert_type_description_runtime_to_msg(
145  const rosidl_runtime_c__type_description__TypeDescription * runtime_description)
146 {
147  RCL_CHECK_ARGUMENT_FOR_NULL(runtime_description, NULL);
148 
149  // Create the object
150  type_description_interfaces__msg__TypeDescription * out =
151  type_description_interfaces__msg__TypeDescription__create();
152  RCL_CHECK_ARGUMENT_FOR_NULL(out, NULL);
153 
154  // init referenced_type_descriptions with the correct size
155  if (!type_description_interfaces__msg__IndividualTypeDescription__Sequence__init(
156  &out->referenced_type_descriptions,
157  runtime_description->referenced_type_descriptions.size))
158  {
159  goto fail;
160  }
161 
162  // Convert individual type description
163  if (!individual_type_description_runtime_to_msg(
164  &runtime_description->type_description,
165  &out->type_description))
166  {
167  goto fail;
168  }
169 
170  // Convert referenced type descriptions
171  for (size_t i = 0; i < runtime_description->referenced_type_descriptions.size; ++i) {
172  if (!individual_type_description_runtime_to_msg(
173  &runtime_description->referenced_type_descriptions.data[i],
174  &out->referenced_type_descriptions.data[i]))
175  {
176  goto fail;
177  }
178  }
179 
180  return out;
181 
182 fail:
183  type_description_interfaces__msg__TypeDescription__destroy(out);
184  return NULL;
185 }
186 
187 rosidl_runtime_c__type_description__TypeDescription *
188 rcl_convert_type_description_msg_to_runtime(
189  const type_description_interfaces__msg__TypeDescription * description_msg)
190 {
191  RCL_CHECK_ARGUMENT_FOR_NULL(description_msg, NULL);
192 
193  // Create the object
194  rosidl_runtime_c__type_description__TypeDescription * out =
195  rosidl_runtime_c__type_description__TypeDescription__create();
196  RCL_CHECK_ARGUMENT_FOR_NULL(out, NULL);
197 
198  // init referenced_type_descriptions with the correct size
199  if (!rosidl_runtime_c__type_description__IndividualTypeDescription__Sequence__init(
200  &out->referenced_type_descriptions,
201  description_msg->referenced_type_descriptions.size))
202  {
203  goto fail;
204  }
205 
206  if (!individual_type_description_msg_to_runtime(
207  &description_msg->type_description,
208  &out->type_description))
209  {
210  goto fail;
211  }
212 
213  for (size_t i = 0; i < description_msg->referenced_type_descriptions.size; ++i) {
214  if (!individual_type_description_msg_to_runtime(
215  &description_msg->referenced_type_descriptions.data[i],
216  &out->referenced_type_descriptions.data[i]))
217  {
218  goto fail;
219  }
220  }
221 
222  return out;
223 
224 fail:
225  rosidl_runtime_c__type_description__TypeDescription__destroy(out);
226  return NULL;
227 }
228 
229 type_description_interfaces__msg__TypeSource__Sequence *
230 rcl_convert_type_source_sequence_runtime_to_msg(
231  const rosidl_runtime_c__type_description__TypeSource__Sequence * runtime_type_sources)
232 {
233  RCL_CHECK_ARGUMENT_FOR_NULL(runtime_type_sources, NULL);
234 
235  // Create the object
236  type_description_interfaces__msg__TypeSource__Sequence * out =
237  type_description_interfaces__msg__TypeSource__Sequence__create(runtime_type_sources->size);
238  RCL_CHECK_ARGUMENT_FOR_NULL(out, NULL);
239 
240  // Copy type sources
241  for (size_t i = 0; i < runtime_type_sources->size; ++i) {
242  // type_name
243  if (!rosidl_runtime_c__String__copy(
244  &(runtime_type_sources->data[i].type_name), &(out->data[i].type_name)))
245  {
246  goto fail;
247  }
248  // encoding
249  if (!rosidl_runtime_c__String__copy(
250  &(runtime_type_sources->data[i].encoding), &(out->data[i].encoding)))
251  {
252  goto fail;
253  }
254  // raw_file_contents
255  if (runtime_type_sources->data[i].raw_file_contents.size > 0) {
256  if (!rosidl_runtime_c__String__copy(
257  &(runtime_type_sources->data[i].raw_file_contents), &(out->data[i].raw_file_contents)))
258  {
259  goto fail;
260  }
261  }
262  }
263 
264  return out;
265 
266 fail:
267  type_description_interfaces__msg__TypeSource__Sequence__destroy(out);
268  return NULL;
269 }
270 
271 rosidl_runtime_c__type_description__TypeSource__Sequence *
272 rcl_convert_type_source_sequence_msg_to_runtime(
273  const type_description_interfaces__msg__TypeSource__Sequence * type_sources_msg)
274 {
275  RCL_CHECK_ARGUMENT_FOR_NULL(type_sources_msg, NULL);
276 
277  // Create the object
278  rosidl_runtime_c__type_description__TypeSource__Sequence * out =
279  rosidl_runtime_c__type_description__TypeSource__Sequence__create(type_sources_msg->size);
280  RCL_CHECK_ARGUMENT_FOR_NULL(out, NULL);
281 
282  // Copy type sources
283  for (size_t i = 0; i < type_sources_msg->size; ++i) {
284  // type_name
285  if (!rosidl_runtime_c__String__copy(
286  &(type_sources_msg->data[i].type_name), &(out->data[i].type_name)))
287  {
288  goto fail;
289  }
290  // encoding
291  if (!rosidl_runtime_c__String__copy(
292  &(type_sources_msg->data[i].encoding), &(out->data[i].encoding)))
293  {
294  goto fail;
295  }
296  // raw_file_contents
297  if (!rosidl_runtime_c__String__copy(
298  &(type_sources_msg->data[i].raw_file_contents), &(out->data[i].raw_file_contents)))
299  {
300  goto fail;
301  }
302  }
303 
304  return out;
305 
306 fail:
307  rosidl_runtime_c__type_description__TypeSource__Sequence__destroy(out);
308  return NULL;
309 }