diff --git a/rcl/CMakeLists.txt b/rcl/CMakeLists.txt index e9e0b4c50..0f32c2102 100644 --- a/rcl/CMakeLists.txt +++ b/rcl/CMakeLists.txt @@ -52,6 +52,7 @@ set(${PROJECT_NAME}_sources src/rcl/node.c src/rcl/node_options.c src/rcl/publisher.c + src/rcl/qos.c src/rcl/remap.c src/rcl/rmw_implementation_identifier_check.c src/rcl/security.c diff --git a/rcl/include/rcl/qos.h b/rcl/include/rcl/qos.h new file mode 100644 index 000000000..5fa4f5b3c --- /dev/null +++ b/rcl/include/rcl/qos.h @@ -0,0 +1,128 @@ +// 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. + +#ifndef RCL__QOS_H_ +#define RCL__QOS_H_ + +#include "rcl/visibility_control.h" +#include "rmw/types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/// Return a string representing the policy value. +/** + * Returns `NULL` when `value` is `RMW_QOS_POLICY_*_UNKNOWN` or an undefined enum value. + * + * The stringified version of the policy value can be obtained doing the follwing conversion: + * RMW_QOS_POLICY__ -> lower_case() + * + * For example, the strigified version of `RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC` is + * "manual_by_topic" and `RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT` is `best_effort`. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] value qos policy value to be stringified. + * \return a null terminated string representing the policy value, or + * \return `NULL` if value is `RMW_QOS_POLICY_*_UNKNOWN` or an undefined enum value. + */ +RCL_PUBLIC +const char * +rcl_qos_durability_policy_to_str(enum rmw_qos_durability_policy_t value); + +/// Return a string representing the policy value. +/** + * See \ref rcl_qos_durability_policy_to_str() for more details. + */ +RCL_PUBLIC +const char * +rcl_qos_history_policy_to_str(enum rmw_qos_history_policy_t value); + +/// Return a string representing the policy value. +/** + * See \ref rcl_qos_durability_policy_to_str() for more details. + */ +RCL_PUBLIC +const char * +rcl_qos_liveliness_policy_to_str(enum rmw_qos_liveliness_policy_t value); + +/// Return a string representing the policy value. +/** + * See \ref rcl_qos_durability_policy_to_str() for more details. + */ +RCL_PUBLIC +const char * +rcl_qos_reliability_policy_to_str(enum rmw_qos_reliability_policy_t value); + +/// Return a enum value based on the provided string. +/** + * Returns the enum value based on the provided string, or + * `RMW_QOS_POLICY_*_UNKNOWN` when the provided string is unexpected. + * + * How policy values are stringified is explained in \ref rcl_qos_durability_policy_to_str. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] str string identifying a qos policy value. + * \return the policy value represented by the string, or + * \return `RMW_QOS_POLICY_*_UNKNOWN` if the string doesn't represent any value. + */ +RCL_PUBLIC +enum rmw_qos_durability_policy_t +rcl_qos_durability_policy_from_str(const char * str); + +/// Return a enum value based on the provided string. +/** + * See \ref rcl_qos_durability_policy_from_str() for more details. + */ +RCL_PUBLIC +enum rmw_qos_history_policy_t +rcl_qos_history_policy_from_str(const char * str); + +/// Return a enum value based on the provided string. +/** + * See \ref rcl_qos_durability_policy_from_str() for more details. + */ +RCL_PUBLIC +enum rmw_qos_liveliness_policy_t +rcl_qos_liveliness_policy_from_str(const char * str); + + +/// Return a enum value based on the provided string. +/** + * See \ref rcl_qos_durability_policy_from_str() for more details. + */ +RCL_PUBLIC +enum rmw_qos_reliability_policy_t +rcl_qos_reliability_policy_from_str(const char * str); + +#ifdef __cplusplus +} +#endif + +#endif // RCL__QOS_H_ diff --git a/rcl/src/rcl/qos.c b/rcl/src/rcl/qos.c new file mode 100644 index 000000000..44fe77bc4 --- /dev/null +++ b/rcl/src/rcl/qos.c @@ -0,0 +1,139 @@ +// 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 "rcl/qos.h" + +const char * +rcl_qos_durability_policy_to_str(enum rmw_qos_durability_policy_t value) +{ + switch (value) { + case RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT: + return "system_default"; + case RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL: + return "transient_local"; + case RMW_QOS_POLICY_DURABILITY_VOLATILE: + return "volatile"; + case RMW_QOS_POLICY_DURABILITY_UNKNOWN: // fallthrough + default: + return NULL; + } +} + +const char * +rcl_qos_history_policy_to_str(enum rmw_qos_history_policy_t value) +{ + switch (value) { + case RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT: + return "system_default"; + case RMW_QOS_POLICY_HISTORY_KEEP_LAST: + return "keep_last"; + case RMW_QOS_POLICY_HISTORY_KEEP_ALL: + return "keep_all"; + case RMW_QOS_POLICY_HISTORY_UNKNOWN: // fallthrough + default: + return NULL; + } +} + +const char * +rcl_qos_liveliness_policy_to_str(enum rmw_qos_liveliness_policy_t value) +{ + switch (value) { + case RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT: + return "system_default"; + case RMW_QOS_POLICY_LIVELINESS_AUTOMATIC: + return "automatic"; + case RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC: + return "manual_by_topic"; + case RMW_QOS_POLICY_LIVELINESS_UNKNOWN: // fallthrough + default: + return NULL; + } +} + +const char * +rcl_qos_reliability_policy_to_str(enum rmw_qos_reliability_policy_t value) +{ + switch (value) { + case RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT: + return "system_default"; + case RMW_QOS_POLICY_RELIABILITY_RELIABLE: + return "reliable"; + case RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT: + return "best_effort"; + case RMW_QOS_POLICY_RELIABILITY_UNKNOWN: // fallthrough + default: + return NULL; + } +} + +enum rmw_qos_durability_policy_t +rcl_qos_durability_policy_from_str(const char * str) +{ + if (0 == strcmp("system_default", str)) { + return RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT; + } + if (0 == strcmp("transient_local", str)) { + return RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL; + } + if (0 == strcmp("volatile", str)) { + return RMW_QOS_POLICY_DURABILITY_VOLATILE; + } + return RMW_QOS_POLICY_DURABILITY_UNKNOWN; +} + +enum rmw_qos_history_policy_t +rcl_qos_history_policy_from_str(const char * str) +{ + if (0 == strcmp("system_default", str)) { + return RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT; + } + if (0 == strcmp("keep_last", str)) { + return RMW_QOS_POLICY_HISTORY_KEEP_LAST; + } + if (0 == strcmp("keep_all", str)) { + return RMW_QOS_POLICY_HISTORY_KEEP_ALL; + } + return RMW_QOS_POLICY_HISTORY_UNKNOWN; +} + +enum rmw_qos_liveliness_policy_t +rcl_qos_liveliness_policy_from_str(const char * str) +{ + if (0 == strcmp("system_default", str)) { + return RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT; + } + if (0 == strcmp("automatic", str)) { + return RMW_QOS_POLICY_LIVELINESS_AUTOMATIC; + } + if (0 == strcmp("manual_by_topic", str)) { + return RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC; + } + return RMW_QOS_POLICY_LIVELINESS_UNKNOWN; +} + +enum rmw_qos_reliability_policy_t +rcl_qos_reliability_policy_from_str(const char * str) +{ + if (0 == strcmp("system_default", str)) { + return RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT; + } + if (0 == strcmp("reliable", str)) { + return RMW_QOS_POLICY_RELIABILITY_RELIABLE; + } + if (0 == strcmp("best_effort", str)) { + return RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; + } + return RMW_QOS_POLICY_RELIABILITY_UNKNOWN; +} diff --git a/rcl/test/CMakeLists.txt b/rcl/test/CMakeLists.txt index def4ac147..b22f2f419 100644 --- a/rcl/test/CMakeLists.txt +++ b/rcl/test/CMakeLists.txt @@ -411,6 +411,12 @@ rcl_add_custom_gtest(test_log_level AMENT_DEPENDENCIES "osrf_testing_tools_cpp" ) +rcl_add_custom_gtest(test_qos + SRCS rcl/test_qos.cpp + APPEND_LIBRARY_DIRS ${extra_lib_dirs} + LIBRARIES ${PROJECT_NAME} +) + # Install test resources install(DIRECTORY ${test_resources_dir_name} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/rcl/test/rcl/test_qos.cpp b/rcl/test/rcl/test_qos.cpp new file mode 100644 index 000000000..6246f4ddb --- /dev/null +++ b/rcl/test/rcl/test_qos.cpp @@ -0,0 +1,55 @@ +// 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 + +#include "rcl/qos.h" +#include "rmw/types.h" + +// Converts to string and back to the policy value, check that it's the same +#define TEST_QOS_POLICY_VALUE_STRINGIFY(kind, value) \ + do { \ + EXPECT_EQ( \ + value, rcl_qos_ ## kind ## _policy_from_str(rcl_qos_ ## kind ## _policy_to_str(value))); \ + } while (0) + +// Check unrecognized string as input of from_str, check UNKNOWN as input of to_str. +#define TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(kind, kind_upper) \ + do { \ + EXPECT_EQ( \ + NULL, rcl_qos_ ## kind ## _policy_to_str(RMW_QOS_POLICY_ ## kind_upper ## _UNKNOWN)); \ + EXPECT_EQ( \ + RMW_QOS_POLICY_ ## kind_upper ## _UNKNOWN, \ + rcl_qos_ ## kind ## _policy_from_str("this could never be a stringified policy value")); \ + } while (0) + +TEST(test_qos_policy_stringify, test_normal_use) { + TEST_QOS_POLICY_VALUE_STRINGIFY(durability, RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT); + TEST_QOS_POLICY_VALUE_STRINGIFY(durability, RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL); + TEST_QOS_POLICY_VALUE_STRINGIFY(durability, RMW_QOS_POLICY_DURABILITY_VOLATILE); + TEST_QOS_POLICY_VALUE_STRINGIFY(history, RMW_QOS_POLICY_HISTORY_KEEP_LAST); + TEST_QOS_POLICY_VALUE_STRINGIFY(history, RMW_QOS_POLICY_HISTORY_KEEP_ALL); + TEST_QOS_POLICY_VALUE_STRINGIFY(history, RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT); + TEST_QOS_POLICY_VALUE_STRINGIFY(liveliness, RMW_QOS_POLICY_LIVELINESS_AUTOMATIC); + TEST_QOS_POLICY_VALUE_STRINGIFY(liveliness, RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC); + TEST_QOS_POLICY_VALUE_STRINGIFY(liveliness, RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT); + TEST_QOS_POLICY_VALUE_STRINGIFY(reliability, RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT); + TEST_QOS_POLICY_VALUE_STRINGIFY(reliability, RMW_QOS_POLICY_RELIABILITY_RELIABLE); + TEST_QOS_POLICY_VALUE_STRINGIFY(reliability, RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT); + + TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(durability, DURABILITY); + TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(history, HISTORY); + TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(liveliness, LIVELINESS); + TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(reliability, RELIABILITY); +}