Commit a3ee7a21 authored by Marcin Siodelski's avatar Marcin Siodelski

[3367] Moved OptionalValue class to the util library.

parent ca6c71ff
......@@ -19,6 +19,7 @@
#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>
......@@ -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<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
......@@ -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<asiolink::IOAddress> ciaddr_;
isc::util::OptionalValue<asiolink::IOAddress> ciaddr_;
private:
......
......@@ -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
......
// 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
......@@ -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
......
// 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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment