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
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 20:12:25 by
