Browse Source

[5097] Added a new template for D2ClientConfigParser tools

Francis Dupont 8 years ago
parent
commit
dad9ff7110
2 changed files with 77 additions and 1 deletions
  1. 31 1
      src/lib/cc/simple_parser.h
  2. 46 0
      src/lib/cc/tests/simple_parser_unittest.cc

+ 31 - 1
src/lib/cc/simple_parser.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -156,6 +156,7 @@ class SimpleParser {
     /// @tparam out_of_range always @c isc::dhcp::DhcpConfigError
     /// @param name name of the parameter for error report
     /// @param value value of the parameter
+    /// @return a value of int_type
     /// @throw isc::data::TypeError when the value is not an integer
     /// @throw out_of_range when the value does not fit in int_type
     template <typename int_type, class out_of_range> int_type
@@ -169,6 +170,35 @@ class SimpleParser {
         }
         return (static_cast<int_type>(val_int));
     }
+
+    /// @brief Returns a converted value
+    ///
+    /// This template should be instantied in parsers when useful
+    ///
+    /// @tparam target_type the type of the result
+    /// @tparam convert the conversion function std::string -> target_type
+    /// @tparam exception_type always @c isc::dhcp::DhcpConfigError
+    /// @param name name of the parameter for error report
+    /// @param type_name name of target_type for error report
+    /// @param value value of the parameter
+    /// @return a converted value of target_type
+    /// @throw isc::data::TypeError when the value is not an integer
+    /// @throw exception_type when the value cannot be converted
+    template <typename target_type,
+              target_type convert(const std::string&),
+              class exception_type> target_type
+    extractConvert(const std::string& name,
+                   const std::string& type_name,
+                   ConstElementPtr value) const {
+        std::string str = value->stringValue();
+        try {
+            return (convert(str));
+        } catch (const std::exception&) {
+            isc_throw(exception_type, "invalid " << type_name << " (" << str
+                      << ") specified for parameter '" << name
+                      << "' (" << value->getPosition() << ")");
+        }
+    }
 };
 
 };

+ 46 - 0
src/lib/cc/tests/simple_parser_unittest.cc

@@ -61,10 +61,35 @@ public:
     ///
     /// @param name name of the parameter for error report
     /// @param value value of the parameter
+    /// @return an uint8_t value
     uint8_t extractUint8(const std::string& name, ConstElementPtr value) const {
         return (extractInt<uint8_t, isc::OutOfRange>(name, value));
     }
 
+    /// @brief Instantiation of extractConvert
+    ///
+    /// @param name name of the parameter for error report
+    /// @param value value of the parameter
+    /// @return a bool value
+    bool extractBool(const std::string& name, ConstElementPtr value) const {
+        return (extractConvert<bool, toBool, isc::BadValue>
+                    (name, "boolean", value));
+    }
+
+    /// @brief Convert to boolean
+    ///
+    /// @param str the string "false" or "true"
+    /// @return false for "false" and true for "true"
+    /// @thrown isc::OutOfRange if not "false" or "true'
+    static bool toBool(const std::string& str) {
+        if (str == "false") {
+            return (false);
+        } else if (str == "true") {
+            return (true);
+        } else {
+            isc_throw(TypeError, "not a boolean: " << str);
+        }
+    }
 };
 
 // This test checks if the parameters can be inherited from the global
@@ -165,3 +190,24 @@ TEST_F(SimpleParserTest, extractInt) {
     EXPECT_NO_THROW(val = parser.extractUint8("foo", hundred));
     EXPECT_EQ(100, val);
 }
+
+// This test exercises the extractConvert template
+TEST_F(SimpleParserTest, extractConvert) {
+
+    SimpleParserClassTest parser;
+
+    // extractConvert checks if it is a string
+    ConstElementPtr not_bool(new IntElement(1));
+    EXPECT_THROW(parser.extractBool("foo", not_bool), TypeError);
+
+    // checks if extractConvert can return the expected value
+    ConstElementPtr a_bool(new StringElement("false"));
+    bool val = true;
+    EXPECT_NO_THROW(val = parser.extractBool("foo", a_bool));
+    EXPECT_FALSE(val);
+
+    // extractConvert checks convertion
+    ConstElementPtr bad_bool(new StringElement("foo"));
+    EXPECT_THROW(parser.extractBool("bar", bad_bool), isc::BadValue);
+}
+