From 50bace13e4befd8e5732bf8c10bb13703faca6fe Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Tue, 12 Jan 2016 02:01:08 +0100 Subject: [PATCH 1/8] Document ElementHandle Signed-off-by: Kevin Rocard --- parameter/include/ElementHandle.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/parameter/include/ElementHandle.h b/parameter/include/ElementHandle.h index 542379409..a52faf0e3 100644 --- a/parameter/include/ElementHandle.h +++ b/parameter/include/ElementHandle.h @@ -45,7 +45,13 @@ class CConfigurableElement; class CBaseParameter; /** @} */ -/** TODO */ +/** ElementHandle gives access to elements of the parameter tree. + * + * ElementHandle objects can be created by calling the + * ParameterMgrPlatformConnector::createElementHandle. + * + * @note non const method can only be called on rogue elements. + */ class PARAMETER_EXPORT ElementHandle { public: From a26f0adcb2bbedf3785e6c43e19f9900d5627277 Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Mon, 11 Jan 2016 21:49:02 +0100 Subject: [PATCH 2/8] convertTo: Allow hexadecimal boolean convertTo now allow 0x0 and 0x1 as input. It was inconsistant with the other types. Do that by converting the string to uint8_t and then testing for 0 or 1. Also do a case insensitive comparison for "true" and "false". Signed-off-by: Kevin Rocard --- utility/convert.hpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/utility/convert.hpp b/utility/convert.hpp index a45c4a718..acbdd618b 100644 --- a/utility/convert.hpp +++ b/utility/convert.hpp @@ -33,8 +33,10 @@ #include #include #include +#include #include #include +#include #include /* details namespace is here to hide implementation details to header end user. It @@ -184,6 +186,8 @@ static inline bool convertToVia(const std::string &str, T &result) * @param[out] result reference to object where to store the result. * * @return true if conversion was successful, false otherwise. + * + * @FIXME: Unit tests were not imported with this conversion library. */ template static inline bool convertTo(const std::string &str, T &result) @@ -302,12 +306,30 @@ inline bool convertTo(const std::string &str, double &result) template <> inline bool convertTo(const std::string &str, bool &result) { - if (str == "0" || str == "FALSE" || str == "false") { + // Try the numerical representation + uint8_t numeric; + if (convertTo(str, numeric)) { + switch (numeric) { + case 0: + result = false; + return true; + case 1: + result = true; + return true; + default: + return false; + } + } + + std::string lower = str; + transform(begin(str), end(str), begin(lower), tolower); + + if (lower == "false") { result = false; return true; } - if (str == "1" || str == "TRUE" || str == "true") { + if (lower == "true") { result = true; return true; } From af6088da72dcfcf8b126c81907959e2da571fb24 Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Mon, 11 Jan 2016 20:09:03 +0100 Subject: [PATCH 3/8] Parse boolean parameters with convertTo Instead of hard coding specific values a boolean can take, use covertTo. This means a lot of values are now taken as boolean (like "true" and "false") and not only {,0x}{0,1}. Signed-off-by: Kevin Rocard --- parameter/BooleanParameterType.cpp | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/parameter/BooleanParameterType.cpp b/parameter/BooleanParameterType.cpp index 66556d304..3e544c2b8 100644 --- a/parameter/BooleanParameterType.cpp +++ b/parameter/BooleanParameterType.cpp @@ -30,6 +30,7 @@ #include "BooleanParameterType.h" #include "ParameterAccessContext.h" #include "Utility.h" +#include "convert.hpp" #define base CParameterType @@ -47,27 +48,14 @@ std::string CBooleanParameterType::getKind() const bool CBooleanParameterType::toBlackboard(const std::string &strValue, uint32_t &uiValue, CParameterAccessContext ¶meterAccessContext) const { - if (strValue == "1" || strValue == "0x1") { - - uiValue = true; - } else if (strValue == "0" || strValue == "0x0") { - - uiValue = false; - } else { - parameterAccessContext.setError(strValue + " value not part of numerical space {"); - - if (utility::isHexadecimal(strValue)) { - - parameterAccessContext.appendToError("0x0, 0x1"); - } else { - - parameterAccessContext.appendToError("0, 1"); - } - parameterAccessContext.appendToError("} for " + getKind()); + bool value; + if (not convertTo(strValue, value)) { + parameterAccessContext.setError(strValue + " value is invalid for " + getKind() + + ", valid values are {0, 1, 0x0, 0x1, true, false}"); return false; } - + uiValue = value; return true; } From bd35c6bec506a343d272fddc59fe987760fa2950 Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Mon, 11 Jan 2016 20:57:43 +0100 Subject: [PATCH 4/8] Test ElementHandle::setAs for booleans It was not tested. Signed-off-by: Kevin Rocard --- parameter/include/ElementHandle.h | 26 +++++++++++++++-- test/functional-tests/Handle.cpp | 29 +++++++++++++++++++ .../include/ElementHandle.hpp | 20 ++++++++++++- test/xml-generator/testVector/complex.pfw | 2 +- 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/parameter/include/ElementHandle.h b/parameter/include/ElementHandle.h index a52faf0e3..cf3e70608 100644 --- a/parameter/include/ElementHandle.h +++ b/parameter/include/ElementHandle.h @@ -177,7 +177,7 @@ class PARAMETER_EXPORT ElementHandle /** Access (get or set) parameters as different types. * - * Will fail if the element is not a paramete. + * Will fail if the element is not a parameter. * Array access will fail if the parameter is not an array. * * @param value if get, the value to get (in parameter) @@ -233,15 +233,35 @@ class PARAMETER_EXPORT ElementHandle /** @} */ protected: + /** Friend to be constructed from CParameterMgr::createElementHandle. */ + friend CParameterMgr; + + /** Protected for test purposes. + * Client must not inherit from this class anyway. + * @{ */ ElementHandle(CConfigurableElement &element, CParameterMgr ¶meterMgr); - friend CParameterMgr; // So that it can build the handler -private: + /** Access a parameter with a template type + * + * Template version of getAsBoolean, getAsInteger, getAsDoubleArray... + * + * @tparam T How to access the parameter. + * Eg: use bool to call setAsBoolean + * use std::vector to call setAsBooleanArray + * + * @note Why are those two methods not public ? + * It could depreciate all the other setAs* and getAs* + * @{ + */ template bool setAs(const T value, std::string &error) const; template bool getAs(T &value, std::string &error) const; + /** @} */ + /** @} */ + +private: template static size_t getSize(T value); template diff --git a/test/functional-tests/Handle.cpp b/test/functional-tests/Handle.cpp index 1c594fdd3..f3a48bf4b 100644 --- a/test/functional-tests/Handle.cpp +++ b/test/functional-tests/Handle.cpp @@ -602,4 +602,33 @@ SCENARIO("Mapping handle access", "[handler][mapping]") } } +SCENARIO_METHOD(AllParamsPF, "Access boolean", "[handler][access]") +{ + ElementHandle handle(*this, "/test/test/bool"); + struct TestVector + { + bool expectedValue; + list values; + }; + list testVectors = { + {true, {"1", "0x1", "001", "0x001", "true", "True", "TRUe"}}, + {false, {"0", "0x0", "000", "0x000", "false", "False", "FaLSe"}}}; + + for (auto testVector : testVectors) { + for (auto value : testVector.values) { + CAPTURE(value); + auto expectedValue = testVector.expectedValue; + CAPTURE(expectedValue); + + CHECK_NOTHROW(handle.setAs(value)); + CHECK(handle.getAs() == std::to_string(expectedValue)); + CHECK(handle.getAs() == expectedValue); + } + } + + for (string invalid : {"2", "-1", "0x10", "None", "faux"}) { + CHECK_THROWS_AS(handle.setAs(invalid), Exception); + } +} + } // namespace parameterFramework diff --git a/test/functional-tests/include/ElementHandle.hpp b/test/functional-tests/include/ElementHandle.hpp index dc48ce908..19f5083d2 100644 --- a/test/functional-tests/include/ElementHandle.hpp +++ b/test/functional-tests/include/ElementHandle.hpp @@ -41,8 +41,12 @@ namespace parameterFramework * Contrary to ::ElementHandle, is constructed through it's constructor * and not a factory method. * @see parameterFramework::ParameterFramework for the main PF interface. + * + * @fixme Should privately inherit from FailureWrapper but this can not be done + * as this class uses protected ::ElementHandle::getAs and setAs methods. + * See their documentation for more information. */ -class ElementHandle : private FailureWrapper<::ElementHandle> +class ElementHandle : protected FailureWrapper<::ElementHandle> { ElementHandle(const ElementHandle &other) = delete; ElementHandle &operator=(const ElementHandle &other) = delete; @@ -71,6 +75,20 @@ class ElementHandle : private FailureWrapper<::ElementHandle> return value; } + /** Wrap EH::setAs* to throw an exception on failure. */ + template + void setAs(T value) + { + mayFailCall(&EH::setAs, value); + } + + /** Wrap EH::getAs* to throw an exception on failure. + * @todo list allowed types. */ + template + T getAs() + { + return mayFailGet(&EH::getAs); + } /** Wrap EH::setAsDouble to throw an exception on failure. */ void setAsDouble(double value) { mayFailCall(&EH::setAsDouble, value); } /** Wrap EH::getAsDouble to throw an exception on failure. */ diff --git a/test/xml-generator/testVector/complex.pfw b/test/xml-generator/testVector/complex.pfw index 042259572..b1bfc6422 100644 --- a/test/xml-generator/testVector/complex.pfw +++ b/test/xml-generator/testVector/complex.pfw @@ -37,4 +37,4 @@ domainGroup: Red sequenceAware q2.5 = 1.18750 string = 12 ab @ \n \0 ✔ "'\ component: included - bool = 1 + bool = true From 49653487b7e1fef6b0acb5a902a28efc88660200 Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Tue, 12 Jan 2016 01:45:15 +0100 Subject: [PATCH 5/8] functional test: update fload tests to use setAs<> The tests were using the setAsDouble version instead of the more generic setAs. Signed-off-by: Kevin Rocard --- test/functional-tests/FloatingPoint.cpp | 6 +++--- test/functional-tests/include/ElementHandle.hpp | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/test/functional-tests/FloatingPoint.cpp b/test/functional-tests/FloatingPoint.cpp index fd41797f1..ec6a68eef 100644 --- a/test/functional-tests/FloatingPoint.cpp +++ b/test/functional-tests/FloatingPoint.cpp @@ -159,9 +159,9 @@ SCENARIO_METHOD(FloatsPF, "Floating points", "[floating points]") {"(inside range)", 0.0f}, }) { GIVEN ("A valid value " + vec.title) { - CHECK_NOTHROW(handle.setAsDouble(vec.payload)); + CHECK_NOTHROW(handle.setAs(vec.payload)); double getValueBack; - REQUIRE_NOTHROW(handle.getAsDouble(getValueBack)); + REQUIRE_NOTHROW(getValueBack = handle.getAs()); CHECK(getValueBack == vec.payload); } } @@ -169,7 +169,7 @@ SCENARIO_METHOD(FloatsPF, "Floating points", "[floating points]") {"(too high)", 12.3f}, {"(too low)", -50.5f}, }) { GIVEN ("An invalid value " + vec.title) { - CHECK_THROWS_AS(handle.setAsDouble(vec.payload), Exception); + CHECK_THROWS_AS(handle.setAs(vec.payload), Exception); } } } diff --git a/test/functional-tests/include/ElementHandle.hpp b/test/functional-tests/include/ElementHandle.hpp index 19f5083d2..aa4981ab5 100644 --- a/test/functional-tests/include/ElementHandle.hpp +++ b/test/functional-tests/include/ElementHandle.hpp @@ -89,10 +89,6 @@ class ElementHandle : protected FailureWrapper<::ElementHandle> { return mayFailGet(&EH::getAs); } - /** Wrap EH::setAsDouble to throw an exception on failure. */ - void setAsDouble(double value) { mayFailCall(&EH::setAsDouble, value); } - /** Wrap EH::getAsDouble to throw an exception on failure. */ - void getAsDouble(double &value) const { mayFailCall(&EH::getAsDouble, value); } std::string getStructureAsXML() const { return mayFailGet(&EH::getStructureAsXML); } From 3403cec8a1898a677e68f48f55f5409c80c1a0fd Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Tue, 12 Jan 2016 02:25:03 +0100 Subject: [PATCH 6/8] Travis: Remove dpkg asio as it is c++11 incompatible Signed-off-by: Kevin Rocard --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 71d95d6e7..09c5451d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,6 @@ addons: - g++-4.8 - cmake - python3-dev - - libasio-dev - clang-format-3.8 install: From bb342cad2cbcbf011f558ce892db86eb62f88ebb Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Tue, 12 Jan 2016 02:06:34 +0100 Subject: [PATCH 7/8] WIP ElementHandle: move setAs to public api Signed-off-by: Kevin Rocard --- parameter/include/ElementHandle.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/parameter/include/ElementHandle.h b/parameter/include/ElementHandle.h index cf3e70608..0990e2f0c 100644 --- a/parameter/include/ElementHandle.h +++ b/parameter/include/ElementHandle.h @@ -232,15 +232,6 @@ class PARAMETER_EXPORT ElementHandle /** @} */ -protected: - /** Friend to be constructed from CParameterMgr::createElementHandle. */ - friend CParameterMgr; - - /** Protected for test purposes. - * Client must not inherit from this class anyway. - * @{ */ - ElementHandle(CConfigurableElement &element, CParameterMgr ¶meterMgr); - /** Access a parameter with a template type * * Template version of getAsBoolean, getAsInteger, getAsDoubleArray... @@ -259,7 +250,14 @@ class PARAMETER_EXPORT ElementHandle bool getAs(T &value, std::string &error) const; /** @} */ - /** @} */ +protected: + /** Friend to be constructed from CParameterMgr::createElementHandle. */ + friend CParameterMgr; + + /** Protected for test purposes. + * Client must not inherit from this class anyway. + */ + ElementHandle(CConfigurableElement &element, CParameterMgr ¶meterMgr); private: template From bd767ad896e872b1e3126fe30c2641fd3629699a Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Tue, 12 Jan 2016 02:22:47 +0100 Subject: [PATCH 8/8] POC explict template instanciation Signed-off-by: Kevin Rocard --- parameter/ElementHandle.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/parameter/ElementHandle.cpp b/parameter/ElementHandle.cpp index ac9376526..553526a96 100644 --- a/parameter/ElementHandle.cpp +++ b/parameter/ElementHandle.cpp @@ -218,6 +218,10 @@ bool ElementHandle::setAs(const T value, string &error) const return parameter.access(copy, true, parameterAccessContext); } +template PARAMETER_EXPORT bool ElementHandle::setAs(bool, string &) const; +template PARAMETER_EXPORT bool ElementHandle::setAs(string, string &) const; +template PARAMETER_EXPORT bool ElementHandle::setAs(double, string &) const; + template bool ElementHandle::getAs(T &value, string &error) const { @@ -235,6 +239,10 @@ bool ElementHandle::getAs(T &value, string &error) const return parameter.access(value, false, parameterAccessContext); } +template PARAMETER_EXPORT bool ElementHandle::getAs(bool &, string &) const; +template PARAMETER_EXPORT bool ElementHandle::getAs(string &, string &) const; +template PARAMETER_EXPORT bool ElementHandle::getAs(double &, string &) const; + // Boolean access bool ElementHandle::setAsBoolean(bool bValue, string &error) {