MXS-2346 Add config::ParamInteger and config::Integer
This commit is contained in:
		@ -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<uint32_t>::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<uint32_t>::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<uint32_t>::max()
 | 
			
		||||
                      ? max_value : std::numeric_limits<uint32_t>::max())
 | 
			
		||||
    {
 | 
			
		||||
        mxb_assert(min_value >= 0);
 | 
			
		||||
        mxb_assert(max_value <= std::numeric_limits<uint32_t>::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<int32_t>::min(),
 | 
			
		||||
                       std::numeric_limits<int32_t>::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<int32_t>::min(),
 | 
			
		||||
                       std::numeric_limits<int32_t>::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<int32_t>::min()
 | 
			
		||||
                      ? min_value : std::numeric_limits<int32_t>::min(),
 | 
			
		||||
                      max_value <= std::numeric_limits<int32_t>::max()
 | 
			
		||||
                      ? max_value : std::numeric_limits<int32_t>::max())
 | 
			
		||||
    {
 | 
			
		||||
        mxb_assert(min_value >= std::numeric_limits<int32_t>::min());
 | 
			
		||||
        mxb_assert(max_value <= std::numeric_limits<int32_t>::max());
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -954,14 +1079,35 @@ inline bool operator >= (const typename ParamType::value_type& lhs,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Number : public ConcreteType<Number, ParamNumber>
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
    Number(Configuration* pConfiguration, const ParamNumber* pParam)
 | 
			
		||||
        : ConcreteType(pConfiguration, pParam)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Count
 | 
			
		||||
 */
 | 
			
		||||
class Count : public ConcreteType<Count, ParamCount>
 | 
			
		||||
class Count : public Number
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    Count(Configuration* pConfiguration, const ParamCount* pParam)
 | 
			
		||||
        : ConcreteType(pConfiguration, pParam)
 | 
			
		||||
        : Number(pConfiguration, pParam)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Integer
 | 
			
		||||
 */
 | 
			
		||||
class Integer : public Number
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    Integer(Configuration* pConfiguration, const ParamInteger* pParam)
 | 
			
		||||
        : Number(pConfiguration, pParam)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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<Count&>(value);
 | 
			
		||||
    Number& number_value = static_cast<Number&>(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,
 | 
			
		||||
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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -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<std::chrono::seconds>
 | 
			
		||||
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<config::Integer::value_type> 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user