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
rpc.h
- Committer:
- simon.ford@mbed.co.uk
- Date:
- 2009-01-22
- Revision:
- 5:62573be585e9
- Parent:
- 4:5d1359a283bc
- Child:
- 6:3fd6a337c7cc
File content as of revision 5:62573be585e9:
/* mbed Microcontroller Library
* Copyright (c) 2008 ARM Limited. All rights reserved.
*/
#ifndef MBED_RPC_H
#define MBED_RPC_H
/* Section rpc
* Helpers for rpc handling.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Base.h"
namespace mbed {
/* Function parse_arg
* Parses and returns a value from a string.
*
* Variable
* arg - The string to pase
* next - If not NULL a pointer to after the last
* character parsed is written here
*/
template<typename T> T parse_arg(const char *arg, const char **next);
/* signed integer types */
template<> inline char parse_arg<char>(const char *arg, const char **next) {
if(next != NULL) *next = arg+1;
return *arg;
}
template<> inline short int parse_arg<short int>(const char *arg, const char **next) {
return strtol(arg, const_cast<char**>(next), 10);
}
template<> inline long int parse_arg<long int>(const char *arg, const char **next) {
return strtol(arg, const_cast<char**>(next), 10);
}
template<> inline int parse_arg<int>(const char *arg, const char **next) {
return strtol(arg, const_cast<char**>(next), 10);
}
template<> inline long long parse_arg<long long>(const char *arg, const char **next) {
return strtoll(arg, const_cast<char**>(next), 10);
}
/* unsigned integer types */
template<> inline unsigned char parse_arg<unsigned char>(const char *arg, const char **next) {
if(next != NULL) *next = arg+1;
return *arg;
}
template<> inline unsigned short int parse_arg<unsigned short int>(const char *arg, const char **next) {
return strtoul(arg, const_cast<char**>(next), 10);
}
template<> inline unsigned long int parse_arg<unsigned long int>(const char *arg, const char **next) {
return strtoul(arg, const_cast<char**>(next), 10);
}
template<> inline unsigned int parse_arg<unsigned int>(const char *arg, const char **next) {
return strtoul(arg, const_cast<char**>(next), 10);
}
template<> inline unsigned long long parse_arg<unsigned long long>(const char *arg, const char **next) {
return strtoull(arg, const_cast<char**>(next), 10);
}
/* floating types */
template<> inline float parse_arg<float>(const char *arg, const char **next) {
#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
}
template<> inline double parse_arg<double>(const char *arg, const char **next) {
return strtod(arg,const_cast<char**>(next));
}
template<> inline long double parse_arg<long double>(const char *arg, const char **next) {
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
*
* Variable
* val - The value to write
* result - A pointer to the array to write the value into
*/
template<typename T> void write_result(T val, char *result);
/* signed integer types */
template<> inline void write_result<char>(char val, char *result) {
result[0] = val;
result[1] = '\0';
}
template<> inline void write_result<short int>(short int val, char *result) {
sprintf(result, "%hi", val);
}
template<> inline void write_result<int>(int val, char *result) {
sprintf(result, "%i", val);
}
template<> inline void write_result<long int>(long int val, char *result) {
sprintf(result, "%li", val);
}
template<> inline void write_result<long long int>(long long int val, char *result) {
sprintf(result, "%lli", val);
}
/* unsigned integer types */
template<> inline void write_result<unsigned char>(unsigned char val, char *result) {
result[0] = val;
result[1] = '\0';
}
template<> inline void write_result<unsigned short int>(unsigned short int val, char *result) {
sprintf(result, "%hu", val);
}
template<> inline void write_result<unsigned int>(unsigned int val, char *result) {
sprintf(result, "%u", val);
}
template<> inline void write_result<unsigned long int>(unsigned long int val, char *result) {
sprintf(result, "%lu", val);
}
template<> inline void write_result<unsigned long long int>(unsigned long long int val, char *result) {
sprintf(result, "%llu", val);
}
/* floating types */
template<> inline void write_result<float>(float val, char *result) {
sprintf(result, "%g", val);
}
template<> inline void write_result<double>(double val, char *result) {
sprintf(result, "%g", val);
}
template<> inline void write_result<long double>(long double val, char *result) {
sprintf(result, "%Lg", val);
}
/* 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 rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
(static_cast<T*>(this_ptr)->*member)();
if(result != NULL) {
result[0] = '\0';
}
}
/* Function rpc_method_caller
*/
template<class T, typename A1, void (T::*member)(A1)>
void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
const char *next = arguments;
A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
(static_cast<T*>(this_ptr)->*member)(arg1);
if(result != NULL) {
result[0] = '\0';
}
}
/* Function rpc_method_caller
*/
template<class T, typename A1, typename A2, void (T::*member)(A1,A2)>
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),NULL);
(static_cast<T*>(this_ptr)->*member)(arg1,arg2);
if(result != NULL) {
result[0] = '\0';
}
}
/* Function rpc_method_caller
*/
template<typename R, class T, R (T::*member)()>
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);
}
}
/* Function rpc_method_caller
*/
template<typename R, class T, typename A1, R (T::*member)(A1)>
void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
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) {
write_result<R>(res, result);
}
}
/* Function rpc_method_caller
*/
template<typename R, class T, typename A1, typename A2, R (T::*member)(A1,A2)>
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),NULL);
R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2);
if(result != NULL) {
write_result<R>(res, result);
}
}
/* 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;
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
*
* Variables
* call - A pointer to a string describing the call, which has
* the form /object/method arg ... argn. Arguments are
* delimited by space characters, and the string is terminated
* by a null character.
* result - A pointer to an array to write the result into.
*/
bool rpc(const char *buf, char *result = 0);
} /* namespace mbed */
#endif
