Browse Source

[2491] Added function to add new integer data field to an option.

Marcin Siodelski 12 years ago
parent
commit
10e87104e0

+ 2 - 10
src/lib/dhcp/option_custom.cc

@@ -73,18 +73,10 @@ OptionCustom::addArrayDataField(const bool value) {
 }
 
 void
-OptionCustom::checkArrayType() const {
-    if (!definition_.getArrayType()) {
-        isc_throw(InvalidOperation, "failed to add new array entry to an"
-                  << " option. The option is not an array.");
-    }
-}
-
-void
 OptionCustom::checkIndex(const uint32_t index) const {
     if (index >= buffers_.size()) {
         isc_throw(isc::OutOfRange, "specified data field index " << index
-                  << " is out of rangex.");
+                  << " is out of range.");
     }
 }
 
@@ -113,7 +105,7 @@ OptionCustom::checkDataType(const uint32_t index) const {
     if (OptionDataTypeTraits<T>::type != data_type) {
         isc_throw(isc::dhcp::InvalidDataType,
                   "specified data type " << data_type << " does not"
-                  "match data type in an option definition for field"
+                  " match the data type in an option definition for field"
                   " index " << index);
     }
 }

+ 26 - 1
src/lib/dhcp/option_custom.h

@@ -98,6 +98,26 @@ public:
     /// @param value value to be stored in the created buffer.
     void addArrayDataField(const bool value);
 
+    /// @brief Create new buffer and store integer value in it.
+    ///
+    /// @param value value to be stored in the created buffer.
+    /// @tparam T integer type of the value being stored.
+    template<typename T>
+    void addArrayDataField(const T value) {
+        checkArrayType();
+
+        OptionDataType data_type = definition_.getType();
+        if (OptionDataTypeTraits<T>::type != data_type) {
+            isc_throw(isc::dhcp::InvalidDataType,
+                      "specified data type " << data_type << " does not"
+                      " match the data type in an option definition");
+        }
+
+        OptionBuffer buf;
+        OptionDataTypeUtil::writeInt<T>(value, buf);
+        buffers_.push_back(buf);
+    }
+
     /// @brief Return a number of the data fields.
     ///
     /// @return number of data fields held by the option.
@@ -280,7 +300,12 @@ private:
     /// an array.
     ///
     /// @throw isc::InvalidOperation if option is not an array.
-    inline void checkArrayType() const;
+    inline void checkArrayType() const {
+        if (!definition_.getArrayType()) {
+            isc_throw(InvalidOperation, "failed to add new array entry to an"
+                      << " option. The option is not an array.");
+        }
+    }
 
     /// @brief Verify that the integer type is consistent with option
     /// field type.

+ 37 - 0
src/lib/dhcp/tests/option_custom_unittest.cc

@@ -1007,6 +1007,43 @@ TEST_F(OptionCustomTest, setBooleanDataArray) {
     EXPECT_TRUE(value2);
 }
 
+// The purpose of this test is to verify that am option carying
+// an array of 16-bit signed integer values can be created with
+// no values initially and that the values can be later added to it.
+TEST_F(OptionCustomTest, setUint16DataArray) {
+    OptionDefinition opt_def("OPTION_FOO", 1000, "uint16", true);
+
+    // Create an option and let the data field be initialized
+    // to default value (do not provide any data buffer).
+    boost::scoped_ptr<OptionCustom> option;
+    ASSERT_NO_THROW(
+        option.reset(new OptionCustom(opt_def, Option::V6));
+    );
+    ASSERT_TRUE(option);
+
+    // Initially, the array should contain no values.
+    ASSERT_EQ(0, option->getDataFieldsNum());
+
+    // Add 3 new data fields holding integer values.
+    ASSERT_NO_THROW(option->addArrayDataField<uint16_t>(67));
+    ASSERT_NO_THROW(option->addArrayDataField<uint16_t>(876));
+    ASSERT_NO_THROW(option->addArrayDataField<uint16_t>(32222));
+
+    // We should now have 3 data fields.
+    ASSERT_EQ(3, option->getDataFieldsNum());
+
+    // Check that the values have been correctly set.
+    uint16_t value0;
+    ASSERT_NO_THROW(value0 = option->readInteger<uint16_t>(0));
+    EXPECT_EQ(67, value0);
+    uint16_t value1;
+    ASSERT_NO_THROW(value1 = option->readInteger<uint16_t>(1));
+    EXPECT_EQ(876, value1);
+    uint16_t value2;
+    ASSERT_NO_THROW(value2 = option->readInteger<uint16_t>(2));
+    EXPECT_EQ(32222, value2);
+}
+
 /// The purpose of this test is to verify that an option comprising
 /// array of IPv4 address can be created with no addresses and that
 /// multiple IPv4 addresses can be added to it after creation.