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
Diff: rpc.h
- Revision:
- 8:00a04e5cd407
- Parent:
- 6:3fd6a337c7cc
- Child:
- 11:1c1ebd0324fa
--- a/rpc.h Fri Jan 23 16:26:21 2009 +0000
+++ b/rpc.h Tue Feb 03 18:02:02 2009 +0000
@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include "Base.h"
namespace mbed {
@@ -26,50 +27,99 @@
*/
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) {
- if(next != NULL) *next = arg+1;
- return *arg;
+ return parse_arg<int>(arg,next);
}
template<> inline short int parse_arg<short int>(const char *arg, const char **next) {
- return strtol(arg, const_cast<char**>(next), 10);
+ return parse_arg<int>(arg,next);
}
template<> inline long int parse_arg<long int>(const char *arg, const char **next) {
- return strtol(arg, const_cast<char**>(next), 10);
-}
-
-template<> inline int parse_arg<int>(const char *arg, const char **next) {
- return strtol(arg, const_cast<char**>(next), 10);
+ 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), 10);
+ 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) {
- if(next != NULL) *next = arg+1;
- return *arg;
+ return parse_arg<unsigned int>(arg,next);
}
template<> inline unsigned short int parse_arg<unsigned short int>(const char *arg, const char **next) {
- return strtoul(arg, const_cast<char**>(next), 10);
+ return parse_arg<unsigned int>(arg,next);
}
template<> inline unsigned long int parse_arg<unsigned long int>(const char *arg, const char **next) {
- return strtoul(arg, const_cast<char**>(next), 10);
-}
-
-template<> inline unsigned int parse_arg<unsigned int>(const char *arg, const char **next) {
- return strtoul(arg, const_cast<char**>(next), 10);
+ 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), 10);
+ return strtoull(arg, const_cast<char**>(next), 0);
}
/* floating types */
@@ -98,22 +148,44 @@
template<> inline char *parse_arg<char*>(const char *arg, const char **next) {
const char *ptr = arg;
- while(*ptr >= '!' && *ptr != ',') {
- ptr++;
+ 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;
+ }
}
- int len = ptr-arg;
- char *p;
- if(len==0) {
- p = NULL;
- } else {
- p = new char[len+1];
- memcpy(p, arg, len);
- p[len] = 0;
- }
+
if(next != NULL) {
*next = ptr;
}
- return p;
+ return res;
}
template<> inline const char *parse_arg<const char*>(const char *arg, const char **next) {
@@ -179,15 +251,15 @@
/* floating types */
template<> inline void write_result<float>(float val, char *result) {
- sprintf(result, "%g", val);
+ sprintf(result, "%.17g", val);
}
template<> inline void write_result<double>(double val, char *result) {
- sprintf(result, "%g", val);
+ sprintf(result, "%.17g", val);
}
template<> inline void write_result<long double>(long double val, char *result) {
- sprintf(result, "%Lg", val);
+ sprintf(result, "%.17Lg", val);
}
@@ -211,7 +283,9 @@
inline const char *next_arg(const char* next) {
- if(*next == ',' || *next == ' ') next++;
+ while(*next == ' ') next++;
+ if(*next == ',' || *next == '?') next++;
+ while(*next == ' ') next++;
return next;
}
@@ -268,6 +342,23 @@
/* Function 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';
+ }
+}
+
+
+/* Function 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)();
