Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.

[WIP] Allow setting boolean parameter with "true" and "false" #332

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ addons:
- g++-4.8
- cmake
- python3-dev
- libasio-dev
- clang-format-3.8

install:
Expand Down
24 changes: 6 additions & 18 deletions parameter/BooleanParameterType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "BooleanParameterType.h"
#include "ParameterAccessContext.h"
#include "Utility.h"
#include "convert.hpp"

#define base CParameterType

Expand All @@ -47,27 +48,14 @@ std::string CBooleanParameterType::getKind() const
bool CBooleanParameterType::toBlackboard(const std::string &strValue, uint32_t &uiValue,
CParameterAccessContext &parameterAccessContext) 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;
}

Expand Down
8 changes: 8 additions & 0 deletions parameter/ElementHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class T>
bool ElementHandle::getAs(T &value, string &error) const
{
Expand All @@ -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)
{
Expand Down
38 changes: 31 additions & 7 deletions parameter/include/ElementHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -171,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)
Expand Down Expand Up @@ -226,16 +232,34 @@ class PARAMETER_EXPORT ElementHandle

/** @} */

protected:
ElementHandle(CConfigurableElement &element, CParameterMgr &parameterMgr);
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<bool> to call setAsBooleanArray
*
* @note Why are those two methods not public ?
* It could depreciate all the other setAs* and getAs*
* @{
*/
template <class T>
bool setAs(const T value, std::string &error) const;
template <class T>
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 &parameterMgr);

private:
template <class T>
static size_t getSize(T value);
template <class T>
Expand Down
6 changes: 3 additions & 3 deletions test/functional-tests/FloatingPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,17 @@ 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<double>(vec.payload));
double getValueBack;
REQUIRE_NOTHROW(handle.getAsDouble(getValueBack));
REQUIRE_NOTHROW(getValueBack = handle.getAs<double>());
CHECK(getValueBack == vec.payload);
}
}
for (auto &vec : Tests<float>{
{"(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<double>(vec.payload), Exception);
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions test/functional-tests/Handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> values;
};
list<TestVector> 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<decltype(value)>() == std::to_string(expectedValue));
CHECK(handle.getAs<decltype(expectedValue)>() == expectedValue);
}
}

for (string invalid : {"2", "-1", "0x10", "None", "faux"}) {
CHECK_THROWS_AS(handle.setAs(invalid), Exception);
}
}

} // namespace parameterFramework
24 changes: 19 additions & 5 deletions test/functional-tests/include/ElementHandle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -71,10 +75,20 @@ class ElementHandle : private FailureWrapper<::ElementHandle>
return value;
}

/** 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); }
/** Wrap EH::setAs* to throw an exception on failure. */
template <class T>
void setAs(T value)
{
mayFailCall(&EH::setAs<T>, value);
}

/** Wrap EH::getAs* to throw an exception on failure.
* @todo list allowed types. */
template <class T>
T getAs()
{
return mayFailGet(&EH::getAs<T>);
}

std::string getStructureAsXML() const { return mayFailGet(&EH::getStructureAsXML); }

Expand Down
2 changes: 1 addition & 1 deletion test/xml-generator/testVector/complex.pfw
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ domainGroup: Red sequenceAware
q2.5 = 1.18750
string = 12 ab @ <![CDATA[ < > \n \0 ✔ "'\
component: included
bool = 1
bool = true
26 changes: 24 additions & 2 deletions utility/convert.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@
#include <limits>
#include <sstream>
#include <string>
#include <algorithm>
#include <stdint.h>
#include <cmath>
#include <cctype>
#include <type_traits>

/* details namespace is here to hide implementation details to header end user. It
Expand Down Expand Up @@ -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 <typename T>
static inline bool convertTo(const std::string &str, T &result)
Expand Down Expand Up @@ -302,12 +306,30 @@ inline bool convertTo<double>(const std::string &str, double &result)
template <>
inline bool convertTo<bool>(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;
}
Expand Down