Skip to content

Commit 70d4692

Browse files
committed
feat: type check on bound function parameters solves #18
1 parent fc42ad8 commit 70d4692

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

src/rpclite_utils.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
namespace RpcUtils {
2020
namespace detail {
2121

22+
#define TYPE_ERROR (-1)
2223
#define WRONG_MSG (-2)
2324
#define NO_MSG (-1)
2425
#define CALL_MSG 0
@@ -165,10 +166,10 @@ inline bool unpackObject(MsgPack::Unpacker& unpacker){
165166
}
166167

167168
template<typename T>
168-
inline bool deserialize_single(MsgPack::Unpacker& unpacker, T& value) {
169-
if (!unpacker.unpackable(value)) return false;
169+
int deserialize_single(MsgPack::Unpacker& unpacker, T& value) {
170+
if (!unpacker.unpackable(value)) return TYPE_ERROR;
170171
unpacker.deserialize(value);
171-
return true;
172+
return 0;
172173
}
173174

174175

@@ -177,21 +178,22 @@ inline bool deserialize_single(MsgPack::Unpacker& unpacker, T& value) {
177178
/////////////////////////////
178179

179180
template<std::size_t I = 0, typename... Ts>
180-
inline typename std::enable_if<I == sizeof...(Ts), bool>::type
181+
typename std::enable_if<I == sizeof...(Ts), int>::type
181182
deserialize_tuple(MsgPack::Unpacker&, std::tuple<Ts...>&) {
182-
return true;
183+
return 0;
183184
}
184185

185186
template<std::size_t I = 0, typename... Ts>
186-
inline typename std::enable_if<I < sizeof...(Ts), bool>::type
187+
typename std::enable_if<I < sizeof...(Ts), int>::type
187188
deserialize_tuple(MsgPack::Unpacker& unpacker, std::tuple<Ts...>& out) {
188-
if (!deserialize_single(unpacker, std::get<I>(out))) return false;
189+
const int res = deserialize_single(unpacker, std::get<I>(out));
190+
if (res==TYPE_ERROR) return TYPE_ERROR-I;
189191
return deserialize_tuple<I + 1>(unpacker, out);
190192
}
191193

192194
// Helper to invoke a function with a tuple of arguments
193195
template<typename F, typename Tuple, std::size_t... I>
194-
inline auto invoke_with_tuple(F&& f, Tuple&& t, arx::stdx::index_sequence<I...>)
196+
auto invoke_with_tuple(F&& f, Tuple&& t, arx::stdx::index_sequence<I...>)
195197
-> decltype(f(std::get<I>(std::forward<Tuple>(t))...)) {
196198
return f(std::get<I>(std::forward<Tuple>(t))...);
197199
}

src/wrapper.h

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#ifndef RPCLITE_WRAPPER_H
1313
#define RPCLITE_WRAPPER_H
1414

15+
#include <string>
16+
1517
#include "error.h"
1618
#include "rpclite_utils.h"
1719

@@ -69,7 +71,20 @@ class RpcFunctionWrapper<std::function<R(Args...)>>: public IFunctionWrapper {
6971
return false;
7072
}
7173

72-
return handle_call(unpacker, packer);
74+
const int res = handle_call(unpacker, packer);
75+
if (res<0) {
76+
MsgPack::str_t err_msg = "Wrong type parameter in position: ";
77+
#ifdef ARDUINO
78+
err_msg += String(TYPE_ERROR-res);
79+
#else
80+
err_msg += std::to_string(TYPE_ERROR-res);
81+
#endif
82+
RpcError error(MALFORMED_CALL_ERR, err_msg);
83+
packer.serialize(error, nil);
84+
return false;
85+
}
86+
87+
return true;
7388

7489
#ifdef HANDLE_RPC_ERRORS
7590
} catch (const std::exception& e) {
@@ -86,27 +101,29 @@ class RpcFunctionWrapper<std::function<R(Args...)>>: public IFunctionWrapper {
86101
std::function<R(Args...)> _func;
87102

88103
template<typename Dummy = R>
89-
typename std::enable_if<std::is_void<Dummy>::value, bool>::type
104+
typename std::enable_if<std::is_void<Dummy>::value, int>::type
90105
handle_call(MsgPack::Unpacker& unpacker, MsgPack::Packer& packer) {
91106
//unpacker not ready if deserialization fails at this point
92107
std::tuple<Args...> args;
93-
if (!deserialize_tuple(unpacker, args)) return false;
108+
const int res = deserialize_tuple(unpacker, args);
109+
if (res<0) return res;
94110
MsgPack::object::nil_t nil;
95111
invoke_with_tuple(_func, args, arx::stdx::make_index_sequence<sizeof...(Args)>{});
96112
packer.serialize(nil, nil);
97-
return true;
113+
return 0;
98114
}
99115

100116
template<typename Dummy = R>
101-
typename std::enable_if<!std::is_void<Dummy>::value, bool>::type
117+
typename std::enable_if<!std::is_void<Dummy>::value, int>::type
102118
handle_call(MsgPack::Unpacker& unpacker, MsgPack::Packer& packer) {
103119
//unpacker not ready if deserialization fails at this point
104120
std::tuple<Args...> args;
105-
if (!deserialize_tuple(unpacker, args)) return false;
121+
const int res = deserialize_tuple(unpacker, args);
122+
if (res<0) return res;
106123
MsgPack::object::nil_t nil;
107124
R out = invoke_with_tuple(_func, args, arx::stdx::make_index_sequence<sizeof...(Args)>{});
108125
packer.serialize(nil, out);
109-
return true;
126+
return 0;
110127
}
111128
};
112129

0 commit comments

Comments
 (0)