diff --git a/rmw/include/rmw/events_statuses/incompatible_qos.h b/rmw/include/rmw/events_statuses/incompatible_qos.h index ecdd6c1d..838d2d5c 100644 --- a/rmw/include/rmw/events_statuses/incompatible_qos.h +++ b/rmw/include/rmw/events_statuses/incompatible_qos.h @@ -17,6 +17,7 @@ #include +#include "rmw/qos_policy_kind.h" #include "rmw/visibility_control.h" #ifdef __cplusplus @@ -24,18 +25,6 @@ extern "C" { #endif -/// QoS Policy Kinds -typedef enum RMW_PUBLIC_TYPE rmw_qos_policy_kind_t -{ - RMW_QOS_POLICY_INVALID = 1 << 0, - RMW_QOS_POLICY_DURABILITY = 1 << 1, - RMW_QOS_POLICY_DEADLINE = 1 << 2, - RMW_QOS_POLICY_LIVELINESS = 1 << 3, - RMW_QOS_POLICY_RELIABILITY = 1 << 4, - RMW_QOS_POLICY_HISTORY = 1 << 5, - RMW_QOS_POLICY_LIFESPAN = 1 << 6 -} rmw_qos_policy_kind_t; - struct RMW_PUBLIC_TYPE rmw_qos_incompatible_event_status_t { /** diff --git a/rmw/include/rmw/qos_policy_kind.h b/rmw/include/rmw/qos_policy_kind.h new file mode 100644 index 00000000..c582c068 --- /dev/null +++ b/rmw/include/rmw/qos_policy_kind.h @@ -0,0 +1,45 @@ +// Copyright 2020 Open Source Robotics Foundation, Inc. +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// 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 RMW__QOS_POLICY_KIND_H_ +#define RMW__QOS_POLICY_KIND_H_ + +#include "rmw/visibility_control.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/// QoS Policy Kinds +typedef enum RMW_PUBLIC_TYPE rmw_qos_policy_kind_t +{ + RMW_QOS_POLICY_INVALID = 1 << 0, + RMW_QOS_POLICY_DURABILITY = 1 << 1, + RMW_QOS_POLICY_DEADLINE = 1 << 2, + RMW_QOS_POLICY_LIVELINESS = 1 << 3, + RMW_QOS_POLICY_RELIABILITY = 1 << 4, + RMW_QOS_POLICY_HISTORY = 1 << 5, + RMW_QOS_POLICY_LIFESPAN = 1 << 6, + RMW_QOS_POLICY_DEPTH = 1 << 7, + RMW_QOS_POLICY_LIVELINESS_LEASE_DURATION = 1 << 8, + RMW_QOS_POLICY_AVOID_ROS_NAMESPACE_CONVENTIONS = 1 << 9, +} rmw_qos_policy_kind_t; + +#ifdef __cplusplus +} +#endif + +#endif // RMW__QOS_POLICY_KIND_H_ diff --git a/rmw/include/rmw/qos_string_conversions.h b/rmw/include/rmw/qos_string_conversions.h index 27d14dfa..c77ce499 100644 --- a/rmw/include/rmw/qos_string_conversions.h +++ b/rmw/include/rmw/qos_string_conversions.h @@ -23,6 +23,32 @@ extern "C" { #endif +/// Return a string representing the policy kind. +/** + * Returns `NULL` when `kind` is `RMW_QOS_POLICY_INVALID` or an undefined kind. + * + * The stringified version of the policy kind can be obtained doing the follwing conversion: + * RMW_QOS_POLICY_ -> lower_case() + * + * For example, the stringified version of `RMW_QOS_POLICY_DURABILITY` is + * "durability" and `RMW_QOS_POLICY_DEADLINE` is "deadline". + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] kind qos policy kind to be stringified. + * \return a null terminated string representing the policy kind, or + * \return `NULL` if kind is `RMW_QOS_POLICY_INVALID` or an undefined kind. + */ +RMW_PUBLIC +const char * +rmw_qos_policy_kind_to_str(rmw_qos_policy_kind_t kind); + /// Return a string representing the policy value. /** * Returns `NULL` when `value` is `RMW_QOS_POLICY_*_UNKNOWN` or an undefined enum value. @@ -73,6 +99,29 @@ RMW_PUBLIC const char * rmw_qos_reliability_policy_to_str(enum rmw_qos_reliability_policy_t value); +/// Return a policy kind based on the provided string. +/** + * Returns the policy kind represented by the provided string, or + * `RMW_QOS_POLICY_INVALID` when the provided string doesn't represent any policy kind. + * + * How policy kinds are stringified is explained in \ref rmw_qos_policy_kind_to_str. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] str string identifying a qos policy kind. + * \return the policy kind represented by the string, or + * \return `RMW_QOS_POLICY_INVALID` if the string doesn't represent any policy kind. + */ +RMW_PUBLIC +rmw_qos_policy_kind_t +rmw_qos_policy_kind_from_str(const char * str); + /// Return a enum value based on the provided string. /** * Returns the enum value based on the provided string, or diff --git a/rmw/src/qos_string_conversions.c b/rmw/src/qos_string_conversions.c index 8a8f0942..279b0977 100644 --- a/rmw/src/qos_string_conversions.c +++ b/rmw/src/qos_string_conversions.c @@ -12,8 +12,37 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "rmw/error_handling.h" #include "rmw/qos_string_conversions.h" +const char * +rmw_qos_policy_kind_to_str(rmw_qos_policy_kind_t kind) +{ + switch (kind) { + case RMW_QOS_POLICY_DURABILITY: + return "durability"; + case RMW_QOS_POLICY_DEADLINE: + return "deadline"; + case RMW_QOS_POLICY_LIVELINESS: + return "liveliness"; + case RMW_QOS_POLICY_RELIABILITY: + return "reliability"; + case RMW_QOS_POLICY_HISTORY: + return "history"; + case RMW_QOS_POLICY_LIFESPAN: + return "lifespan"; + case RMW_QOS_POLICY_DEPTH: + return "depth"; + case RMW_QOS_POLICY_LIVELINESS_LEASE_DURATION: + return "liveliness_lease_duration"; + case RMW_QOS_POLICY_AVOID_ROS_NAMESPACE_CONVENTIONS: + return "avoid_ros_namespace_conventions"; + case RMW_QOS_POLICY_INVALID: // fallthrough + default: + return NULL; + } +} + const char * rmw_qos_durability_policy_to_str(enum rmw_qos_durability_policy_t value) { @@ -81,9 +110,44 @@ rmw_qos_reliability_policy_to_str(enum rmw_qos_reliability_policy_t value) #define RMW_QOS_STREQ_WITH_LITERAL(string_literal, string) \ (0 == strncmp(string_literal, str, sizeof(string_literal))) +rmw_qos_policy_kind_t +rmw_qos_policy_kind_from_str(const char * str) +{ + RMW_CHECK_ARGUMENT_FOR_NULL(str, RMW_QOS_POLICY_INVALID); + if (RMW_QOS_STREQ_WITH_LITERAL("durability", str)) { + return RMW_QOS_POLICY_DURABILITY; + } + if (RMW_QOS_STREQ_WITH_LITERAL("deadline", str)) { + return RMW_QOS_POLICY_DEADLINE; + } + if (RMW_QOS_STREQ_WITH_LITERAL("liveliness", str)) { + return RMW_QOS_POLICY_LIVELINESS; + } + if (RMW_QOS_STREQ_WITH_LITERAL("reliability", str)) { + return RMW_QOS_POLICY_RELIABILITY; + } + if (RMW_QOS_STREQ_WITH_LITERAL("history", str)) { + return RMW_QOS_POLICY_HISTORY; + } + if (RMW_QOS_STREQ_WITH_LITERAL("lifespan", str)) { + return RMW_QOS_POLICY_LIFESPAN; + } + if (RMW_QOS_STREQ_WITH_LITERAL("depth", str)) { + return RMW_QOS_POLICY_DEPTH; + } + if (RMW_QOS_STREQ_WITH_LITERAL("liveliness_lease_duration", str)) { + return RMW_QOS_POLICY_LIVELINESS_LEASE_DURATION; + } + if (RMW_QOS_STREQ_WITH_LITERAL("avoid_ros_namespace_conventions", str)) { + return RMW_QOS_POLICY_AVOID_ROS_NAMESPACE_CONVENTIONS; + } + return RMW_QOS_POLICY_INVALID; +} + enum rmw_qos_durability_policy_t rmw_qos_durability_policy_from_str(const char * str) { + RMW_CHECK_ARGUMENT_FOR_NULL(str, RMW_QOS_POLICY_DURABILITY_UNKNOWN); if (RMW_QOS_STREQ_WITH_LITERAL("system_default", str)) { return RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT; } @@ -99,6 +163,7 @@ rmw_qos_durability_policy_from_str(const char * str) enum rmw_qos_history_policy_t rmw_qos_history_policy_from_str(const char * str) { + RMW_CHECK_ARGUMENT_FOR_NULL(str, RMW_QOS_POLICY_HISTORY_UNKNOWN); if (RMW_QOS_STREQ_WITH_LITERAL("system_default", str)) { return RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT; } @@ -114,6 +179,7 @@ rmw_qos_history_policy_from_str(const char * str) enum rmw_qos_liveliness_policy_t rmw_qos_liveliness_policy_from_str(const char * str) { + RMW_CHECK_ARGUMENT_FOR_NULL(str, RMW_QOS_POLICY_LIVELINESS_UNKNOWN); if (RMW_QOS_STREQ_WITH_LITERAL("system_default", str)) { return RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT; } @@ -129,6 +195,7 @@ rmw_qos_liveliness_policy_from_str(const char * str) enum rmw_qos_reliability_policy_t rmw_qos_reliability_policy_from_str(const char * str) { + RMW_CHECK_ARGUMENT_FOR_NULL(str, RMW_QOS_POLICY_RELIABILITY_UNKNOWN); if (RMW_QOS_STREQ_WITH_LITERAL("system_default", str)) { return RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT; } diff --git a/rmw/test/test_qos_string_conversions.cpp b/rmw/test/test_qos_string_conversions.cpp index a024c4d9..126ad399 100644 --- a/rmw/test/test_qos_string_conversions.cpp +++ b/rmw/test/test_qos_string_conversions.cpp @@ -32,9 +32,12 @@ EXPECT_EQ( \ RMW_QOS_POLICY_ ## kind_upper ## _UNKNOWN, \ rmw_qos_ ## kind ## _policy_from_str("this could never be a stringified policy value")); \ + EXPECT_EQ( \ + RMW_QOS_POLICY_ ## kind_upper ## _UNKNOWN, \ + rmw_qos_ ## kind ## _policy_from_str(NULL)); \ } while (0) -TEST(test_qos_policy_stringify, test_normal_use) { +TEST(test_qos_policy_stringify, test_policy_values) { 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); @@ -53,3 +56,26 @@ TEST(test_qos_policy_stringify, test_normal_use) { TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(liveliness, LIVELINESS); TEST_QOS_POLICY_STRINGIFY_CORNER_CASES(reliability, RELIABILITY); } + +// Converts to string and back to the policy kind, check that it's the same +#define TEST_QOS_POLICY_KIND_STRINGIFY(kind) \ + do { \ + EXPECT_EQ( \ + kind, rmw_qos_policy_kind_from_str(rmw_qos_policy_kind_to_str(kind))); \ + } while (0) + +TEST(test_qos_policy_stringify, test_policy_kinds) { + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_DURABILITY); + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_DEADLINE); + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_LIVELINESS); + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_RELIABILITY); + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_HISTORY); + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_LIFESPAN); + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_DEPTH); + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_LIVELINESS_LEASE_DURATION); + TEST_QOS_POLICY_KIND_STRINGIFY(RMW_QOS_POLICY_AVOID_ROS_NAMESPACE_CONVENTIONS); + + EXPECT_EQ(RMW_QOS_POLICY_INVALID, rmw_qos_policy_kind_from_str(NULL)); + EXPECT_EQ(RMW_QOS_POLICY_INVALID, rmw_qos_policy_kind_from_str("this is not a policy kind!")); + EXPECT_FALSE(rmw_qos_policy_kind_to_str(RMW_QOS_POLICY_INVALID)); +}