printer

Dependents:   Good_Serial_HelloWorld_Mbed

Fork of mbed by gokmen ascioglu

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rpc.h Source File

rpc.h

00001 /* mbed Microcontroller Library - RPC
00002  * Copyright (c) 2008-2009 ARM Limited. All rights reserved.
00003  */ 
00004  
00005 #ifndef MBED_RPC_H
00006 #define MBED_RPC_H
00007 
00008 /* Section rpc
00009  *  Helpers for rpc handling.
00010  */
00011 
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <ctype.h>
00016 #include "Base.h"
00017 
00018 #include "PinNames.h"
00019 #include <stdint.h>
00020 
00021 namespace mbed {
00022 
00023 /* Function parse_arg
00024  *  Parses and returns a value from a string.
00025  *
00026  * Variable
00027  *  arg - The string to pase
00028  *  next - If not NULL a pointer to after the last 
00029  *    character parsed is written here
00030  */
00031 template<typename T> T parse_arg(const char *arg, const char **next);
00032 
00033 inline char parse_char(const char *arg, const char **next) {
00034     char c = *arg++;
00035     if(c == '\\') {
00036         c = *arg++;
00037         switch(c) {
00038         case 'a': c = '\a'; break;
00039         case 'b': c = '\b'; break;
00040         case 't': c = '\t'; break;
00041         case 'n': c = '\n'; break;
00042         case 'v': c = '\v'; break;
00043         case 'f': c = '\f'; break;
00044         case 'r': c = '\r'; break;
00045         case 'x': 
00046             {
00047                 /* two-character hexadecimal */
00048                 char buf[3];
00049                 buf[0] = *arg++;
00050                 buf[1] = *arg++;
00051                 buf[2] = 0;
00052                 c = strtol(buf, NULL, 16); 
00053             }
00054             break;
00055         default: 
00056             if(isdigit(c)) {
00057                 /* three-character octal */
00058                 char buf[4];
00059                 buf[0] = c;
00060                 buf[1] = *arg++;
00061                 buf[2] = *arg++;
00062                 buf[3] = 0;
00063                 c = strtol(buf, NULL, 8); 
00064             }
00065             break;
00066         }
00067     }
00068     *next = arg;
00069     return c;
00070 }
00071 
00072 /* signed integer types */
00073 
00074 template<> inline int parse_arg<int>(const char *arg, const char **next) {
00075     if(arg[0] == '\'') {
00076         char c = parse_char(arg+1, &arg);
00077         if(next != NULL) *next = arg+1;
00078         return c;
00079     } else {
00080         return strtol(arg, const_cast<char**>(next), 0);        
00081     }
00082 }
00083 
00084 template<> inline char parse_arg<char>(const char *arg, const char **next) {
00085     return parse_arg<int>(arg,next);
00086 }
00087 
00088 template<> inline short int parse_arg<short int>(const char *arg, const char **next) {
00089     return parse_arg<int>(arg,next);
00090 }
00091 
00092 template<> inline long int parse_arg<long int>(const char *arg, const char **next) {
00093     return parse_arg<int>(arg,next);
00094 }
00095 
00096 template<> inline long long parse_arg<long long>(const char *arg, const char **next) {
00097     return strtoll(arg, const_cast<char**>(next), 0);
00098 }
00099 
00100 /* unsigned integer types */
00101 
00102 template<> inline unsigned int parse_arg<unsigned int>(const char *arg, const char **next) {
00103     if(arg[0] == '\'') {
00104         char c = parse_char(arg+1, &arg);
00105         if(next != NULL) *next = arg+1;
00106         return c;
00107     } else {
00108         return strtoul(arg, const_cast<char**>(next), 0);        
00109     }
00110 }
00111 
00112 template<> inline unsigned char parse_arg<unsigned char>(const char *arg, const char **next) {
00113     return parse_arg<unsigned int>(arg,next);
00114 }
00115 
00116 template<> inline unsigned short int parse_arg<unsigned short int>(const char *arg, const char **next) {
00117     return parse_arg<unsigned int>(arg,next);
00118 }
00119 
00120 template<> inline unsigned long int parse_arg<unsigned long int>(const char *arg, const char **next) {
00121     return parse_arg<unsigned int>(arg,next);
00122 }
00123 
00124 template<> inline unsigned long long parse_arg<unsigned long long>(const char *arg, const char **next) {
00125     return strtoull(arg, const_cast<char**>(next), 0);
00126 }
00127 
00128 /* floating types */
00129 
00130 template<> inline float parse_arg<float>(const char *arg, const char **next) {
00131 #if !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 410000
00132     return strtof(arg,const_cast<char**>(next));
00133 #elif __ARMCC_VERSION >= 310000
00134     /* bug in header means no using declaration for strtof */
00135     return std::strtof(arg,const_cast<char**>(next));    
00136 #else
00137     /* strtof not supported */
00138     return strtod(arg,const_cast<char**>(next));
00139 #endif
00140 }
00141 
00142 template<> inline double parse_arg<double>(const char *arg, const char **next) {
00143     return strtod(arg,const_cast<char**>(next));
00144 }
00145 
00146 template<> inline long double parse_arg<long double>(const char *arg, const char **next) {
00147     return strtod(arg,const_cast<char**>(next));
00148 }
00149 
00150 /* string */
00151 
00152 template<> inline char *parse_arg<char*>(const char *arg, const char **next) {
00153     const char *ptr = arg;
00154     char *res = NULL;
00155     if(*arg == '"') {
00156         /* quoted string */
00157         ptr = ++arg;
00158         int len = 0;
00159         /* find the end (and length) of the quoted string */
00160         for(char c = *ptr; c != 0 && c != '"'; c = *++ptr) {
00161             len++;
00162             if(c == '\\') {
00163                 ptr++;
00164             }
00165         }
00166         /* copy the quoted string, and unescape characters */
00167         if(len != 0) {
00168             res = new char[len+1];
00169             char *resptr = res;
00170             while(arg != ptr) {
00171                 *resptr++ = parse_char(arg, &arg);
00172             }
00173             *resptr = 0;
00174         }
00175     } else {
00176         /* unquoted string */
00177         while(isalnum(*ptr) || *ptr=='_') {
00178             ptr++;
00179         }
00180         int len = ptr-arg;
00181         if(len!=0) {
00182             res = new char[len+1];
00183             memcpy(res, arg, len);
00184             res[len] = 0;
00185         }
00186     }
00187 
00188     if(next != NULL) {
00189         *next = ptr;
00190     }
00191     return res;
00192 }
00193 
00194 template<> inline const char *parse_arg<const char*>(const char *arg, const char **next) {
00195     return parse_arg<char*>(arg,next);
00196 }
00197 
00198 /* Pins */
00199 
00200 
00201 inline PinName parse_pins(const char *str) {
00202     const PinName pin_names[] = {p5, p6, p7, p8, p9, p10, p11, p12, p13, p14
00203                                 , p15, p16, p17, p18, p19, p20, p21, p22, p23
00204                                 , p24, p25, p26, p27, p28, p29, p30};
00205 
00206     if(str[0] == 'P') { // Pn_n
00207         uint32_t port = str[1] - '0';
00208         uint32_t pin = str[3] - '0'; // Pn_n
00209         uint32_t pin2 = str[4] - '0'; // Pn_nn
00210         if(pin2 <= 9) {
00211             pin = pin * 10 + pin2;
00212         }
00213 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00214         return (PinName)(LPC_GPIO0_BASE + port * 32 + pin);
00215 #elif defined(TARGET_LPC11U24)
00216         return (PinName)(port * 32 + pin);
00217 #endif
00218     } else if(str[0] == 'p') {  // pn
00219         uint32_t pin = str[1] - '0'; // pn
00220         uint32_t pin2 = str[2] - '0'; // pnn
00221         if(pin2 <= 9) {
00222                   pin = pin * 10 + pin2;
00223         }
00224         if(pin < 5 || pin > 30) {
00225               return NC;
00226         }
00227         return pin_names[pin - 5];
00228     } else if(str[0] == 'L') {  // LEDn
00229         switch(str[3]) {
00230             case '1' : return LED1;
00231             case '2' : return LED2;
00232             case '3' : return LED3;
00233             case '4' : return LED4;
00234         }
00235     } else if(str[0] == 'U') {  // USB?X
00236         switch(str[3]) {
00237             case 'T' : return USBTX;
00238             case 'R' : return USBRX;
00239         }
00240     }
00241     return NC;
00242 }
00243 
00244 template<> inline PinName parse_arg<PinName>(const char *arg, const char **next) {
00245     const char *ptr = arg;
00246     PinName pinname = NC;
00247     while(isalnum(*ptr) || *ptr=='_') {
00248         ptr++;
00249     }
00250     int len = ptr-arg;
00251     if(len!=0) {
00252         pinname = parse_pins(arg);
00253     
00254     }
00255     if(next != NULL) {
00256         *next = ptr;
00257     }
00258     return pinname;
00259 }
00260 
00261 
00262 /* Function write_result
00263  *  Writes a value in to a result string in an appropriate manner
00264  *
00265  * Variable
00266  *  val - The value to write
00267  *  result - A pointer to the array to write the value into
00268  */
00269 template<typename T> void write_result(T val, char *result);
00270 
00271 /* signed integer types */
00272 
00273 template<> inline void write_result<char>(char val, char *result) {
00274     result[0] = val;
00275     result[1] = '\0';
00276 }
00277 
00278 template<> inline void write_result<short int>(short int val, char *result) {
00279     sprintf(result, "%hi", val); 
00280 }
00281 
00282 template<> inline void write_result<int>(int val, char *result) {
00283     sprintf(result, "%i", val); 
00284 }
00285 
00286 template<> inline void write_result<long int>(long int val, char *result) {
00287     sprintf(result, "%li", val); 
00288 }
00289 
00290 template<> inline void write_result<long long int>(long long int val, char *result) {
00291     sprintf(result, "%lli", val); 
00292 }
00293 
00294 /* unsigned integer types */
00295 
00296 template<> inline void write_result<unsigned char>(unsigned char val, char *result) {
00297     result[0] = val;
00298     result[1] = '\0';
00299 }
00300 
00301 template<> inline void write_result<unsigned short int>(unsigned short int val, char *result) {
00302     sprintf(result, "%hu", val); 
00303 }
00304 
00305 template<> inline void write_result<unsigned int>(unsigned int val, char *result) {
00306     sprintf(result, "%u", val); 
00307 }
00308 
00309 template<> inline void write_result<unsigned long int>(unsigned long int val, char *result) {
00310     sprintf(result, "%lu", val); 
00311 }
00312 
00313 template<> inline void write_result<unsigned long long int>(unsigned long long int val, char *result) {
00314     sprintf(result, "%llu", val); 
00315 }
00316 
00317 /* floating types */
00318 
00319 template<> inline void write_result<float>(float val, char *result) {
00320     sprintf(result, "%.17g", val); 
00321 }
00322 
00323 template<> inline void write_result<double>(double val, char *result) {
00324     sprintf(result, "%.17g", val); 
00325 }
00326 
00327 template<> inline void write_result<long double>(long double val, char *result) {
00328     sprintf(result, "%.17Lg", val); 
00329 }
00330 
00331 
00332 /* string */
00333 
00334 template<> inline void write_result<char*>(char *val, char *result) {
00335     if(val==NULL) {
00336         result[0] = 0;
00337     } else {
00338         strcpy(result, val);
00339     }
00340 }
00341 
00342 template<> inline void write_result<const char*>(const char *val, char *result) {
00343     if(val==NULL) {
00344         result[0] = 0;
00345     } else {
00346         strcpy(result, val);
00347     }
00348 }
00349 
00350 
00351 inline const char *next_arg(const char* next) {
00352     while(*next == ' ') next++;
00353     if(*next == ',' || *next == '?') next++;
00354     while(*next == ' ') next++;
00355     return next;
00356 }
00357 
00358 
00359 /* Function rpc_method_caller
00360  */
00361 template<class T, void (T::*member)(const char *,char *)> 
00362 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
00363     (static_cast<T*>(this_ptr)->*member)(arguments,result); 
00364 }
00365 
00366 
00367 /* Function rpc_method_caller
00368  */
00369 template<class T, void (T::*member)()> 
00370 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) { 
00371     (static_cast<T*>(this_ptr)->*member)(); 
00372     if(result != NULL) {
00373         result[0] = '\0';
00374     }
00375 }
00376 
00377 
00378 /* Function rpc_method_caller
00379  */
00380 template<class T, typename A1, void (T::*member)(A1)> 
00381 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
00382 
00383     const char *next = arguments;
00384     A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
00385 
00386     (static_cast<T*>(this_ptr)->*member)(arg1); 
00387     if(result != NULL) {
00388         result[0] = '\0';
00389     }
00390 }
00391 
00392 
00393 /* Function rpc_method_caller
00394  */
00395 template<class T, typename A1, typename A2, void (T::*member)(A1,A2)> 
00396 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
00397 
00398     const char *next = arguments;
00399     A1 arg1 = parse_arg<A1>(next_arg(next),&next);
00400     A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
00401 
00402     (static_cast<T*>(this_ptr)->*member)(arg1,arg2);
00403     if(result != NULL) {
00404         result[0] = '\0';
00405     }
00406 }
00407 
00408 
00409 /* Function rpc_method_caller
00410  */
00411 template<class T, typename A1, typename A2, typename A3, void (T::*member)(A1,A2,A3)> 
00412 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
00413 
00414     const char *next = arguments;
00415     A1 arg1 = parse_arg<A1>(next_arg(next),&next);
00416     A2 arg2 = parse_arg<A2>(next_arg(next),&next);
00417     A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
00418 
00419     (static_cast<T*>(this_ptr)->*member)(arg1,arg2,arg3);
00420     if(result != NULL) {
00421         result[0] = '\0';
00422     }
00423 }
00424 
00425 
00426 /* Function rpc_method_caller
00427  */
00428 template<typename R, class T, R (T::*member)()> 
00429 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) { 
00430     R res = (static_cast<T*>(this_ptr)->*member)();
00431     if(result != NULL) {
00432         write_result<R>(res, result);
00433     }
00434 }
00435 
00436 
00437 /* Function rpc_method_caller
00438  */
00439 template<typename R, class T, typename A1, R (T::*member)(A1)> 
00440 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
00441 
00442     const char *next = arguments;
00443     A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
00444 
00445     R res = (static_cast<T*>(this_ptr)->*member)(arg1);
00446     if(result != NULL) {
00447         write_result<R>(res, result);
00448     }
00449 }
00450 
00451 
00452 /* Function rpc_method_caller
00453  */
00454 template<typename R, class T, typename A1, typename A2, R (T::*member)(A1,A2)> 
00455 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
00456 
00457     const char *next = arguments;
00458     A1 arg1 = parse_arg<A1>(next_arg(next),&next);
00459     A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
00460 
00461     R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2);
00462     if(result != NULL) {
00463         write_result<R>(res, result);
00464     }
00465 }
00466 
00467 
00468 /* Function rpc_method_caller
00469  */
00470 template<typename R, class T, typename A1, typename A2, typename A3, R (T::*member)(A1,A2,A3)> 
00471 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
00472 
00473     const char *next = arguments;
00474     A1 arg1 = parse_arg<A1>(next_arg(next),&next);
00475     A2 arg2 = parse_arg<A2>(next_arg(next),&next);
00476     A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
00477 
00478     R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2,arg3);
00479     if(result != NULL) {
00480         write_result<R>(res, result);
00481     }
00482 }
00483 
00484 
00485 /* Function rpc_function caller
00486  */
00487 template<typename R, R (*func)()>
00488 void rpc_function_caller(const char *arguments, char *result) {
00489     R res = (*func)();
00490     if(result != NULL) {
00491         write_result<R>(res, result);
00492     }
00493 }
00494 
00495 
00496 /* Function rpc_function caller
00497  */
00498 template<typename R, typename A1, R (*func)(A1)>
00499 void rpc_function_caller(const char *arguments, char *result) {
00500     A1 arg1 = parse_arg<A1>(next_arg(arguments),NULL);
00501     R res = (*func)(arg1);
00502     if(result != NULL) {
00503         write_result<R>(res, result);
00504     }
00505 }
00506 
00507 
00508 /* Function rpc_function caller
00509  */
00510 template<typename R, typename A1, typename A2, R (*func)(A1,A2)>
00511 void rpc_function_caller(const char *arguments, char *result) {
00512 
00513     const char *next = arguments;
00514     A1 arg1 = parse_arg<A1>(next_arg(next),&next);
00515     A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
00516 
00517     R res = (*func)(arg1,arg2);
00518     if(result != NULL) {
00519         write_result<R>(res, result);
00520     }
00521 }
00522 
00523 
00524 /* Function rpc_function caller
00525  */
00526 template<typename R, typename A1, typename A2, typename A3, R (*func)(A1,A2,A3)>
00527 void rpc_function_caller(const char *arguments, char *result) {
00528 
00529     const char *next = arguments;
00530     A1 arg1 = parse_arg<A1>(next_arg(next),&next);
00531     A2 arg2 = parse_arg<A2>(next_arg(next),&next);
00532     A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
00533 
00534     R res = (*func)(arg1,arg2,arg3);
00535     if(result != NULL) {
00536         write_result<R>(res, result);
00537     }
00538 }
00539 
00540 
00541 /* Function rpc_function caller
00542  */
00543 template<typename R, typename A1, typename A2, typename A3, typename A4, R (*func)(A1,A2,A3,A4)>
00544 void rpc_function_caller(const char *arguments, char *result) {
00545 
00546     const char *next = arguments;
00547     A1 arg1 = parse_arg<A1>(next_arg(next),&next);
00548     A2 arg2 = parse_arg<A2>(next_arg(next),&next);
00549     A3 arg3 = parse_arg<A3>(next_arg(next),&next);
00550     A4 arg4 = parse_arg<A4>(next_arg(next),NULL);
00551 
00552     R res = (*func)(arg1,arg2,arg3,arg4);
00553     if(result != NULL) {
00554         write_result<R>(res, result);
00555     }
00556 }
00557 
00558 
00559 struct rpc_method { 
00560     const char *name;
00561     typedef void (*caller_t)(Base*, const char*, char*);
00562     typedef const struct rpc_method *(*super_t)(Base*);
00563     union {
00564         caller_t caller;
00565         super_t super;
00566     };
00567 };
00568 
00569 template<class C>
00570 const struct rpc_method *rpc_super(Base *this_ptr) {
00571     return static_cast<C*>(this_ptr)->C::get_rpc_methods();
00572 }
00573 
00574 #define RPC_METHOD_END { NULL, NULL }
00575 #define RPC_METHOD_SUPER(C) { NULL, (rpc_method::caller_t)(rpc_method::super_t)rpc_super<C> }
00576 
00577 /* Function rpc
00578  *  Parse a string describing a call and then do it
00579  *
00580  * Variables
00581  *  call - A pointer to a string describing the call, which has
00582  *    the form /object/method arg ... argn. Arguments are
00583  *    delimited by space characters, and the string is terminated
00584  *    by a null character.
00585  *  result - A pointer to an array to write the result into.
00586  */
00587 bool rpc(const char *buf, char *result = 0);
00588 
00589 
00590 } // namespace mbed
00591 
00592 #endif