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

Commit 469d9a0

Browse files
committed
Fix ElementHandle::setAs.*Array methods
Direct accesses to array parameters were incorrectly identified, resulting in an error when the client tried to set them. This was caused by a programming mistake in using overloaded methods because `T`, `const T`, `T &` and `const T&` are different. This is fixed by using the SFINAE principle and correctly handing all the cases described above. Signed-off-by: David Wagner <[email protected]>
1 parent f3ec327 commit 469d9a0

File tree

4 files changed

+95
-27
lines changed

4 files changed

+95
-27
lines changed

parameter/ElementHandle.cpp

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,36 @@ using std::string;
4141
using std::mutex;
4242
using std::lock_guard;
4343

44+
template <class T>
45+
struct isVector : std::false_type
46+
{
47+
};
48+
49+
template <class T>
50+
struct isVector<std::vector<T>> : std::true_type
51+
{
52+
};
53+
54+
template <class T>
55+
struct remove_ref_cv
56+
{
57+
using type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
58+
};
59+
60+
template <class T>
61+
static typename std::enable_if<not isVector<typename remove_ref_cv<T>::type>::value,
62+
size_t>::type getUserInputSize(T /*values*/)
63+
{
64+
return 0;
65+
}
66+
67+
template <class T>
68+
static typename std::enable_if<isVector<typename remove_ref_cv<T>::type>::value, size_t>::type
69+
getUserInputSize(T values)
70+
{
71+
return values.size();
72+
}
73+
4474
ElementHandle::ElementHandle(CConfigurableElement &element, CParameterMgr &parameterMgr)
4575
: mElement(element), mParameterMgr(parameterMgr)
4676
{
@@ -137,27 +167,6 @@ bool ElementHandle::getStructureAsXML(std::string &xmlSettings, std::string &err
137167
CXmlParameterSerializingContext{accessContext, error}, xmlSettings);
138168
}
139169

140-
template <class T>
141-
struct isVector : std::false_type
142-
{
143-
};
144-
template <class T>
145-
struct isVector<std::vector<T>> : std::true_type
146-
{
147-
};
148-
149-
template <class T>
150-
size_t ElementHandle::getSize(T /*value*/)
151-
{
152-
return 0;
153-
}
154-
155-
template <class T>
156-
size_t ElementHandle::getSize(std::vector<T> &values)
157-
{
158-
return values.size();
159-
}
160-
161170
bool ElementHandle::getAsXML(std::string &xmlValue, std::string &error) const
162171
{
163172
std::string result;
@@ -194,7 +203,7 @@ bool ElementHandle::setAsBytes(const std::vector<uint8_t> &bytesValue, std::stri
194203
template <class T>
195204
bool ElementHandle::setAs(const T value, string &error) const
196205
{
197-
if (not checkSetValidity(getSize(value), error)) {
206+
if (not checkSetValidity(getUserInputSize(value), error)) {
198207
return false;
199208
}
200209
// Safe downcast thanks to isParameter check in checkSetValidity

parameter/include/ElementHandle.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,6 @@ class PARAMETER_EXPORT ElementHandle
234234
template <class T>
235235
bool getAs(T &value, std::string &error) const;
236236

237-
template <class T>
238-
static size_t getSize(T value);
239-
template <class T>
240-
static size_t getSize(std::vector<T> &values);
241-
242237
CBaseParameter &getParameter();
243238
const CBaseParameter &getParameter() const;
244239

test/functional-tests/Handle.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,4 +602,46 @@ SCENARIO("Mapping handle access", "[handler][mapping]")
602602
}
603603
}
604604

605+
SCENARIO_METHOD(SettingsTestPF, "Handle Get/Set as various kinds", "[handler][dynamic]")
606+
{
607+
ElementHandle intScalar(*this, "/test/test/parameter_block/integer");
608+
WHEN ("Setting a scalar integer") {
609+
WHEN ("As an array") {
610+
THEN ("It should fail") {
611+
CHECK_THROWS(intScalar.setAsIntegerArray({0, 0}));
612+
}
613+
}
614+
WHEN ("As a scalalar") {
615+
THEN ("It should succeed") {
616+
uint32_t expected = 111;
617+
CHECK_NOTHROW(intScalar.setAsInteger(expected));
618+
AND_THEN ("Getting it back should give the same value") {
619+
uint32_t back = 42;
620+
CHECK_NOTHROW(intScalar.getAsInteger(back));
621+
CHECK(back == expected);
622+
}
623+
}
624+
}
625+
}
626+
627+
ElementHandle intArray(*this, "/test/test/parameter_block/integer_array");
628+
WHEN ("Setting a array integer") {
629+
WHEN ("As a scalar") {
630+
THEN ("It should fail") {
631+
CHECK_THROWS(intArray.setAsSignedInteger(0));
632+
}
633+
}
634+
WHEN ("As a integer") {
635+
THEN ("It should succeed") {
636+
const std::vector<int32_t> expected = {-9, 8, -7, 6};
637+
CHECK_NOTHROW(intArray.setAsSignedIntegerArray(expected));
638+
AND_THEN ("Getting it back should give the same value") {
639+
std::vector<int32_t> back = {-42, 42, 43, -43};
640+
CHECK_NOTHROW(intArray.getAsSignedIntegerArray(back));
641+
CHECK(back == expected);
642+
}
643+
}
644+
}
645+
}
646+
}
605647
} // namespace parameterFramework

test/functional-tests/include/ElementHandle.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,28 @@ class ElementHandle : private FailureWrapper<::ElementHandle>
7676
/** Wrap EH::getAsDouble to throw an exception on failure. */
7777
void getAsDouble(double &value) const { mayFailCall(&EH::getAsDouble, value); }
7878

79+
void setAsInteger(uint32_t value) { mayFailCall(&EH::setAsInteger, value); }
80+
void getAsInteger(uint32_t &value) const { mayFailCall(&EH::getAsInteger, value); }
81+
void setAsIntegerArray(const std::vector<uint32_t> &value)
82+
{
83+
mayFailCall(&EH::setAsIntegerArray, value);
84+
}
85+
void getAsIntegerArray(std::vector<uint32_t> &value) const
86+
{
87+
mayFailCall(&EH::getAsIntegerArray, value);
88+
}
89+
90+
void setAsSignedInteger(int32_t value) { mayFailCall(&EH::setAsSignedInteger, value); }
91+
void getAsSignedInteger(int32_t &value) const { mayFailCall(&EH::getAsSignedInteger, value); }
92+
void setAsSignedIntegerArray(const std::vector<int32_t> &value)
93+
{
94+
mayFailCall(&EH::setAsSignedIntegerArray, value);
95+
}
96+
void getAsSignedIntegerArray(std::vector<int32_t> &value) const
97+
{
98+
mayFailCall(&EH::getAsSignedIntegerArray, value);
99+
}
100+
79101
std::string getStructureAsXML() const { return mayFailGet(&EH::getStructureAsXML); }
80102

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

0 commit comments

Comments
 (0)