Browse Source

[2312] Implemented OptionCustom::toText() function.

Marcin Siodelski 12 years ago
parent
commit
ff2167388f

+ 19 - 9
src/lib/dhcp/option_custom.cc

@@ -242,20 +242,30 @@ OptionCustom::len() {
     return (length);
 }
 
-std::string OptionCustom::toText(int /* =0 */ ) {
+std::string OptionCustom::toText(int indent /* = 0 */ ) {
     std::stringstream tmp;
 
-    /*    for (int i = 0; i < indent; i++)
+    for (int i = 0; i < indent; ++i)
         tmp << " ";
 
-    tmp << "type=" << type_ << ", len=" << len()-getHeaderLen() << ": ";
+    tmp << "type=" << type_ << ", len=" << len()-getHeaderLen()
+        << ", data fields:" << std::endl;
 
-    for (unsigned int i = 0; i < data_.size(); i++) {
-        if (i) {
-            tmp << ":";
+    OptionDataType data_type = definition_.getType();
+    for (unsigned int i = 0; i < getDataFieldsNum(); ++i) {
+        if (data_type == OPT_RECORD_TYPE) {
+            const OptionDefinition::RecordFieldsCollection& fields =
+                definition_.getRecordFields();
+
+            for (OptionDefinition::RecordFieldsConstIter field = fields.begin();
+                 field != fields.end(); ++field) {
+                for (int j = 0; j < indent + 2; ++j) {
+                    tmp << " ";
+                }
+                tmp << OptionDataTypeUtil::getDataTypeName(*field)
+                    << ", value = " << "here is a value" << std::endl;
+            }
         }
-        tmp << setfill('0') << setw(2) << hex
-            << static_cast<unsigned short>(data_[i]);
     }
 
     // print suboptions
@@ -263,7 +273,7 @@ std::string OptionCustom::toText(int /* =0 */ ) {
          opt != options_.end();
          ++opt) {
         tmp << (*opt).second->toText(indent+2);
-        } */
+    }
     return tmp.str();
 }
 

+ 69 - 0
src/lib/dhcp/option_data_types.cc

@@ -18,6 +18,54 @@
 namespace isc {
 namespace dhcp {
 
+OptionDataTypeUtil::OptionDataTypeUtil() {
+    data_types_["empty"] = OPT_EMPTY_TYPE;
+    data_types_["binary"] = OPT_BINARY_TYPE;
+    data_types_["boolean"] = OPT_BOOLEAN_TYPE;
+    data_types_["int8"] = OPT_INT8_TYPE;
+    data_types_["int16"] = OPT_INT16_TYPE;
+    data_types_["int32"] = OPT_INT32_TYPE;
+    data_types_["uint8"] = OPT_UINT8_TYPE;
+    data_types_["uint16"] = OPT_UINT16_TYPE;
+    data_types_["uint32"] = OPT_UINT32_TYPE;
+    data_types_["ipv4-address"] = OPT_IPV4_ADDRESS_TYPE;
+    data_types_["ipv6-address"] = OPT_IPV6_ADDRESS_TYPE;
+    data_types_["string"] = OPT_STRING_TYPE;
+    data_types_["fqdn"] = OPT_FQDN_TYPE;
+    data_types_["record"] = OPT_RECORD_TYPE;
+
+    data_type_names_[OPT_EMPTY_TYPE] = "empty";
+    data_type_names_[OPT_BINARY_TYPE] = "binary";
+    data_type_names_[OPT_BOOLEAN_TYPE] = "boolean";
+    data_type_names_[OPT_INT8_TYPE] = "int8";
+    data_type_names_[OPT_INT16_TYPE] = "int16";
+    data_type_names_[OPT_INT32_TYPE] = "int32";
+    data_type_names_[OPT_UINT8_TYPE] = "uint8";
+    data_type_names_[OPT_UINT16_TYPE] = "uint16";
+    data_type_names_[OPT_UINT32_TYPE] = "uint32";
+    data_type_names_[OPT_IPV4_ADDRESS_TYPE] = "ipv4-address";
+    data_type_names_[OPT_IPV6_ADDRESS_TYPE] = "ipv4-address";
+    data_type_names_[OPT_STRING_TYPE] = "string";
+    data_type_names_[OPT_FQDN_TYPE] = "fqdn";
+    data_type_names_[OPT_RECORD_TYPE] = "record";
+    data_type_names_[OPT_UNKNOWN_TYPE] = "unknown";
+}
+
+OptionDataType
+OptionDataTypeUtil::getDataType(const std::string& data_type) {
+    return (OptionDataTypeUtil::instance().getDataTypeImpl(data_type));
+}
+
+OptionDataType
+OptionDataTypeUtil::getDataTypeImpl(const std::string& data_type) const {
+    std::map<std::string, OptionDataType>::const_iterator data_type_it =
+        data_types_.find(data_type);
+    if (data_type_it != data_types_.end()) {
+        return (data_type_it->second);
+    }
+    return (OPT_UNKNOWN_TYPE);
+}
+
 int
 OptionDataTypeUtil::getDataTypeLen(const OptionDataType data_type) {
     switch (data_type) {
@@ -41,6 +89,27 @@ OptionDataTypeUtil::getDataTypeLen(const OptionDataType data_type) {
     return (0);
 }
 
+const std::string&
+OptionDataTypeUtil::getDataTypeName(const OptionDataType data_type) {
+    return (OptionDataTypeUtil::instance().getDataTypeNameImpl(data_type));
+}
+
+const std::string&
+OptionDataTypeUtil::getDataTypeNameImpl(const OptionDataType data_type) const {
+    std::map<OptionDataType, std::string>::const_iterator data_type_it =
+        data_type_names_.find(data_type);
+    if (data_type_it != data_type_names_.end()) {
+        return (data_type_it->second);
+    }
+    return (data_type_names_.find(OPT_UNKNOWN_TYPE)->second);
+}
+
+OptionDataTypeUtil&
+OptionDataTypeUtil::instance() {
+    static OptionDataTypeUtil instance;
+    return (instance);
+}
+
 void
 OptionDataTypeUtil::readAddress(const std::vector<uint8_t>& buf,
                             const short family,

+ 49 - 1
src/lib/dhcp/option_data_types.h

@@ -174,10 +174,22 @@ struct OptionDataTypeTraits<std::string> {
     static const OptionDataType type = OPT_STRING_TYPE;
 };
 
-/// @brief Utility class to write/read data to/from a buffer.
+/// @brief Utility class for option data types.
 class OptionDataTypeUtil {
 public:
 
+    /// @brief Return option data type from its name.
+    ///
+    /// @param data_type data type name.
+    /// @return option data type.
+    static OptionDataType getDataType(const std::string& data_type);
+
+    /// @brief Return option data type name from the data type enumerator.
+    ///
+    /// @param data_type option data type.
+    /// @return option data type name.
+    static const std::string& getDataTypeName(const OptionDataType data_type);
+
     /// @brief Get data type buffer length.
     ///
     /// This functionm returs the size of a particular data type.
@@ -312,7 +324,43 @@ public:
     /// @param [out] buf output buffer.
     static void writeString(const std::string& value,
                             std::vector<uint8_t>& buf);
+private:
+
+    /// The container holding mapping of data type names to
+    /// data types enumerator.
+    std::map<std::string, OptionDataType> data_types_;
+
+    /// The container holding mapping of data types to data
+    /// type names.
+    std::map<OptionDataType, std::string> data_type_names_;
+
+    /// @brief Private constructor.
+    ///
+    /// This constructor is private because this class should
+    /// be used as singleton (through static public functions).
+    OptionDataTypeUtil();
+
+    /// @brief Return instance of OptionDataTypeUtil
+    ///
+    /// This function is used by some of the public static functions
+    /// to create an instance of OptionDataTypeUtil class.
+    /// When instance is called it calls the class'es constructor
+    /// and initializes some of the private data members.
+    ///
+    /// @return instance of OptionDataTypeUtil singleton.
+    static OptionDataTypeUtil& instance();
 
+    /// @brief Return option data type from its name.
+    ///
+    /// @param data_type data type name.
+    /// @return option data type.
+    OptionDataType getDataTypeImpl(const std::string& data_type) const;
+
+    /// @brief Return option data type name from the data type enumerator.
+    ///
+    /// @param data_type option data type.
+    /// @return option data type name.
+    const std::string& getDataTypeNameImpl(const OptionDataType data_type) const;
 };
 
 

+ 123 - 149
src/lib/dhcp/option_definition.cc

@@ -28,150 +28,6 @@ using namespace isc::util;
 namespace isc {
 namespace dhcp {
 
-OptionDefinition::DataTypeUtil::DataTypeUtil() {
-    data_types_["empty"] = OPT_EMPTY_TYPE;
-    data_types_["binary"] = OPT_BINARY_TYPE;
-    data_types_["boolean"] = OPT_BOOLEAN_TYPE;
-    data_types_["int8"] = OPT_INT8_TYPE;
-    data_types_["int16"] = OPT_INT16_TYPE;
-    data_types_["int32"] = OPT_INT32_TYPE;
-    data_types_["uint8"] = OPT_UINT8_TYPE;
-    data_types_["uint16"] = OPT_UINT16_TYPE;
-    data_types_["uint32"] = OPT_UINT32_TYPE;
-    data_types_["ipv4-address"] = OPT_IPV4_ADDRESS_TYPE;
-    data_types_["ipv6-address"] = OPT_IPV6_ADDRESS_TYPE;
-    data_types_["string"] = OPT_STRING_TYPE;
-    data_types_["fqdn"] = OPT_FQDN_TYPE;
-    data_types_["record"] = OPT_RECORD_TYPE;
-}
-
-OptionDataType
-OptionDefinition::DataTypeUtil::getOptionDataType(const std::string& data_type) {
-    std::map<std::string, OptionDataType>::const_iterator data_type_it =
-        data_types_.find(data_type);
-    if (data_type_it != data_types_.end()) {
-        return (data_type_it->second);
-    }
-    return (OPT_UNKNOWN_TYPE);
-}
-
-template<typename T>
-T OptionDefinition::DataTypeUtil::lexicalCastWithRangeCheck(const std::string& value_str) const {
-    // Lexical cast in case of our data types make sense only
-    // for uintX_t, intX_t and bool type.
-    if (!OptionDataTypeTraits<T>::integer_type &&
-        OptionDataTypeTraits<T>::type != OPT_BOOLEAN_TYPE) {
-        isc_throw(BadDataTypeCast, "unable to do lexical cast to non-integer and"
-                  << " non-boolean data type");
-    }
-    // We use the 64-bit value here because it has wider range than
-    // any other type we use here and it allows to detect out of
-    // bounds conditions e.g. negative value specified for uintX_t
-    // data type. Obviously if the value exceeds the limits of int64
-    // this function will not handle that properly.
-    int64_t result = 0;
-    try {
-        result = boost::lexical_cast<int64_t>(value_str);
-    } catch (const boost::bad_lexical_cast& ex) {
-        // Prepare error message here.
-        std::string data_type_str = "boolean";
-        if (OptionDataTypeTraits<T>::integer_type) {
-            data_type_str = "integer";
-        }
-        isc_throw(BadDataTypeCast, "unable to do lexical cast to " << data_type_str
-                  << " data type for value " << value_str << ": " << ex.what());
-    }
-    // Perform range checks for integer values only (exclude bool values).
-    if (OptionDataTypeTraits<T>::integer_type) {
-        if (result > numeric_limits<T>::max() ||
-            result < numeric_limits<T>::min()) {
-            isc_throw(BadDataTypeCast, "unable to do lexical cast for value "
-                      << value_str << ". This value is expected to be in the range of "
-                      << numeric_limits<T>::min() << ".." << numeric_limits<T>::max());
-        }
-    }
-    return (static_cast<T>(result));
-}
-
-void
-OptionDefinition::DataTypeUtil::writeToBuffer(const std::string& value,
-                                              const OptionDataType type,
-                                              OptionBuffer& buf) {
-    // We are going to write value given by value argument to the buffer.
-    // The actual type of the value is given by second argument. Check
-    // this argument to determine how to write this value to the buffer.
-    switch (type) {
-    case OPT_BINARY_TYPE:
-        OptionDataTypeUtil::writeBinary(value, buf);
-        return;
-    case OPT_BOOLEAN_TYPE:
-        // We encode the true value as 1 and false as 0 on 8 bits.
-        // That way we actually waste 7 bits but it seems to be the
-        // simpler way to encode boolean.
-        // @todo Consider if any other encode methods can be used.
-        OptionDataTypeUtil::writeBool(lexicalCastWithRangeCheck<bool>(value), buf);
-        return;
-    case OPT_INT8_TYPE:
-        OptionDataTypeUtil::writeInt<uint8_t>(lexicalCastWithRangeCheck<int8_t>(value),
-                                              buf);
-        return;
-    case OPT_INT16_TYPE:
-        OptionDataTypeUtil::writeInt<uint16_t>(lexicalCastWithRangeCheck<int16_t>(value),
-                                               buf);
-        return;
-    case OPT_INT32_TYPE:
-        OptionDataTypeUtil::writeInt<uint32_t>(lexicalCastWithRangeCheck<int32_t>(value),
-                                               buf);
-        return;
-    case OPT_UINT8_TYPE:
-        OptionDataTypeUtil::writeInt<uint8_t>(lexicalCastWithRangeCheck<uint8_t>(value),
-                                              buf);
-        return;
-    case OPT_UINT16_TYPE:
-        OptionDataTypeUtil::writeInt<uint16_t>(lexicalCastWithRangeCheck<uint16_t>(value),
-                                               buf);
-        return;
-    case OPT_UINT32_TYPE:
-        OptionDataTypeUtil::writeInt<uint32_t>(lexicalCastWithRangeCheck<uint32_t>(value),
-                                               buf);
-        return;
-    case OPT_IPV4_ADDRESS_TYPE:
-    case OPT_IPV6_ADDRESS_TYPE:
-        {
-            asiolink::IOAddress address(value);
-            if (!address.getAddress().is_v4() &&
-                !address.getAddress().is_v6()) {
-                isc_throw(BadDataTypeCast, "provided address " << address.toText()
-                          << " is not a valid "
-                          << (address.getAddress().is_v4() ? "IPv4" : "IPv6")
-                          << " address");
-            }
-            OptionDataTypeUtil::writeAddress(address, buf);
-            return;
-        }
-    case OPT_STRING_TYPE:
-        OptionDataTypeUtil::writeString(value, buf);
-        return;
-    case OPT_FQDN_TYPE:
-        {
-            // FQDN implementation is not terribly complicated but will require
-            // creation of some additional logic (maybe object) that will parse
-            // the fqdn into labels.
-            isc_throw(isc::NotImplemented, "write of FQDN record into option buffer"
-                      " is not supported yet");
-            return;
-        }
-    default:
-        // We hit this point because invalid option data type has been specified
-        // This may be the case because 'empty' or 'record' data type has been
-        // specified. We don't throw exception here because it will be thrown
-        // at the exit point from this function.
-        ;
-    }
-    isc_throw(isc::BadValue, "attempt to write invalid option data field type"
-              " into the option buffer: " << type);
-
-}
 
 OptionDefinition::OptionDefinition(const std::string& name,
                                  const uint16_t code,
@@ -184,7 +40,7 @@ OptionDefinition::OptionDefinition(const std::string& name,
     // Data type is held as enum value by this class.
     // Use the provided option type string to get the
     // corresponding enum value.
-    type_ = DataTypeUtil::instance().getOptionDataType(type);
+    type_ = OptionDataTypeUtil::getDataType(type);
 }
 
 OptionDefinition::OptionDefinition(const std::string& name,
@@ -199,7 +55,7 @@ OptionDefinition::OptionDefinition(const std::string& name,
 
 void
 OptionDefinition::addRecordField(const std::string& data_type_name) {
-    OptionDataType data_type = DataTypeUtil::instance().getOptionDataType(data_type_name);
+    OptionDataType data_type = OptionDataTypeUtil::getDataType(data_type_name);
     addRecordField(data_type);
 }
 
@@ -291,10 +147,10 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
         if (values.size() == 0) {
             isc_throw(InvalidOptionValue, "no option value specified");
         }
-        DataTypeUtil::instance().writeToBuffer(values[0], type_, buf);
+        writeToBuffer(values[0], type_, buf);
     } else if (array_type_ && type_ != OPT_RECORD_TYPE) {
         for (size_t i = 0; i < values.size(); ++i) {
-            DataTypeUtil::instance().writeToBuffer(values[i], type_, buf);
+            writeToBuffer(values[i], type_, buf);
         }
     } else if (type_ == OPT_RECORD_TYPE) {
         const RecordFieldsCollection& records = getRecordFields();
@@ -304,7 +160,7 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
                       << " provided.");
         }
         for (size_t i = 0; i < records.size(); ++i) {
-            DataTypeUtil::instance().writeToBuffer(values[i], records[i], buf);
+            writeToBuffer(values[i], records[i], buf);
         }
     }
     return (optionFactory(u, type, buf.begin(), buf.end()));
@@ -410,6 +266,124 @@ OptionDefinition::haveIAAddr6Format() const {
     return (haveIAx6Format(OPT_IPV6_ADDRESS_TYPE));
 }
 
+template<typename T>
+T OptionDefinition::lexicalCastWithRangeCheck(const std::string& value_str) const {
+    // Lexical cast in case of our data types make sense only
+    // for uintX_t, intX_t and bool type.
+    if (!OptionDataTypeTraits<T>::integer_type &&
+        OptionDataTypeTraits<T>::type != OPT_BOOLEAN_TYPE) {
+        isc_throw(BadDataTypeCast, "unable to do lexical cast to non-integer and"
+                  << " non-boolean data type");
+    }
+    // We use the 64-bit value here because it has wider range than
+    // any other type we use here and it allows to detect out of
+    // bounds conditions e.g. negative value specified for uintX_t
+    // data type. Obviously if the value exceeds the limits of int64
+    // this function will not handle that properly.
+    int64_t result = 0;
+    try {
+        result = boost::lexical_cast<int64_t>(value_str);
+    } catch (const boost::bad_lexical_cast& ex) {
+        // Prepare error message here.
+        std::string data_type_str = "boolean";
+        if (OptionDataTypeTraits<T>::integer_type) {
+            data_type_str = "integer";
+        }
+        isc_throw(BadDataTypeCast, "unable to do lexical cast to " << data_type_str
+                  << " data type for value " << value_str << ": " << ex.what());
+    }
+    // Perform range checks for integer values only (exclude bool values).
+    if (OptionDataTypeTraits<T>::integer_type) {
+        if (result > numeric_limits<T>::max() ||
+            result < numeric_limits<T>::min()) {
+            isc_throw(BadDataTypeCast, "unable to do lexical cast for value "
+                      << value_str << ". This value is expected to be in the range of "
+                      << numeric_limits<T>::min() << ".." << numeric_limits<T>::max());
+        }
+    }
+    return (static_cast<T>(result));
+}
+
+void
+OptionDefinition::writeToBuffer(const std::string& value,
+                                const OptionDataType type,
+                                OptionBuffer& buf) const {
+    // We are going to write value given by value argument to the buffer.
+    // The actual type of the value is given by second argument. Check
+    // this argument to determine how to write this value to the buffer.
+    switch (type) {
+    case OPT_BINARY_TYPE:
+        OptionDataTypeUtil::writeBinary(value, buf);
+        return;
+    case OPT_BOOLEAN_TYPE:
+        // We encode the true value as 1 and false as 0 on 8 bits.
+        // That way we actually waste 7 bits but it seems to be the
+        // simpler way to encode boolean.
+        // @todo Consider if any other encode methods can be used.
+        OptionDataTypeUtil::writeBool(lexicalCastWithRangeCheck<bool>(value), buf);
+        return;
+    case OPT_INT8_TYPE:
+        OptionDataTypeUtil::writeInt<uint8_t>(lexicalCastWithRangeCheck<int8_t>(value),
+                                              buf);
+        return;
+    case OPT_INT16_TYPE:
+        OptionDataTypeUtil::writeInt<uint16_t>(lexicalCastWithRangeCheck<int16_t>(value),
+                                               buf);
+        return;
+    case OPT_INT32_TYPE:
+        OptionDataTypeUtil::writeInt<uint32_t>(lexicalCastWithRangeCheck<int32_t>(value),
+                                               buf);
+        return;
+    case OPT_UINT8_TYPE:
+        OptionDataTypeUtil::writeInt<uint8_t>(lexicalCastWithRangeCheck<uint8_t>(value),
+                                              buf);
+        return;
+    case OPT_UINT16_TYPE:
+        OptionDataTypeUtil::writeInt<uint16_t>(lexicalCastWithRangeCheck<uint16_t>(value),
+                                               buf);
+        return;
+    case OPT_UINT32_TYPE:
+        OptionDataTypeUtil::writeInt<uint32_t>(lexicalCastWithRangeCheck<uint32_t>(value),
+                                               buf);
+        return;
+    case OPT_IPV4_ADDRESS_TYPE:
+    case OPT_IPV6_ADDRESS_TYPE:
+        {
+            asiolink::IOAddress address(value);
+            if (!address.getAddress().is_v4() &&
+                !address.getAddress().is_v6()) {
+                isc_throw(BadDataTypeCast, "provided address " << address.toText()
+                          << " is not a valid "
+                          << (address.getAddress().is_v4() ? "IPv4" : "IPv6")
+                          << " address");
+            }
+            OptionDataTypeUtil::writeAddress(address, buf);
+            return;
+        }
+    case OPT_STRING_TYPE:
+        OptionDataTypeUtil::writeString(value, buf);
+        return;
+    case OPT_FQDN_TYPE:
+        {
+            // FQDN implementation is not terribly complicated but will require
+            // creation of some additional logic (maybe object) that will parse
+            // the fqdn into labels.
+            isc_throw(isc::NotImplemented, "write of FQDN record into option buffer"
+                      " is not supported yet");
+            return;
+        }
+    default:
+        // We hit this point because invalid option data type has been specified
+        // This may be the case because 'empty' or 'record' data type has been
+        // specified. We don't throw exception here because it will be thrown
+        // at the exit point from this function.
+        ;
+    }
+    isc_throw(isc::BadValue, "attempt to write invalid option data field type"
+              " into the option buffer: " << type);
+
+}
+
 OptionPtr
 OptionDefinition::factoryAddrList4(uint16_t type,
                                   OptionBufferConstIter begin,

+ 34 - 77
src/lib/dhcp/option_definition.h

@@ -131,83 +131,6 @@ public:
     /// Const iterator for record data fields.
     typedef std::vector<OptionDataType>::const_iterator RecordFieldsConstIter;
 
-private:
-
-    /// @brief Utility class for operations on OptionDataTypes.
-    ///
-    /// This class is implemented as the singleton because the list of
-    /// supported data types need only be loaded only once into memory as it
-    /// can persist for all option definitions.
-    ///
-    /// @todo This class can be extended to return the string value
-    /// representing the data type from the enum value.
-    class DataTypeUtil {
-    public:
-
-        /// @brief Return the sole instance of this class.
-        ///
-        /// @return instance of this class.
-        static DataTypeUtil& instance() {
-            static DataTypeUtil instance;
-            return (instance);
-        }
-
-        /// @brief Convert type given as string value to option data type.
-        ///
-        /// @param data_type_name data type string.
-        ///
-        /// @return option data type.
-        OptionDataType getOptionDataType(const std::string& data_type_name);
-
-        /// @brief Perform lexical cast of the value and validate its range.
-        ///
-        /// This function performs lexical cast of a string value to integer
-        /// or boolean value and checks if the resulting value is within a
-        /// range of a target type. Note that range checks are not performed
-        /// on boolean values. The target type should be one of the supported
-        /// integer types or bool.
-        ///
-        /// @param value_str input value given as string.
-        /// @tparam T target type for lexical cast.
-        ///
-        /// @return cast value.
-        /// @throw BadDataTypeCast if cast was not successful.
-        template<typename T>
-        T lexicalCastWithRangeCheck(const std::string& value_str) const;
-
-        /// @brief Write the string value into the provided buffer.
-        ///
-        /// This method writes the given value to the specified buffer.
-        /// The provided string value may represent data of different types.
-        /// The actual data type is specified with the second argument.
-        /// Based on a value of this argument, this function will first
-        /// try to cast the string value to the particular data type and
-        /// if it is successful it will store the data in the buffer
-        /// in a binary format.
-        ///
-        /// @param value string representation of the value to be written.
-        /// @param type the actual data type to be stored.
-        /// @param [in, out] buf buffer where the value is to be stored.
-        ///
-        /// @throw BadDataTypeCast if data write was unsuccessful.
-        void writeToBuffer(const std::string& value, const OptionDataType type,
-                           OptionBuffer& buf);
-
-    private:
-        /// @brief Private constructor.
-        ///
-        /// Constructor initializes the internal data structures, e.g.
-        /// mapping between data type name and the corresponding enum.
-        /// This constructor is private to ensure that exactly one
-        /// instance of this class can be created using \ref instance
-        /// function.
-        DataTypeUtil();
-
-        /// Map of data types, maps name of the type to enum value.
-        std::map<std::string, OptionDataType> data_types_;
-    };
-
-public:
     /// @brief Constructor.
     ///
     /// @param name option name.
@@ -471,6 +394,40 @@ private:
         return (type == type_);
     }
 
+    /// @brief Perform lexical cast of the value and validate its range.
+    ///
+    /// This function performs lexical cast of a string value to integer
+    /// or boolean value and checks if the resulting value is within a
+    /// range of a target type. Note that range checks are not performed
+    /// on boolean values. The target type should be one of the supported
+    /// integer types or bool.
+    ///
+    /// @param value_str input value given as string.
+    /// @tparam T target type for lexical cast.
+    ///
+    /// @return cast value.
+    /// @throw BadDataTypeCast if cast was not successful.
+    template<typename T>
+    T lexicalCastWithRangeCheck(const std::string& value_str) const;
+
+    /// @brief Write the string value into the provided buffer.
+    ///
+    /// This method writes the given value to the specified buffer.
+    /// The provided string value may represent data of different types.
+    /// The actual data type is specified with the second argument.
+    /// Based on a value of this argument, this function will first
+    /// try to cast the string value to the particular data type and
+    /// if it is successful it will store the data in the buffer
+    /// in a binary format.
+    ///
+    /// @param value string representation of the value to be written.
+    /// @param type the actual data type to be stored.
+    /// @param [in, out] buf buffer where the value is to be stored.
+    ///
+    /// @throw BadDataTypeCast if data write was unsuccessful.
+    void writeToBuffer(const std::string& value, const OptionDataType type,
+                       OptionBuffer& buf) const;
+
     /// @brief Sanity check universe value.
     ///
     /// @param expected_universe expected universe value.