mbed(SerialHalfDuplex入り)
Fork of mbed by
Diff: rpc.h
- Revision:
- 44:24d45a770a51
- Parent:
- 43:e2ed12d17f06
- Child:
- 45:3d775a932e1d
--- a/rpc.h Fri Oct 26 17:40:46 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,585 +0,0 @@ -/* mbed Microcontroller Library - RPC - * Copyright (c) 2008-2009 ARM Limited. All rights reserved. - */ - -#ifndef MBED_RPC_H -#define MBED_RPC_H - -/** Helpers for rpc handling. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include "Base.h" - -#include "PinNames.h" -#include <stdint.h> - -namespace mbed { - -/** Parses and returns a value from a string. - * - * @param arg The string to pase - * @param 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); - -inline char parse_char(const char *arg, const char **next) { - char c = *arg++; - if(c == '\\') { - c = *arg++; - switch(c) { - case 'a': c = '\a'; break; - case 'b': c = '\b'; break; - case 't': c = '\t'; break; - case 'n': c = '\n'; break; - case 'v': c = '\v'; break; - case 'f': c = '\f'; break; - case 'r': c = '\r'; break; - case 'x': - { - /* two-character hexadecimal */ - char buf[3]; - buf[0] = *arg++; - buf[1] = *arg++; - buf[2] = 0; - c = strtol(buf, NULL, 16); - } - break; - default: - if(isdigit(c)) { - /* three-character octal */ - char buf[4]; - buf[0] = c; - buf[1] = *arg++; - buf[2] = *arg++; - buf[3] = 0; - c = strtol(buf, NULL, 8); - } - break; - } - } - *next = arg; - return c; -} - -/* signed integer types */ - -template<> inline int parse_arg<int>(const char *arg, const char **next) { - if(arg[0] == '\'') { - char c = parse_char(arg+1, &arg); - if(next != NULL) *next = arg+1; - return c; - } else { - return strtol(arg, const_cast<char**>(next), 0); - } -} - -template<> inline char parse_arg<char>(const char *arg, const char **next) { - return parse_arg<int>(arg,next); -} - -template<> inline short int parse_arg<short int>(const char *arg, const char **next) { - return parse_arg<int>(arg,next); -} - -template<> inline long int parse_arg<long int>(const char *arg, const char **next) { - return parse_arg<int>(arg,next); -} - -template<> inline long long parse_arg<long long>(const char *arg, const char **next) { - return strtoll(arg, const_cast<char**>(next), 0); -} - -/* unsigned integer types */ - -template<> inline unsigned int parse_arg<unsigned int>(const char *arg, const char **next) { - if(arg[0] == '\'') { - char c = parse_char(arg+1, &arg); - if(next != NULL) *next = arg+1; - return c; - } else { - return strtoul(arg, const_cast<char**>(next), 0); - } -} - -template<> inline unsigned char parse_arg<unsigned char>(const char *arg, const char **next) { - return parse_arg<unsigned int>(arg,next); -} - -template<> inline unsigned short int parse_arg<unsigned short int>(const char *arg, const char **next) { - return parse_arg<unsigned int>(arg,next); -} - -template<> inline unsigned long int parse_arg<unsigned long int>(const char *arg, const char **next) { - return parse_arg<unsigned int>(arg,next); -} - -template<> inline unsigned long long parse_arg<unsigned long long>(const char *arg, const char **next) { - return strtoull(arg, const_cast<char**>(next), 0); -} - -/* 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; - char *res = NULL; - if(*arg == '"') { - /* quoted string */ - ptr = ++arg; - int len = 0; - /* find the end (and length) of the quoted string */ - for(char c = *ptr; c != 0 && c != '"'; c = *++ptr) { - len++; - if(c == '\\') { - ptr++; - } - } - /* copy the quoted string, and unescape characters */ - if(len != 0) { - res = new char[len+1]; - char *resptr = res; - while(arg != ptr) { - *resptr++ = parse_char(arg, &arg); - } - *resptr = 0; - } - } else { - /* unquoted string */ - while(isalnum(*ptr) || *ptr=='_') { - ptr++; - } - int len = ptr-arg; - if(len!=0) { - res = new char[len+1]; - memcpy(res, arg, len); - res[len] = 0; - } - } - - if(next != NULL) { - *next = ptr; - } - return res; -} - -template<> inline const char *parse_arg<const char*>(const char *arg, const char **next) { - return parse_arg<char*>(arg,next); -} - -/* Pins */ - - -inline PinName parse_pins(const char *str) { - const PinName pin_names[] = {p5, p6, p7, p8, p9, p10, p11, p12, p13, p14 - , p15, p16, p17, p18, p19, p20, p21, p22, p23 - , p24, p25, p26, p27, p28, p29, p30}; - - if(str[0] == 'P') { // Pn_n - uint32_t port = str[1] - '0'; - uint32_t pin = str[3] - '0'; // Pn_n - uint32_t pin2 = str[4] - '0'; // Pn_nn - if(pin2 <= 9) { - pin = pin * 10 + pin2; - } -#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) - return (PinName)(LPC_GPIO0_BASE + port * 32 + pin); -#elif defined(TARGET_LPC11U24) - return (PinName)(port * 32 + pin); -#endif - } else if(str[0] == 'p') { // pn - uint32_t pin = str[1] - '0'; // pn - uint32_t pin2 = str[2] - '0'; // pnn - if(pin2 <= 9) { - pin = pin * 10 + pin2; - } - if(pin < 5 || pin > 30) { - return NC; - } - return pin_names[pin - 5]; - } else if(str[0] == 'L') { // LEDn - switch(str[3]) { - case '1' : return LED1; - case '2' : return LED2; - case '3' : return LED3; - case '4' : return LED4; - } - } else if(str[0] == 'U') { // USB?X - switch(str[3]) { - case 'T' : return USBTX; - case 'R' : return USBRX; - } - } - return NC; -} - -template<> inline PinName parse_arg<PinName>(const char *arg, const char **next) { - const char *ptr = arg; - PinName pinname = NC; - while(isalnum(*ptr) || *ptr=='_') { - ptr++; - } - int len = ptr-arg; - if(len!=0) { - pinname = parse_pins(arg); - - } - if(next != NULL) { - *next = ptr; - } - return pinname; -} - - -/** Writes a value in to a result string in an appropriate manner - * - * @param val The value to write - * @param 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, "%.17g", val); -} - -template<> inline void write_result<double>(double val, char *result) { - sprintf(result, "%.17g", val); -} - -template<> inline void write_result<long double>(long double val, char *result) { - sprintf(result, "%.17Lg", val); -} - - -/* string */ - -template<> inline void write_result<char*>(char *val, char *result) { - if(val==NULL) { - result[0] = 0; - } else { - strcpy(result, val); - } -} - -template<> inline void write_result<const char*>(const char *val, char *result) { - if(val==NULL) { - result[0] = 0; - } else { - strcpy(result, val); - } -} - - -inline const char *next_arg(const char* next) { - while(*next == ' ') next++; - if(*next == ',' || *next == '?') next++; - while(*next == ' ') next++; - return next; -} - - -/** 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); -} - - -/** 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'; - } -} - - -/** 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'; - } -} - - -/** 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'; - } -} - - -/** rpc_method_caller - */ -template<class T, typename A1, typename A2, typename A3, void (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); - - (static_cast<T*>(this_ptr)->*member)(arg1,arg2,arg3); - if(result != NULL) { - result[0] = '\0'; - } -} - - -/** 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); - } -} - - -/** 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); - } -} - - -/** 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); - } -} - - -/** 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); - } -} - - -/** 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); - } -} - - -/** 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); - } -} - - -/** 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); - } -} - - -/** 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); - } -} - - -/** 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> } - -/** Parse a string describing a call and then do it - * - * @param 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. - * @param result A pointer to an array to write the result into. - */ -bool rpc(const char *buf, char *result = 0); - - -} // namespace mbed - -#endif