From: Marcin Siodelski Date: Thu, 31 Jan 2019 08:43:24 +0000 (+0100) Subject: [#429,!217] StampedValue can now parse string values. X-Git-Tag: 429-Updated-StampedValue-to-support-reals_base~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1550a5dece49cadbc0987bbc4b93a5203729f804;p=thirdparty%2Fkea.git [#429,!217] StampedValue can now parse string values. --- diff --git a/src/lib/cc/stamped_value.cc b/src/lib/cc/stamped_value.cc index 25577388f8..9e23a08020 100644 --- a/src/lib/cc/stamped_value.cc +++ b/src/lib/cc/stamped_value.cc @@ -40,6 +40,56 @@ StampedValue::create(const std::string& name, const std::string& value) { return (StampedValuePtr(new StampedValue(name, value))); } +StampedValuePtr +StampedValue::create(const std::string& name, const std::string& value, + Element::types parameter_type) { + StampedValuePtr stamped_value; + + try { + switch (parameter_type) { + case Element::string: + stamped_value = StampedValue::create(name, value); + break; + + case Element::integer: + stamped_value = StampedValue::create(name, + Element::create(boost::lexical_cast(value))); + break; + + case Element::boolean: + // We only allow "1" and "0" as input to this function. + if ((value != "0") && (value != "1")) { + isc_throw(BadValue, "StampedValue: invalid value " << value + << " specified as boolean. Expected \"0\" or \"1\""); + } + stamped_value = StampedValue::create(name, + Element::create((value == "0") ? false : true)); + break; + + case Element::real: + stamped_value = StampedValue::create(name, + Element::create(boost::lexical_cast(value))); + break; + + default: + // Invalid data type provided as argument. + isc_throw(TypeError, "StampedValue: unsupported type '" + << Element::typeToName(parameter_type) + << " of the parameter '" << name); + } + + } catch (const boost::bad_lexical_cast& ex) { + // Failed to cast the value to a given type. + isc_throw(BadValue, "StampedValue: the value of the parameter '" + << Element::typeToName(parameter_type) + << "' can't be converted to " + << Element::typeToName(parameter_type) + << " type"); + } + + return (stamped_value); +} + int StampedValue::getType() const { if (!value_) { diff --git a/src/lib/cc/stamped_value.h b/src/lib/cc/stamped_value.h index 0ffcdb7c9e..73f3dacc3d 100644 --- a/src/lib/cc/stamped_value.h +++ b/src/lib/cc/stamped_value.h @@ -89,6 +89,21 @@ public: static StampedValuePtr create(const std::string& name, const std::string& value); + /// @brief Factory function which attempts to convert provided + /// string value to a given type. + /// + /// This factory function is useful in cases when the value is + /// read as a string from a database. The string value has to + /// be converted to the appropriate data type. The type is also + /// known from the database. + /// + /// @param name Name of the value. + /// @param value Value given as string to be converted. + /// @param type Type of the value to convert to. + static StampedValuePtr create(const std::string& name, + const std::string& value, + Element::types type); + /// @brief Returns a type of the value. /// /// @return Type of the value as integer. It can be compared diff --git a/src/lib/cc/tests/stamped_value_unittest.cc b/src/lib/cc/tests/stamped_value_unittest.cc index 0fddf0d8a8..fa0cd0769f 100644 --- a/src/lib/cc/tests/stamped_value_unittest.cc +++ b/src/lib/cc/tests/stamped_value_unittest.cc @@ -44,6 +44,17 @@ TEST(StampedValueTest, createFromString) { EXPECT_THROW(value->getDoubleValue(), TypeError); } +// Tests that the stamped value can be created from string using the +// factory function variant that takes parameter type as an argument. +TEST(StampedValueTest, convertStringToString) { + StampedValuePtr value; + ASSERT_NO_THROW(value = StampedValue::create("bar", "foo", Element::string)); + EXPECT_FALSE(value->amNull()); + EXPECT_EQ(Element::string, value->getType()); + EXPECT_EQ("bar", value->getName()); + EXPECT_EQ("foo", value->getValue()); +} + // Tests that stamped value from integer can be created. TEST(StampedValueTest, createFromInteger) { StampedValuePtr value; @@ -60,6 +71,18 @@ TEST(StampedValueTest, createFromInteger) { EXPECT_THROW(value->getDoubleValue(), TypeError); } +// Tests that stamped value can be converted from string to integer. +TEST(StampedValueTest, convertStringToInteger) { + StampedValuePtr value; + ASSERT_NO_THROW(value = StampedValue::create("bar", "123", Element::integer)); + EXPECT_FALSE(value->amNull()); + EXPECT_EQ(Element::integer, value->getType()); + EXPECT_EQ("bar", value->getName()); + EXPECT_EQ(123, value->getSignedIntegerValue()); + + EXPECT_THROW(StampedValue::create("bar", "hoho", Element::integer), BadValue); +} + // Tests that stamped value from bool can be created. TEST(StampedValueTest, createFromBool) { StampedValuePtr value; @@ -76,6 +99,24 @@ TEST(StampedValueTest, createFromBool) { EXPECT_THROW(value->getDoubleValue(), TypeError); } +// Tests that stamped value can be converted from string to boolean. +TEST(StampedValueTest, convertStringToBoolean) { + StampedValuePtr value; + ASSERT_NO_THROW(value = StampedValue::create("bar", "1", Element::boolean)); + EXPECT_FALSE(value->amNull()); + EXPECT_EQ(Element::boolean, value->getType()); + EXPECT_EQ("bar", value->getName()); + EXPECT_TRUE(value->getBoolValue()); + + ASSERT_NO_THROW(value = StampedValue::create("foo", "0", Element::boolean)); + EXPECT_FALSE(value->amNull()); + EXPECT_EQ(Element::boolean, value->getType()); + EXPECT_EQ("foo", value->getName()); + EXPECT_FALSE(value->getBoolValue()); + + EXPECT_THROW(StampedValue::create("bar", "888", Element::boolean), BadValue); +} + // Tests that stamped value from real can be created. TEST(StampedValueTest, createFromDouble) { StampedValuePtr value; @@ -92,11 +133,27 @@ TEST(StampedValueTest, createFromDouble) { EXPECT_THROW(value->getBoolValue(), TypeError); } +// Tests that stamped value can be converted from string to real. +TEST(StampedValueTest, convertStringToDouble) { + StampedValuePtr value; + ASSERT_NO_THROW(value = StampedValue::create("bar", "1.67", Element::real)); + EXPECT_FALSE(value->amNull()); + EXPECT_EQ(Element::real, value->getType()); + EXPECT_EQ("bar", value->getName()); + EXPECT_EQ(1.67, value->getDoubleValue()); + + EXPECT_THROW(StampedValue::create("bar", "hoho", Element::real), BadValue); +} + // Tests that the value must have an allowed type. TEST(StampedValueTest, createFailures) { EXPECT_THROW(StampedValue::create("bar", ElementPtr()), BadValue); EXPECT_THROW(StampedValue::create("bar", Element::createMap()), TypeError); EXPECT_THROW(StampedValue::create("bar", Element::createList()), TypeError); + + EXPECT_THROW(StampedValue::create("bar", "1", Element::map), TypeError); + EXPECT_THROW(StampedValue::create("bar", "1", Element::list), TypeError); + EXPECT_THROW(StampedValue::create("bar", "1", Element::null), TypeError); } // Tests that Elements can be created from stamped values.