#include <dhcp/hwaddr.h>
#include <dhcp/pkt4.h>
#include <dhcp4/tests/dhcp4_test_utils.h>
+#include <util/optional_value.h>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <set>
isc::Exception(file, line, what) { };
};
-/// @brief Simple class representing an optional value.
-///
-/// This class encapsulates a value of any type. An additional flag held
-/// by this class indicates if the value is specified, i.e. should be used
-/// by the @c Dhcp4Client class. This is used in cases when the caller
-/// needs to override some values used by the client. For example, the
-/// client sets ciaddr according to the RFC2131, depending on the client's
-/// state and using available lease information. However, a test may need
-/// to override the value being used by the client to test some negative
-/// scenarios (e.g. invalid ciaddr). To do this, the test needs to set
-/// the optional value to the desired value and mark it specified. If the
-/// @c Dhcp4Client finds that the value is specified, it will use this
-/// value in the outgoing message. Otherwise, it will disregard the
-/// value and use the defaults.
-///
-/// @tparam Type of the encapsulated value.
-template<typename T>
-class OptionalValue {
-public:
-
- /// @brief Constructor
- ///
- /// Creates optional value. The value defaults to "unspecified".
- OptionalValue(const T& value)
- : value_(value),
- specified_(false) {
- }
-
- /// @brief Retrieves the actual value.
- T get() const {
- return (value_);
- }
-
- /// @brief Sets the actual value.
- ///
- /// @param value New value.
- void set(const T& value) {
- value_ = value;
- }
-
- /// @brief Sets the new value and marks it specified.
- ///
- /// @param value New actual value.
- void specify(const T& value) {
- set(value);
- specify(true);
- }
-
- /// @brief Sets the value to "specified".
- ///
- /// It does not alter the actual value. It only marks it "specified".
- /// @param specified boolean that determined if a value is specified or not
- void specify(const bool specified) {
- specified_ = specified;
- }
-
- /// @brief Checks if the value is specified or unspecified.
- ///
- /// @return true if the value is specified, false otherwise.
- bool isSpecified() const {
- return (specified_);
- }
-
-private:
- T value_; ///< Encapsulated value.
- bool specified_; ///< Flag which indicates if the value is specified.
-};
-
/// @brief DHCPv4 client used for unit testing.
///
/// This class implements a DHCPv4 "client" which interoperates with the
/// If this value is "unspecified" the default values will be used
/// by the client. If this value is specified, it will override ciaddr
/// in the client's messages.
- OptionalValue<asiolink::IOAddress> ciaddr_;
+ isc::util::OptionalValue<asiolink::IOAddress> ciaddr_;
private:
if USE_SHARED_MEMORY
libkea_util_la_SOURCES += memory_segment_mapped.h memory_segment_mapped.cc
endif
+libkea_util_la_SOURCES += optional_value.h
libkea_util_la_SOURCES += range_utilities.h
libkea_util_la_SOURCES += signal_set.cc signal_set.h
libkea_util_la_SOURCES += encode/base16_from_binary.h
--- /dev/null
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef OPTIONAL_VALUE_H
+#define OPTIONAL_VALUE_H
+
+namespace isc {
+namespace util {
+
+/// @brief Simple class representing an optional value.
+///
+/// This template class encapsulates a value of any type. An additional flag
+/// held by this class indicates if the value is "specified" or "unspecified".
+/// For example, a configuration parser for DHCP server may use this class
+/// to represent the value of the configuration parameter which may appear
+/// in the configuration file, but is not mandatory. The value of the
+/// @c OptionalValue may be initialized to "unspecified" initially. When the
+/// configuration parser finds that the appropriate parameter exists in the
+/// configuration file, the default value can be overriden and the value may
+/// be marked as "specified". If the parameter is not found, the value remains
+/// "unspecified" and the appropriate actions may be taken, e.g. the default
+/// value may be used.
+///
+/// This is a generic class and may be used in all cases when there is a need
+/// for the additional information to be carried along with the value.
+/// Alternative approach is to use a pointer which is only initialized if the
+/// actual value needs to be specified, but this may not be feasible in all
+/// cases.
+///
+/// @tparam Type of the encapsulated value.
+template<typename T>
+class OptionalValue {
+public:
+
+ /// @brief Constructor
+ ///
+ /// Creates optional value. The value defaults to "unspecified".
+ ///
+ /// @param value Default explicit value.
+ /// @param specified Boolean value which determines if the value is
+ /// initially specified or not (default is false).
+ OptionalValue(const T& value, const bool specified = false)
+ : value_(value),
+ specified_(specified) {
+ }
+
+ /// @brief Retrieves the actual value.
+ T get() const {
+ return (value_);
+ }
+
+ /// @brief Sets the actual value.
+ ///
+ /// @param value New value.
+ void set(const T& value) {
+ value_ = value;
+ }
+
+ /// @brief Sets the new value and marks it specified.
+ ///
+ /// @param value New actual value.
+ void specify(const T& value) {
+ set(value);
+ specify(true);
+ }
+
+ /// @brief Sets the value to "specified" or "unspecified".
+ ///
+ /// It does not alter the actual value. It only marks it "specified" or
+ /// "unspecified".
+ /// @param specified boolean that determined if a value is specified or not
+ void specify(const bool specified) {
+ specified_ = specified;
+ }
+
+ /// @brief Checks if the value is specified or unspecified.
+ ///
+ /// @return true if the value is specified, false otherwise.
+ bool isSpecified() const {
+ return (specified_);
+ }
+
+private:
+ T value_; ///< Encapsulated value.
+ bool specified_; ///< Flag which indicates if the value is specified.
+};
+
+} // end of namespace isc::util
+} // end of namespace isc
+
+#endif // OPTIONAL_VALUE_H
endif
run_unittests_SOURCES += memory_segment_common_unittest.h
run_unittests_SOURCES += memory_segment_common_unittest.cc
+run_unittests_SOURCES += optional_value_unittest.cc
run_unittests_SOURCES += qid_gen_unittest.cc
run_unittests_SOURCES += random_number_generator_unittest.cc
run_unittests_SOURCES += socketsession_unittest.cc
--- /dev/null
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <util/optional_value.h>
+#include <gtest/gtest.h>
+
+namespace {
+
+using namespace isc::util;
+
+// This test checks that the constructor sets the values passed as arguments.
+TEST(OptionalValueTest, constructor) {
+ // Do not specify the second parameter. The default should be that
+ // the value is "unspecified".
+ OptionalValue<int> value1(10);
+ EXPECT_EQ(10, value1.get());
+ EXPECT_FALSE(value1.isSpecified());
+
+ // Use the non-default value for second parameter.
+ OptionalValue<int> value2(2, true);
+ EXPECT_EQ(2, value2.get());
+ EXPECT_TRUE(value2.isSpecified());
+}
+
+// This test checks that the OptionalValue::set and OptionalValue::specify
+// set the values as expected.
+TEST(OptionalValueTest, set) {
+ OptionalValue<int> value(10);
+ ASSERT_EQ(10, value.get());
+ ASSERT_FALSE(value.isSpecified());
+
+ // Set new value. This should not change the "specified" flag.
+ value.set(100);
+ ASSERT_EQ(100, value.get());
+ ASSERT_FALSE(value.isSpecified());
+
+ // Mark value "specified". The value itself should not change.
+ value.specify(true);
+ ASSERT_EQ(100, value.get());
+ ASSERT_TRUE(value.isSpecified());
+
+ // Once it is "specified", set the new value. It should remain specified.
+ value.set(5);
+ ASSERT_EQ(5, value.get());
+ ASSERT_TRUE(value.isSpecified());
+
+ // Mark it "unspecified". The value should remain the same.
+ value.specify(false);
+ ASSERT_EQ(5, value.get());
+ ASSERT_FALSE(value.isSpecified());
+}
+
+// This test checks that the OptionalValue::specify functions may be used
+// to set the new value and to mark value specified.
+TEST(OptionalValueTest, specifyValue) {
+ OptionalValue<int> value(10);
+ ASSERT_EQ(10, value.get());
+ ASSERT_FALSE(value.isSpecified());
+
+ // Set the new value and mark it "specified".
+ value.specify(123);
+ ASSERT_EQ(123, value.get());
+ ASSERT_TRUE(value.isSpecified());
+
+ // Specify another value. The value should be still "specified".
+ value.specify(1000);
+ ASSERT_EQ(1000, value.get());
+ ASSERT_TRUE(value.isSpecified());
+}
+
+} // end of anonymous namespace