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 /* 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
Generated on Wed Jul 13 2022 00:10:01 by
