MXS-2346 Add config::ParamInteger and config::Integer

This commit is contained in:
Johan Wikman
2019-04-02 10:21:42 +03:00
parent 17aa494c87
commit c381aefefc
3 changed files with 245 additions and 47 deletions

View File

@ -298,30 +298,10 @@ private:
value_type m_default_value; value_type m_default_value;
}; };
/** class ParamNumber : public Param
* ParamCount
*/
class ParamCount : public Param
{ {
public: public:
using value_type = uint64_t; using value_type = int64_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;
std::string default_to_string() const override; 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; bool from_string(const std::string& value, value_type* pValue, std::string* pMessage = nullptr) const;
std::string to_string(value_type value) 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: private:
ParamCount(Specification* pSpecification, ParamCount(Specification* pSpecification,
const char* zName, const char* zName,
const char* zDescription, const char* zDescription,
Kind kind, Kind kind,
value_type default_value) value_type default_value,
: Param(pSpecification, zName, zDescription, kind, MXS_MODULE_PARAM_COUNT) value_type min_value,
, m_default_value(default_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: 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 * Count
*/ */
class Count : public ConcreteType<Count, ParamCount> class Count : public Number
{ {
public: public:
Count(Configuration* pConfiguration, const ParamCount* pParam) 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)
{ {
} }
}; };

View File

@ -439,49 +439,44 @@ string ParamBool::to_string(value_type value) const
} }
/** /**
* ParamCount * ParamNumber
*/ */
std::string ParamCount::type() const std::string ParamNumber::default_to_string() const
{
return "count";
}
std::string ParamCount::default_to_string() const
{ {
return to_string(m_default_value); 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; value_type value;
return from_string(value_as_string, &value, pMessage); 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); mxb_assert(&value.parameter() == this);
Count& count_value = static_cast<Count&>(value); Number& number_value = static_cast<Number&>(value);
value_type x; value_type x;
bool valid = from_string(value_as_string, &x); bool valid = from_string(value_as_string, &x);
if (valid) if (valid)
{ {
count_value.set(x); number_value.set(x);
} }
return valid; 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, value_type* pValue,
std::string* pMessage) const std::string* pMessage) const
{ {
const char* zValue = value_as_string.c_str(); const char* zValue = value_as_string.c_str();
char* zEnd; char* zEnd;
long l = strtol(zValue, &zEnd, 10); 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) if (valid)
{ {
@ -489,18 +484,49 @@ bool ParamCount::from_string(const std::string& value_as_string,
} }
else if (pMessage) 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; *pMessage += value_as_string;
} }
return valid; 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); return std::to_string(value);
} }
/**
* ParamCount
*/
std::string ParamCount::type() const
{
return "count";
}
/**
* ParamInteger
*/
std::string ParamInteger::type() const
{
return "integer";
}
/** /**
* ParamPath * ParamPath
*/ */

View File

@ -46,6 +46,11 @@ param_count(&specification,
"count_parameter", "count_parameter",
"Specifies the cardinality of something."); "Specifies the cardinality of something.");
config::ParamInteger
param_integer(&specification,
"integer_parameter",
"Specifies a number.");
config::ParamDuration<std::chrono::seconds> config::ParamDuration<std::chrono::seconds>
param_duration_1(&specification, param_duration_1(&specification,
"duration_parameter_1", "duration_parameter_1",
@ -274,6 +279,24 @@ int test_string(config::String& value)
return test(value, entries, elements_in_array(entries)); 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() int main()
{ {
mxb::Log log; mxb::Log log;
@ -314,5 +337,8 @@ int main()
config::String value_string(&configuration, &param_string); config::String value_string(&configuration, &param_string);
nErrors += test_string(value_string); nErrors += test_string(value_string);
config::Integer value_integer(&configuration, &param_integer);
nErrors += test_integer(value_integer);
return nErrors ? EXIT_FAILURE : EXIT_SUCCESS; return nErrors ? EXIT_FAILURE : EXIT_SUCCESS;
} }