From: Marcin Siodelski Date: Mon, 13 Oct 2014 16:38:08 +0000 (+0200) Subject: [3367] Moved OptionalValue class to the util library. X-Git-Tag: trac3162a_base~8^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a3ee7a211b8f5929a256a835b49e7a14908428d1;p=thirdparty%2Fkea.git [3367] Moved OptionalValue class to the util library. --- diff --git a/src/bin/dhcp4/tests/dhcp4_client.h b/src/bin/dhcp4/tests/dhcp4_client.h index 0be7b662d1..724014e87c 100644 --- a/src/bin/dhcp4/tests/dhcp4_client.h +++ b/src/bin/dhcp4/tests/dhcp4_client.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -34,74 +35,6 @@ public: 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 -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 @@ -367,7 +300,7 @@ public: /// 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 ciaddr_; + isc::util::OptionalValue ciaddr_; private: diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am index 09f28662b4..f2d6a69596 100644 --- a/src/lib/util/Makefile.am +++ b/src/lib/util/Makefile.am @@ -30,6 +30,7 @@ libkea_util_la_SOURCES += memory_segment_local.h memory_segment_local.cc 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 diff --git a/src/lib/util/optional_value.h b/src/lib/util/optional_value.h new file mode 100644 index 0000000000..3b964f4b94 --- /dev/null +++ b/src/lib/util/optional_value.h @@ -0,0 +1,102 @@ +// 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 +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 diff --git a/src/lib/util/tests/Makefile.am b/src/lib/util/tests/Makefile.am index 2a9aaead30..91722be1ba 100644 --- a/src/lib/util/tests/Makefile.am +++ b/src/lib/util/tests/Makefile.am @@ -40,6 +40,7 @@ run_unittests_SOURCES += memory_segment_mapped_unittest.cc 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 diff --git a/src/lib/util/tests/optional_value_unittest.cc b/src/lib/util/tests/optional_value_unittest.cc new file mode 100644 index 0000000000..a5f7438085 --- /dev/null +++ b/src/lib/util/tests/optional_value_unittest.cc @@ -0,0 +1,83 @@ +// 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 +#include +#include + +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 value1(10); + EXPECT_EQ(10, value1.get()); + EXPECT_FALSE(value1.isSpecified()); + + // Use the non-default value for second parameter. + OptionalValue 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 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 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