From 058fa930d0a25022c47ca673d24f302e5031cb6f Mon Sep 17 00:00:00 2001 From: Marcin Siodelski Date: Mon, 25 Mar 2019 16:59:19 +0100 Subject: [PATCH] [#490,!284] Created ElementExtractor template. --- src/lib/cc/Makefile.am | 2 + src/lib/cc/element_extractor.h | 100 ++++++++++++++++++ src/lib/cc/tests/Makefile.am | 1 + .../cc/tests/element_extractor_unittests.cc | 43 ++++++++ 4 files changed, 146 insertions(+) create mode 100644 src/lib/cc/element_extractor.h create mode 100644 src/lib/cc/tests/element_extractor_unittests.cc diff --git a/src/lib/cc/Makefile.am b/src/lib/cc/Makefile.am index e5bddc69ef..3f98f79adf 100644 --- a/src/lib/cc/Makefile.am +++ b/src/lib/cc/Makefile.am @@ -6,6 +6,7 @@ AM_CXXFLAGS = $(KEA_CXXFLAGS) lib_LTLIBRARIES = libkea-cc.la libkea_cc_la_SOURCES = data.cc data.h +libkea_cc_la_SOURCES += element_extractor.h libkea_cc_la_SOURCES += cfg_to_element.h dhcp_config_error.h libkea_cc_la_SOURCES += command_interpreter.cc command_interpreter.h libkea_cc_la_SOURCES += json_feed.cc json_feed.h @@ -28,6 +29,7 @@ libkea_cc_include_HEADERS = \ command_interpreter.h \ data.h \ dhcp_config_error.h \ + element_extractor.h \ json_feed.h \ simple_parser.h \ stamped_element.h \ diff --git a/src/lib/cc/element_extractor.h b/src/lib/cc/element_extractor.h new file mode 100644 index 0000000000..ac8158ff1f --- /dev/null +++ b/src/lib/cc/element_extractor.h @@ -0,0 +1,100 @@ +// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef ELEMENT_EXTRACTOR_H +#define ELEMENT_EXTRACTOR_H + +#include +#include + +namespace isc { +namespace data { + +/// @brief Template class for converting a value encapsulated in the +/// @c Element object into a simple type. +/// +/// The @c Element object provides a set of accessors to retrieve +/// values of different types it encapsulates. These methods +/// however can't be always used in template methods and classes. +/// +/// Consider a template function which returns a value of a type +/// specified as template argument. In order to convert a value +/// held in the @c Element object it would have to conditionally +/// call this object's accessors to return the value of the +/// appropriate type. This would however fail to compile because +/// the compiler would check for all possible value types returned +/// by the @c Element accessors and report an error for those that +/// don't cast to the returned type. +/// +/// This class provides a mechanism to extract the value of the +/// appropriate type from the @c Element object within the +/// template function. It comes with a number of class specializations +/// for various data types to be returned. The default implementation +/// calls @c Element::intValue and casts it to the returned type. +/// There are class specializations for @c double, @c bool and +/// @c string. +/// +/// @tparam T Type of the value to be extracted. +template +class ElementExtractor { +public: + + /// @brief Function operator extracting an @c Element value as + /// integer. + /// + /// @param el Element holding a value to be extracted. + T operator()(ConstElementPtr el) const { + return (static_cast(el->intValue())); + } +}; + +/// @brief The @c ElementExtractor specialization for double. +template<> +class ElementExtractor { +public: + + /// @brief Function operator extracting an @c Element value as + /// double. + /// + /// @param el Element holding a value to be extracted. + double operator()(ConstElementPtr el) const { + return (el->doubleValue()); + } +}; + +/// @brief The @c ElementExtractor specialization for boolean. +template<> +class ElementExtractor { +public: + + /// @brief Function operator extracting an @c Element value as + /// boolean. + /// + /// @param el Element holding a value to be extracted. + bool operator()(ConstElementPtr el) const { + return (el->boolValue()); + } + +}; + +/// @brief The @c ElementExtractor specialization for string. +template<> +class ElementExtractor { +public: + + /// @brief Function operator extracting an @c Element value as + /// string. + /// + /// @param el Element holding a value to be extracted. + std::string operator()(ConstElementPtr el) const { + return (el->stringValue()); + } +}; + +} // end of namespace isc::data +} // end of namespace isc + +#endif // ELEMENT_EXTRACTOR_H diff --git a/src/lib/cc/tests/Makefile.am b/src/lib/cc/tests/Makefile.am index 74da3b067a..2682c5a15d 100644 --- a/src/lib/cc/tests/Makefile.am +++ b/src/lib/cc/tests/Makefile.am @@ -17,6 +17,7 @@ TESTS += run_unittests run_unittests_SOURCES = command_interpreter_unittests.cc run_unittests_SOURCES += data_unittests.cc run_unittests_SOURCES += data_file_unittests.cc +run_unittests_SOURCES += element_extractor_unittests.cc run_unittests_SOURCES += json_feed_unittests.cc run_unittests_SOURCES += simple_parser_unittest.cc run_unittests_SOURCES += stamped_element_unittest.cc diff --git a/src/lib/cc/tests/element_extractor_unittests.cc b/src/lib/cc/tests/element_extractor_unittests.cc new file mode 100644 index 0000000000..da327a41c4 --- /dev/null +++ b/src/lib/cc/tests/element_extractor_unittests.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include + +using namespace isc::data; + +namespace { + +// This test verifies that integer value can be extracted. +TEST(ElementExtractor, intValue) { + EXPECT_EQ(5, ElementExtractor()(Element::create(5))); + EXPECT_THROW(ElementExtractor()(Element::create("hola!")), + TypeError); +} + +// This test verifies that double value can be extracted. +TEST(ElementExtractor, doubleValue) { + EXPECT_EQ(1.4, ElementExtractor()(Element::create(1.4))); + EXPECT_THROW(ElementExtractor()(Element::create("hola!")), + TypeError); +} + +// This test verifies that boolean value can be extracted. +TEST(ElementExtractor, boolValue) { + EXPECT_TRUE(ElementExtractor()(Element::create(true))); + EXPECT_THROW(ElementExtractor()(Element::create("hola!")), + TypeError); +} + +// This test verifies that string value can be extracted. +TEST(ElementExtractor, stringValue) { + EXPECT_EQ("hola!", ElementExtractor()(Element::create("hola!"))); + EXPECT_THROW(ElementExtractor()(Element::create(false)), + TypeError); +} + +} -- 2.47.2