Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed by
Diff: rpc.h
- Revision:
- 5:62573be585e9
- Parent:
- 4:5d1359a283bc
- Child:
- 6:3fd6a337c7cc
--- a/rpc.h Thu Nov 27 16:23:24 2008 +0000
+++ b/rpc.h Thu Jan 22 18:32:40 2009 +0000
@@ -75,9 +75,13 @@
/* floating types */
template<> inline float parse_arg<float>(const char *arg, const char **next) {
-#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 310000
+#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 410000
return strtof(arg,const_cast<char**>(next));
+#elif __ARMCC_VERSION >= 310000
+ /* bug in header means no using declaration for strtof */
+ return std::strtof(arg,const_cast<char**>(next));
#else
+ /* strtof not supported */
return strtod(arg,const_cast<char**>(next));
#endif
}
@@ -90,6 +94,32 @@
return strtod(arg,const_cast<char**>(next));
}
+/* string */
+
+template<> inline char *parse_arg<char*>(const char *arg, const char **next) {
+ const char *ptr = arg;
+ while(*ptr != 0 && *ptr != ' ' && *ptr != ',') {
+ ptr++;
+ }
+ int len = ptr-arg;
+ char *p;
+ if(len==0) {
+ p = NULL;
+ } else {
+ p = new char[len+1];
+ memcpy(p, arg, len);
+ p[len] = 0;
+ }
+ if(next != NULL) {
+ *next = ptr;
+ }
+ return p;
+}
+
+template<> inline const char *parse_arg<const char*>(const char *arg, const char **next) {
+ return parse_arg<char*>(arg,next);
+}
+
/* Function write_result
* Writes a value in to a result string in an appropriate manner
@@ -161,10 +191,35 @@
}
-/* Function generic_caller
+/* string */
+
+template<> inline void write_result<char*>(char *val, char *result) {
+ strcpy(result, val);
+}
+
+template<> inline void write_result<const char*>(const char *val, char *result) {
+ strcpy(result, val);
+}
+
+
+inline const char *next_arg(const char* next) {
+ if(*next == ',' || *next == ' ') next++;
+ return next;
+}
+
+
+/* Function rpc_method_caller
+ */
+template<class T, void (T::*member)(const char *,char *)>
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
+ (static_cast<T*>(this_ptr)->*member)(arguments,result);
+}
+
+
+/* Function rpc_method_caller
*/
template<class T, void (T::*member)()>
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
(static_cast<T*>(this_ptr)->*member)();
if(result != NULL) {
result[0] = '\0';
@@ -172,14 +227,13 @@
}
-/* Function generic_caller
+/* Function rpc_method_caller
*/
template<class T, typename A1, void (T::*member)(A1)>
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
- const char *next = arguments;
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
- if(*next == ',' || *next == ' ') next++;
- A1 arg1 = parse_arg<A1>(next,NULL);
+ const char *next = arguments;
+ A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
(static_cast<T*>(this_ptr)->*member)(arg1);
if(result != NULL) {
@@ -188,17 +242,14 @@
}
-/* Function generic_caller
+/* Function rpc_method_caller
*/
template<class T, typename A1, typename A2, void (T::*member)(A1,A2)>
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
- const char *next = arguments;
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
- if(*next == ',' || *next == ' ') next++;
- A1 arg1 = parse_arg<A1>(next,&next);
-
- if(*next == ',' || *next == ' ') next++;
- A2 arg2 = parse_arg<A2>(next,NULL);
+ const char *next = arguments;
+ A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+ A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
(static_cast<T*>(this_ptr)->*member)(arg1,arg2);
if(result != NULL) {
@@ -207,10 +258,10 @@
}
-/* Function generic_caller
+/* Function rpc_method_caller
*/
template<typename R, class T, R (T::*member)()>
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
R res = (static_cast<T*>(this_ptr)->*member)();
if(result != NULL) {
write_result<R>(res, result);
@@ -218,14 +269,13 @@
}
-/* Function generic_caller
+/* Function rpc_method_caller
*/
template<typename R, class T, typename A1, R (T::*member)(A1)>
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
- const char *next = arguments;
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
- if(*next == ',' || *next == ' ') next++;
- A1 arg1 = parse_arg<A1>(next,NULL);
+ const char *next = arguments;
+ A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
R res = (static_cast<T*>(this_ptr)->*member)(arg1);
if(result != NULL) {
@@ -234,17 +284,14 @@
}
-/* Function generic_caller
+/* Function rpc_method_caller
*/
template<typename R, class T, typename A1, typename A2, R (T::*member)(A1,A2)>
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
- const char *next = arguments;
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
- if(*next == ',' || *next == ' ') next++;
- A1 arg1 = parse_arg<A1>(next,&next);
-
- if(*next == ',' || *next == ' ') next++;
- A2 arg2 = parse_arg<A2>(next,NULL);
+ const char *next = arguments;
+ A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+ A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2);
if(result != NULL) {
@@ -252,13 +299,115 @@
}
}
+
+/* Function rpc_method_caller
+ */
+template<typename R, class T, typename A1, typename A2, typename A3, R (T::*member)(A1,A2,A3)>
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
+
+ const char *next = arguments;
+ A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+ A2 arg2 = parse_arg<A2>(next_arg(next),&next);
+ A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
+
+ R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2,arg3);
+ if(result != NULL) {
+ write_result<R>(res, result);
+ }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, R (*func)()>
+void rpc_function_caller(const char *arguments, char *result) {
+ R res = (*func)();
+ if(result != NULL) {
+ write_result<R>(res, result);
+ }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, typename A1, R (*func)(A1)>
+void rpc_function_caller(const char *arguments, char *result) {
+ A1 arg1 = parse_arg<A1>(next_arg(arguments),NULL);
+ R res = (*func)(arg1);
+ if(result != NULL) {
+ write_result<R>(res, result);
+ }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, typename A1, typename A2, R (*func)(A1,A2)>
+void rpc_function_caller(const char *arguments, char *result) {
+
+ const char *next = arguments;
+ A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+ A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
+
+ R res = (*func)(arg1,arg2);
+ if(result != NULL) {
+ write_result<R>(res, result);
+ }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, typename A1, typename A2, typename A3, R (*func)(A1,A2,A3)>
+void rpc_function_caller(const char *arguments, char *result) {
+
+ const char *next = arguments;
+ A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+ A2 arg2 = parse_arg<A2>(next_arg(next),&next);
+ A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
+
+ R res = (*func)(arg1,arg2,arg3);
+ if(result != NULL) {
+ write_result<R>(res, result);
+ }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, typename A1, typename A2, typename A3, typename A4, R (*func)(A1,A2,A3,A4)>
+void rpc_function_caller(const char *arguments, char *result) {
+
+ const char *next = arguments;
+ A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+ A2 arg2 = parse_arg<A2>(next_arg(next),&next);
+ A3 arg3 = parse_arg<A3>(next_arg(next),&next);
+ A4 arg4 = parse_arg<A4>(next_arg(next),NULL);
+
+ R res = (*func)(arg1,arg2,arg3,arg4);
+ if(result != NULL) {
+ write_result<R>(res, result);
+ }
+}
+
+
struct rpc_method {
const char *name;
- void (*caller)(Base*, const char*, char*);
+ typedef void (*caller_t)(Base*, const char*, char*);
+ typedef const struct rpc_method *(*super_t)(Base*);
+ union {
+ caller_t caller;
+ super_t super;
+ };
};
-
+
+template<class C>
+const struct rpc_method *rpc_super(Base *this_ptr) {
+ return static_cast<C*>(this_ptr)->C::get_rpc_methods();
+}
+
#define RPC_METHOD_END { NULL, NULL }
-
+#define RPC_METHOD_SUPER(C) { NULL, (rpc_method::caller_t)(rpc_method::super_t)rpc_super<C> }
/* Function rpc
* Parse a string describing a call and then do it
@@ -272,6 +421,7 @@
*/
bool rpc(const char *buf, char *result = 0);
+
} /* namespace mbed */
#endif
