From c381aefefc29327b9f01374c96c093b0844fa112 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 2 Apr 2019 10:21:42 +0300 Subject: [PATCH] MXS-2346 Add config::ParamInteger and config::Integer --- include/maxscale/config2.hh | 206 ++++++++++++++++++++++++++----- server/core/config2.cc | 60 ++++++--- server/core/test/test_config2.cc | 26 ++++ 3 files changed, 245 insertions(+), 47 deletions(-) diff --git a/include/maxscale/config2.hh b/include/maxscale/config2.hh index ddeaa2fb1..db8fbae5a 100644 --- a/include/maxscale/config2.hh +++ b/include/maxscale/config2.hh @@ -298,30 +298,10 @@ private: value_type m_default_value; }; -/** - * ParamCount - */ -class ParamCount : public Param +class ParamNumber : public Param { public: - using value_type = uint64_t; - - ParamCount(Specification* pSpecification, - const char* zName, - const char* zDescription) - : ParamCount(pSpecification, zName, zDescription, Param::MANDATORY, value_type()) - { - } - - ParamCount(Specification* pSpecification, - const char* zName, - const char* zDescription, - value_type default_value) - : ParamCount(pSpecification, zName, zDescription, Param::OPTIONAL, default_value) - { - } - - std::string type() const override; + using value_type = int64_t; std::string default_to_string() const override; @@ -332,19 +312,164 @@ public: bool from_string(const std::string& value, value_type* pValue, std::string* pMessage = nullptr) const; std::string to_string(value_type value) const; +protected: + ParamNumber(Specification* pSpecification, + const char* zName, + const char* zDescription, + Kind kind, + mxs_module_param_type legacy_type, + value_type default_value, + value_type min_value, + value_type max_value) + : Param(pSpecification, zName, zDescription, kind, legacy_type) + , m_default_value(default_value) + , m_min_value(min_value <= max_value ? min_value : max_value) + , m_max_value(max_value) + { + mxb_assert(min_value <= max_value); + } + +private: + value_type m_default_value; + value_type m_min_value; + value_type m_max_value; +}; + +/** + * ParamCount + */ +class ParamCount : public ParamNumber +{ +public: + ParamCount(Specification* pSpecification, + const char* zName, + const char* zDescription) + : ParamCount(pSpecification, zName, zDescription, Param::MANDATORY, + value_type(), 0, std::numeric_limits::max()) + { + } + + ParamCount(Specification* pSpecification, + const char* zName, + const char* zDescription, + value_type min_value, + value_type max_value) + : ParamCount(pSpecification, zName, zDescription, Param::MANDATORY, + value_type(), min_value, max_value) + { + } + + ParamCount(Specification* pSpecification, + const char* zName, + const char* zDescription, + value_type default_value) + : ParamCount(pSpecification, zName, zDescription, Param::OPTIONAL, + default_value, 0, std::numeric_limits::max()) + { + } + + ParamCount(Specification* pSpecification, + const char* zName, + const char* zDescription, + value_type default_value, + value_type min_value, + value_type max_value) + : ParamCount(pSpecification, zName, zDescription, Param::OPTIONAL, + default_value, min_value, max_value) + { + } + + std::string type() const override; + private: ParamCount(Specification* pSpecification, const char* zName, const char* zDescription, Kind kind, - value_type default_value) - : Param(pSpecification, zName, zDescription, kind, MXS_MODULE_PARAM_COUNT) - , m_default_value(default_value) + value_type default_value, + value_type min_value, + value_type max_value) + : ParamNumber(pSpecification, zName, zDescription, kind, MXS_MODULE_PARAM_COUNT, + default_value, + min_value >= 0 ? min_value : 0, + max_value <= std::numeric_limits::max() + ? max_value : std::numeric_limits::max()) + { + mxb_assert(min_value >= 0); + mxb_assert(max_value <= std::numeric_limits::max()); + } +}; + +using ParamNatural = ParamCount; + +/** + * ParamInteger + */ +class ParamInteger : public ParamNumber +{ +public: + ParamInteger(Specification* pSpecification, + const char* zName, + const char* zDescription) + : ParamInteger(pSpecification, zName, zDescription, Param::MANDATORY, + value_type(), + std::numeric_limits::min(), + std::numeric_limits::max()) { } + ParamInteger(Specification* pSpecification, + const char* zName, + const char* zDescription, + value_type min_value, + value_type max_value) + : ParamInteger(pSpecification, zName, zDescription, Param::MANDATORY, + value_type(), min_value, max_value) + { + } + + ParamInteger(Specification* pSpecification, + const char* zName, + const char* zDescription, + value_type default_value) + : ParamInteger(pSpecification, zName, zDescription, Param::OPTIONAL, + default_value, + std::numeric_limits::min(), + std::numeric_limits::max()) + { + } + + ParamInteger(Specification* pSpecification, + const char* zName, + const char* zDescription, + value_type default_value, + value_type min_value, + value_type max_value) + : ParamInteger(pSpecification, zName, zDescription, Param::OPTIONAL, + default_value, min_value, max_value) + { + } + + std::string type() const override; + private: - value_type m_default_value; + ParamInteger(Specification* pSpecification, + const char* zName, + const char* zDescription, + Kind kind, + value_type default_value, + value_type min_value, + value_type max_value) + : ParamNumber(pSpecification, zName, zDescription, kind, MXS_MODULE_PARAM_INT, + default_value, + min_value >= std::numeric_limits::min() + ? min_value : std::numeric_limits::min(), + max_value <= std::numeric_limits::max() + ? max_value : std::numeric_limits::max()) + { + mxb_assert(min_value >= std::numeric_limits::min()); + mxb_assert(max_value <= std::numeric_limits::max()); + } }; /** @@ -624,7 +749,7 @@ private: /** * ParamBitMask */ -using ParamBitMask = ParamCount; +using ParamBitMask = ParamCount; /** * An instance of the class Configuration specifies the configuration of a particular @@ -954,14 +1079,35 @@ inline bool operator >= (const typename ParamType::value_type& lhs, } +class Number : public ConcreteType +{ +protected: + Number(Configuration* pConfiguration, const ParamNumber* pParam) + : ConcreteType(pConfiguration, pParam) + { + } +}; + /** * Count */ -class Count : public ConcreteType +class Count : public Number { public: - Count(Configuration* pConfiguration, const ParamCount* pParam) - : ConcreteType(pConfiguration, pParam) + Count(Configuration* pConfiguration, const ParamCount* pParam) + : Number(pConfiguration, pParam) + { + } +}; + +/** + * Integer + */ +class Integer : public Number +{ +public: + Integer(Configuration* pConfiguration, const ParamInteger* pParam) + : Number(pConfiguration, pParam) { } }; diff --git a/server/core/config2.cc b/server/core/config2.cc index 445427ae2..bb4f88d3c 100644 --- a/server/core/config2.cc +++ b/server/core/config2.cc @@ -439,49 +439,44 @@ string ParamBool::to_string(value_type value) const } /** - * ParamCount + * ParamNumber */ -std::string ParamCount::type() const -{ - return "count"; -} - -std::string ParamCount::default_to_string() const +std::string ParamNumber::default_to_string() const { return to_string(m_default_value); } -bool ParamCount::validate(const std::string& value_as_string, std::string* pMessage) const +bool ParamNumber::validate(const std::string& value_as_string, std::string* pMessage) const { value_type value; return from_string(value_as_string, &value, pMessage); } -bool ParamCount::set(Type& value, const std::string& value_as_string) const +bool ParamNumber::set(Type& value, const std::string& value_as_string) const { mxb_assert(&value.parameter() == this); - Count& count_value = static_cast(value); + Number& number_value = static_cast(value); value_type x; bool valid = from_string(value_as_string, &x); if (valid) { - count_value.set(x); + number_value.set(x); } return valid; } -bool ParamCount::from_string(const std::string& value_as_string, - value_type* pValue, - std::string* pMessage) const +bool ParamNumber::from_string(const std::string& value_as_string, + value_type* pValue, + std::string* pMessage) const { const char* zValue = value_as_string.c_str(); char* zEnd; long l = strtol(zValue, &zEnd, 10); - bool valid = (l >= 0 && zEnd != zValue && *zEnd == 0); + bool valid = (l >= m_min_value && l <= m_max_value && zEnd != zValue && *zEnd == 0); if (valid) { @@ -489,18 +484,49 @@ bool ParamCount::from_string(const std::string& value_as_string, } else if (pMessage) { - *pMessage = "Invalid count: "; + if (!(zEnd != zValue && *zEnd == 0)) + { + *pMessage = "Invalid "; + } + else if (!(l >= m_min_value)) + { + *pMessage = "Too small a "; + } + else + { + mxb_assert(!(l <= m_max_value)); + *pMessage = "Too large a "; + } + + *pMessage += type(); + *pMessage += ": "; *pMessage += value_as_string; } return valid; } -std::string ParamCount::to_string(value_type value) const +std::string ParamNumber::to_string(value_type value) const { return std::to_string(value); } +/** + * ParamCount + */ +std::string ParamCount::type() const +{ + return "count"; +} + +/** + * ParamInteger + */ +std::string ParamInteger::type() const +{ + return "integer"; +} + /** * ParamPath */ diff --git a/server/core/test/test_config2.cc b/server/core/test/test_config2.cc index 12b0a7efe..6d0f4a3f5 100644 --- a/server/core/test/test_config2.cc +++ b/server/core/test/test_config2.cc @@ -46,6 +46,11 @@ param_count(&specification, "count_parameter", "Specifies the cardinality of something."); +config::ParamInteger +param_integer(&specification, + "integer_parameter", + "Specifies a number."); + config::ParamDuration param_duration_1(&specification, "duration_parameter_1", @@ -274,6 +279,24 @@ int test_string(config::String& value) return test(value, entries, elements_in_array(entries)); } +int test_integer(config::Integer& value) +{ + static const TestEntry entries[] = + { + { "0", true, 0 }, + { "-1", true, -1 }, + { "1", true, 1 }, + { "-2147483648", true, -2147483648 }, + { "2147483647", true, 2147483647 }, + + { "-2147483649", false }, + { "2147483648", false }, + { "0x10" , false }, + }; + + return test(value, entries, elements_in_array(entries)); +} + int main() { mxb::Log log; @@ -314,5 +337,8 @@ int main() config::String value_string(&configuration, ¶m_string); nErrors += test_string(value_string); + config::Integer value_integer(&configuration, ¶m_integer); + nErrors += test_integer(value_integer); + return nErrors ? EXIT_FAILURE : EXIT_SUCCESS; }