ROS 2 rclcpp + rcl - humble  humble
ROS 2 C++ Client Library with ROS Client Library
init_options.c
1 // Copyright 2015 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 #ifdef __cplusplus
16 extern "C"
17 {
18 #endif
19 
20 #include "rcl/init_options.h"
21 
22 #include "./common.h"
23 #include "./init_options_impl.h"
24 #include "rcutils/macros.h"
25 #include "rcl/error_handling.h"
26 #include "rmw/error_handling.h"
27 #include "rcutils/logging_macros.h"
28 
31 {
32  return (const rcl_init_options_t) {
33  .impl = 0,
34  }; // NOLINT(readability/braces): false positive
35 }
36 
38 static inline
40 _rcl_init_options_zero_init(rcl_init_options_t * init_options, rcl_allocator_t allocator)
41 {
42  init_options->impl = allocator.allocate(sizeof(rcl_init_options_impl_t), allocator.state);
43  RCL_CHECK_FOR_NULL_WITH_MSG(
44  init_options->impl,
45  "failed to allocate memory for init options impl",
46  return RCL_RET_BAD_ALLOC);
47  init_options->impl->allocator = allocator;
48  init_options->impl->rmw_init_options = rmw_get_zero_initialized_init_options();
49 
50  return RCL_RET_OK;
51 }
52 
55 {
56  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
57  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_ALREADY_INIT);
58  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_BAD_ALLOC);
59  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
60 
61  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, RCL_RET_INVALID_ARGUMENT);
62  if (NULL != init_options->impl) {
63  RCL_SET_ERROR_MSG("given init_options (rcl_init_options_t) is already initialized");
64  return RCL_RET_ALREADY_INIT;
65  }
67 
68  rcl_ret_t ret = _rcl_init_options_zero_init(init_options, allocator);
69  if (RCL_RET_OK != ret) {
70  return ret;
71  }
72  rmw_ret_t rmw_ret = rmw_init_options_init(&(init_options->impl->rmw_init_options), allocator);
73  if (RMW_RET_OK != rmw_ret) {
74  allocator.deallocate(init_options->impl, allocator.state);
75  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
76  return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
77  }
78  return RCL_RET_OK;
79 }
80 
83 {
84  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
85  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_ALREADY_INIT);
86  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_BAD_ALLOC);
87  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
88 
89  RCL_CHECK_ARGUMENT_FOR_NULL(src, RCL_RET_INVALID_ARGUMENT);
90  RCL_CHECK_ARGUMENT_FOR_NULL(src->impl, RCL_RET_INVALID_ARGUMENT);
91  RCL_CHECK_ALLOCATOR(&src->impl->allocator, return RCL_RET_INVALID_ARGUMENT);
92  RCL_CHECK_ARGUMENT_FOR_NULL(dst, RCL_RET_INVALID_ARGUMENT);
93  if (NULL != dst->impl) {
94  RCL_SET_ERROR_MSG("given dst (rcl_init_options_t) is already initialized");
95  return RCL_RET_ALREADY_INIT;
96  }
97 
98  // initialize dst (since we know it's in a zero initialized state)
99  rcl_ret_t ret = _rcl_init_options_zero_init(dst, src->impl->allocator);
100  if (RCL_RET_OK != ret) {
101  return ret; // error already set
102  }
103 
104  // copy src information into dst
105  rmw_ret_t rmw_ret =
106  rmw_init_options_copy(&(src->impl->rmw_init_options), &(dst->impl->rmw_init_options));
107  if (RMW_RET_OK != rmw_ret) {
108  rmw_error_string_t error_string = rmw_get_error_string();
109  rmw_reset_error();
110  ret = rcl_init_options_fini(dst);
111  if (RCL_RET_OK != ret) {
112  RCUTILS_LOG_ERROR_NAMED(
113  "rcl",
114  "failed to finalize dst rcl_init_options while handling failure to "
115  "copy rmw_init_options, original ret '%d' and error: %s", rmw_ret, error_string.str);
116  return ret; // error already set
117  }
118  RCL_SET_ERROR_MSG(error_string.str);
119  return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
120  }
121 
122  return RCL_RET_OK;
123 }
124 
125 rcl_ret_t
127 {
128  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, RCL_RET_INVALID_ARGUMENT);
129  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, RCL_RET_INVALID_ARGUMENT);
130  rcl_allocator_t allocator = init_options->impl->allocator;
131  RCL_CHECK_ALLOCATOR(&allocator, return RCL_RET_INVALID_ARGUMENT);
132  rmw_ret_t rmw_ret = rmw_init_options_fini(&(init_options->impl->rmw_init_options));
133  if (RMW_RET_OK != rmw_ret) {
134  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
135  return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
136  }
137  allocator.deallocate(init_options->impl, allocator.state);
138  return RCL_RET_OK;
139 }
140 
141 rcl_ret_t
142 rcl_init_options_get_domain_id(const rcl_init_options_t * init_options, size_t * domain_id)
143 {
144  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, RCL_RET_INVALID_ARGUMENT);
145  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, RCL_RET_INVALID_ARGUMENT);
146  RCL_CHECK_ARGUMENT_FOR_NULL(domain_id, RCL_RET_INVALID_ARGUMENT);
147  *domain_id = init_options->impl->rmw_init_options.domain_id;
148  return RCL_RET_OK;
149 }
150 
151 rcl_ret_t
152 rcl_init_options_set_domain_id(rcl_init_options_t * init_options, size_t domain_id)
153 {
154  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, RCL_RET_INVALID_ARGUMENT);
155  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, RCL_RET_INVALID_ARGUMENT);
156  init_options->impl->rmw_init_options.domain_id = domain_id;
157  return RCL_RET_OK;
158 }
159 
160 rmw_init_options_t *
162 {
163  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, NULL);
164  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, NULL);
165  return &(init_options->impl->rmw_init_options);
166 }
167 
168 const rcl_allocator_t *
170 {
171  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, NULL);
172  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, NULL);
173  return &(init_options->impl->allocator);
174 }
175 
176 #ifdef __cplusplus
177 }
178 #endif
#define RCL_CHECK_ALLOCATOR(allocator, fail_statement)
Check that the given allocator is initialized.
Definition: allocator.h:49
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
Definition: allocator.h:31
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_init(rcl_init_options_t *init_options, rcl_allocator_t allocator)
Initialize given init_options with the default values and implementation specific values.
Definition: init_options.c:54
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_set_domain_id(rcl_init_options_t *init_options, size_t domain_id)
Set a domain id in the init options provided.
Definition: init_options.c:152
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_copy(const rcl_init_options_t *src, rcl_init_options_t *dst)
Copy the given source init_options to the destination init_options.
Definition: init_options.c:82
RCL_PUBLIC RCL_WARN_UNUSED rcl_init_options_t rcl_get_zero_initialized_init_options(void)
Return a zero initialized rcl_init_options_t struct.
Definition: init_options.c:30
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_get_domain_id(const rcl_init_options_t *init_options, size_t *domain_id)
Return the domain_id stored in the init options.
Definition: init_options.c:142
RCL_PUBLIC RCL_WARN_UNUSED const rcl_allocator_t * rcl_init_options_get_allocator(const rcl_init_options_t *init_options)
Return the allocator stored in the init_options.
Definition: init_options.c:169
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_fini(rcl_init_options_t *init_options)
Finalize the given init_options.
Definition: init_options.c:126
RCL_PUBLIC RCL_WARN_UNUSED rmw_init_options_t * rcl_init_options_get_rmw_init_options(rcl_init_options_t *init_options)
Return the rmw init options which are stored internally.
Definition: init_options.c:161
Encapsulation of init options and implementation defined init options.
Definition: init_options.h:36
rcl_init_options_impl_t * impl
Implementation specific pointer.
Definition: init_options.h:38
#define RCL_RET_ALREADY_INIT
rcl_init() already called return code.
Definition: types.h:40
#define RCL_RET_OK
Success return code.
Definition: types.h:26
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
Definition: types.h:32
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:34
#define RCL_RET_ERROR
Unspecified error return code.
Definition: types.h:28
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:23