]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#429,!217] StampedValue can now parse string values.
authorMarcin Siodelski <marcin@isc.org>
Thu, 31 Jan 2019 08:43:24 +0000 (09:43 +0100)
committerMarcin Siodelski <marcin@isc.org>
Thu, 31 Jan 2019 17:07:35 +0000 (18:07 +0100)
src/lib/cc/stamped_value.cc
src/lib/cc/stamped_value.h
src/lib/cc/tests/stamped_value_unittest.cc

index 25577388f894d486b355244ec36b35eb600d482c..9e23a08020bc4ca0e93e160ad361507fde88f7aa 100644 (file)
@@ -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<int64_t>(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<double>(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_) {
index 0ffcdb7c9e293e9214c59f3a4829e0c33983f786..73f3dacc3d1678f9da7c41a1990d2cb1dde087fe 100644 (file)
@@ -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
index 0fddf0d8a892d0a5ee2f4838b192a32d09441479..fa0cd0769f1f7f0b496ebfdc8f3e982093c7a155 100644 (file)
@@ -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.