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