Lab 1 Program C

Dependents:   Lab1C

Fork of mbed by -deleted-

Committer:
simon.ford@mbed.co.uk
Date:
Tue Feb 03 18:02:02 2009 +0000
Revision:
8:00a04e5cd407
Parent:
6:3fd6a337c7cc
Child:
11:1c1ebd0324fa
* Update to improve filesystem support
* Add a generic FATFileSystem

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon.ford@mbed.co.uk 4:5d1359a283bc 1 /* mbed Microcontroller Library
simon.ford@mbed.co.uk 4:5d1359a283bc 2 * Copyright (c) 2008 ARM Limited. All rights reserved.
simon.ford@mbed.co.uk 4:5d1359a283bc 3 */
simon.ford@mbed.co.uk 4:5d1359a283bc 4
simon.ford@mbed.co.uk 4:5d1359a283bc 5 #ifndef MBED_RPC_H
simon.ford@mbed.co.uk 4:5d1359a283bc 6 #define MBED_RPC_H
simon.ford@mbed.co.uk 4:5d1359a283bc 7
simon.ford@mbed.co.uk 4:5d1359a283bc 8 /* Section rpc
simon.ford@mbed.co.uk 4:5d1359a283bc 9 * Helpers for rpc handling.
simon.ford@mbed.co.uk 4:5d1359a283bc 10 */
simon.ford@mbed.co.uk 4:5d1359a283bc 11
simon.ford@mbed.co.uk 4:5d1359a283bc 12 #include <stdlib.h>
simon.ford@mbed.co.uk 4:5d1359a283bc 13 #include <stdio.h>
simon.ford@mbed.co.uk 4:5d1359a283bc 14 #include <string.h>
simon.ford@mbed.co.uk 8:00a04e5cd407 15 #include <ctype.h>
simon.ford@mbed.co.uk 4:5d1359a283bc 16 #include "Base.h"
simon.ford@mbed.co.uk 4:5d1359a283bc 17
simon.ford@mbed.co.uk 4:5d1359a283bc 18 namespace mbed {
simon.ford@mbed.co.uk 4:5d1359a283bc 19
simon.ford@mbed.co.uk 4:5d1359a283bc 20 /* Function parse_arg
simon.ford@mbed.co.uk 4:5d1359a283bc 21 * Parses and returns a value from a string.
simon.ford@mbed.co.uk 4:5d1359a283bc 22 *
simon.ford@mbed.co.uk 4:5d1359a283bc 23 * Variable
simon.ford@mbed.co.uk 4:5d1359a283bc 24 * arg - The string to pase
simon.ford@mbed.co.uk 4:5d1359a283bc 25 * next - If not NULL a pointer to after the last
simon.ford@mbed.co.uk 4:5d1359a283bc 26 * character parsed is written here
simon.ford@mbed.co.uk 4:5d1359a283bc 27 */
simon.ford@mbed.co.uk 4:5d1359a283bc 28 template<typename T> T parse_arg(const char *arg, const char **next);
simon.ford@mbed.co.uk 4:5d1359a283bc 29
simon.ford@mbed.co.uk 8:00a04e5cd407 30 inline char parse_char(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 31 char c = *arg++;
simon.ford@mbed.co.uk 8:00a04e5cd407 32 if(c == '\\') {
simon.ford@mbed.co.uk 8:00a04e5cd407 33 c = *arg++;
simon.ford@mbed.co.uk 8:00a04e5cd407 34 switch(c) {
simon.ford@mbed.co.uk 8:00a04e5cd407 35 case 'a': c = '\a'; break;
simon.ford@mbed.co.uk 8:00a04e5cd407 36 case 'b': c = '\b'; break;
simon.ford@mbed.co.uk 8:00a04e5cd407 37 case 't': c = '\t'; break;
simon.ford@mbed.co.uk 8:00a04e5cd407 38 case 'n': c = '\n'; break;
simon.ford@mbed.co.uk 8:00a04e5cd407 39 case 'v': c = '\v'; break;
simon.ford@mbed.co.uk 8:00a04e5cd407 40 case 'f': c = '\f'; break;
simon.ford@mbed.co.uk 8:00a04e5cd407 41 case 'r': c = '\r'; break;
simon.ford@mbed.co.uk 8:00a04e5cd407 42 case 'x':
simon.ford@mbed.co.uk 8:00a04e5cd407 43 {
simon.ford@mbed.co.uk 8:00a04e5cd407 44 /* two-character hexadecimal */
simon.ford@mbed.co.uk 8:00a04e5cd407 45 char buf[3];
simon.ford@mbed.co.uk 8:00a04e5cd407 46 buf[0] = *arg++;
simon.ford@mbed.co.uk 8:00a04e5cd407 47 buf[1] = *arg++;
simon.ford@mbed.co.uk 8:00a04e5cd407 48 buf[2] = 0;
simon.ford@mbed.co.uk 8:00a04e5cd407 49 c = strtol(buf, NULL, 16);
simon.ford@mbed.co.uk 8:00a04e5cd407 50 }
simon.ford@mbed.co.uk 8:00a04e5cd407 51 break;
simon.ford@mbed.co.uk 8:00a04e5cd407 52 default:
simon.ford@mbed.co.uk 8:00a04e5cd407 53 if(isdigit(c)) {
simon.ford@mbed.co.uk 8:00a04e5cd407 54 /* three-character octal */
simon.ford@mbed.co.uk 8:00a04e5cd407 55 char buf[4];
simon.ford@mbed.co.uk 8:00a04e5cd407 56 buf[0] = c;
simon.ford@mbed.co.uk 8:00a04e5cd407 57 buf[1] = *arg++;
simon.ford@mbed.co.uk 8:00a04e5cd407 58 buf[2] = *arg++;
simon.ford@mbed.co.uk 8:00a04e5cd407 59 buf[3] = 0;
simon.ford@mbed.co.uk 8:00a04e5cd407 60 c = strtol(buf, NULL, 8);
simon.ford@mbed.co.uk 8:00a04e5cd407 61 }
simon.ford@mbed.co.uk 8:00a04e5cd407 62 break;
simon.ford@mbed.co.uk 8:00a04e5cd407 63 }
simon.ford@mbed.co.uk 8:00a04e5cd407 64 }
simon.ford@mbed.co.uk 8:00a04e5cd407 65 *next = arg;
simon.ford@mbed.co.uk 8:00a04e5cd407 66 return c;
simon.ford@mbed.co.uk 8:00a04e5cd407 67 }
simon.ford@mbed.co.uk 8:00a04e5cd407 68
simon.ford@mbed.co.uk 4:5d1359a283bc 69 /* signed integer types */
simon.ford@mbed.co.uk 4:5d1359a283bc 70
simon.ford@mbed.co.uk 8:00a04e5cd407 71 template<> inline int parse_arg<int>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 72 if(arg[0] == '\'') {
simon.ford@mbed.co.uk 8:00a04e5cd407 73 char c = parse_char(arg+1, &arg);
simon.ford@mbed.co.uk 8:00a04e5cd407 74 if(next != NULL) *next = arg+1;
simon.ford@mbed.co.uk 8:00a04e5cd407 75 return c;
simon.ford@mbed.co.uk 8:00a04e5cd407 76 } else {
simon.ford@mbed.co.uk 8:00a04e5cd407 77 return strtol(arg, const_cast<char**>(next), 0);
simon.ford@mbed.co.uk 8:00a04e5cd407 78 }
simon.ford@mbed.co.uk 8:00a04e5cd407 79 }
simon.ford@mbed.co.uk 8:00a04e5cd407 80
simon.ford@mbed.co.uk 4:5d1359a283bc 81 template<> inline char parse_arg<char>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 82 return parse_arg<int>(arg,next);
simon.ford@mbed.co.uk 4:5d1359a283bc 83 }
simon.ford@mbed.co.uk 4:5d1359a283bc 84
simon.ford@mbed.co.uk 4:5d1359a283bc 85 template<> inline short int parse_arg<short int>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 86 return parse_arg<int>(arg,next);
simon.ford@mbed.co.uk 4:5d1359a283bc 87 }
simon.ford@mbed.co.uk 4:5d1359a283bc 88
simon.ford@mbed.co.uk 4:5d1359a283bc 89 template<> inline long int parse_arg<long int>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 90 return parse_arg<int>(arg,next);
simon.ford@mbed.co.uk 4:5d1359a283bc 91 }
simon.ford@mbed.co.uk 4:5d1359a283bc 92
simon.ford@mbed.co.uk 4:5d1359a283bc 93 template<> inline long long parse_arg<long long>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 94 return strtoll(arg, const_cast<char**>(next), 0);
simon.ford@mbed.co.uk 4:5d1359a283bc 95 }
simon.ford@mbed.co.uk 4:5d1359a283bc 96
simon.ford@mbed.co.uk 4:5d1359a283bc 97 /* unsigned integer types */
simon.ford@mbed.co.uk 4:5d1359a283bc 98
simon.ford@mbed.co.uk 8:00a04e5cd407 99 template<> inline unsigned int parse_arg<unsigned int>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 100 if(arg[0] == '\'') {
simon.ford@mbed.co.uk 8:00a04e5cd407 101 char c = parse_char(arg+1, &arg);
simon.ford@mbed.co.uk 8:00a04e5cd407 102 if(next != NULL) *next = arg+1;
simon.ford@mbed.co.uk 8:00a04e5cd407 103 return c;
simon.ford@mbed.co.uk 8:00a04e5cd407 104 } else {
simon.ford@mbed.co.uk 8:00a04e5cd407 105 return strtoul(arg, const_cast<char**>(next), 0);
simon.ford@mbed.co.uk 8:00a04e5cd407 106 }
simon.ford@mbed.co.uk 8:00a04e5cd407 107 }
simon.ford@mbed.co.uk 8:00a04e5cd407 108
simon.ford@mbed.co.uk 4:5d1359a283bc 109 template<> inline unsigned char parse_arg<unsigned char>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 110 return parse_arg<unsigned int>(arg,next);
simon.ford@mbed.co.uk 4:5d1359a283bc 111 }
simon.ford@mbed.co.uk 4:5d1359a283bc 112
simon.ford@mbed.co.uk 4:5d1359a283bc 113 template<> inline unsigned short int parse_arg<unsigned short int>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 114 return parse_arg<unsigned int>(arg,next);
simon.ford@mbed.co.uk 4:5d1359a283bc 115 }
simon.ford@mbed.co.uk 4:5d1359a283bc 116
simon.ford@mbed.co.uk 4:5d1359a283bc 117 template<> inline unsigned long int parse_arg<unsigned long int>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 118 return parse_arg<unsigned int>(arg,next);
simon.ford@mbed.co.uk 4:5d1359a283bc 119 }
simon.ford@mbed.co.uk 4:5d1359a283bc 120
simon.ford@mbed.co.uk 4:5d1359a283bc 121 template<> inline unsigned long long parse_arg<unsigned long long>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 122 return strtoull(arg, const_cast<char**>(next), 0);
simon.ford@mbed.co.uk 4:5d1359a283bc 123 }
simon.ford@mbed.co.uk 4:5d1359a283bc 124
simon.ford@mbed.co.uk 4:5d1359a283bc 125 /* floating types */
simon.ford@mbed.co.uk 4:5d1359a283bc 126
simon.ford@mbed.co.uk 4:5d1359a283bc 127 template<> inline float parse_arg<float>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 5:62573be585e9 128 #if !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 410000
simon.ford@mbed.co.uk 4:5d1359a283bc 129 return strtof(arg,const_cast<char**>(next));
simon.ford@mbed.co.uk 5:62573be585e9 130 #elif __ARMCC_VERSION >= 310000
simon.ford@mbed.co.uk 5:62573be585e9 131 /* bug in header means no using declaration for strtof */
simon.ford@mbed.co.uk 5:62573be585e9 132 return std::strtof(arg,const_cast<char**>(next));
simon.ford@mbed.co.uk 4:5d1359a283bc 133 #else
simon.ford@mbed.co.uk 5:62573be585e9 134 /* strtof not supported */
simon.ford@mbed.co.uk 4:5d1359a283bc 135 return strtod(arg,const_cast<char**>(next));
simon.ford@mbed.co.uk 4:5d1359a283bc 136 #endif
simon.ford@mbed.co.uk 4:5d1359a283bc 137 }
simon.ford@mbed.co.uk 4:5d1359a283bc 138
simon.ford@mbed.co.uk 4:5d1359a283bc 139 template<> inline double parse_arg<double>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 4:5d1359a283bc 140 return strtod(arg,const_cast<char**>(next));
simon.ford@mbed.co.uk 4:5d1359a283bc 141 }
simon.ford@mbed.co.uk 4:5d1359a283bc 142
simon.ford@mbed.co.uk 4:5d1359a283bc 143 template<> inline long double parse_arg<long double>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 4:5d1359a283bc 144 return strtod(arg,const_cast<char**>(next));
simon.ford@mbed.co.uk 4:5d1359a283bc 145 }
simon.ford@mbed.co.uk 4:5d1359a283bc 146
simon.ford@mbed.co.uk 5:62573be585e9 147 /* string */
simon.ford@mbed.co.uk 5:62573be585e9 148
simon.ford@mbed.co.uk 5:62573be585e9 149 template<> inline char *parse_arg<char*>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 5:62573be585e9 150 const char *ptr = arg;
simon.ford@mbed.co.uk 8:00a04e5cd407 151 char *res = NULL;
simon.ford@mbed.co.uk 8:00a04e5cd407 152 if(*arg == '"') {
simon.ford@mbed.co.uk 8:00a04e5cd407 153 /* quoted string */
simon.ford@mbed.co.uk 8:00a04e5cd407 154 ptr = ++arg;
simon.ford@mbed.co.uk 8:00a04e5cd407 155 int len = 0;
simon.ford@mbed.co.uk 8:00a04e5cd407 156 /* find the end (and length) of the quoted string */
simon.ford@mbed.co.uk 8:00a04e5cd407 157 for(char c = *ptr; c != 0 && c != '"'; c = *++ptr) {
simon.ford@mbed.co.uk 8:00a04e5cd407 158 len++;
simon.ford@mbed.co.uk 8:00a04e5cd407 159 if(c == '\\') {
simon.ford@mbed.co.uk 8:00a04e5cd407 160 ptr++;
simon.ford@mbed.co.uk 8:00a04e5cd407 161 }
simon.ford@mbed.co.uk 8:00a04e5cd407 162 }
simon.ford@mbed.co.uk 8:00a04e5cd407 163 /* copy the quoted string, and unescape characters */
simon.ford@mbed.co.uk 8:00a04e5cd407 164 if(len != 0) {
simon.ford@mbed.co.uk 8:00a04e5cd407 165 res = new char[len+1];
simon.ford@mbed.co.uk 8:00a04e5cd407 166 char *resptr = res;
simon.ford@mbed.co.uk 8:00a04e5cd407 167 while(arg != ptr) {
simon.ford@mbed.co.uk 8:00a04e5cd407 168 *resptr++ = parse_char(arg, &arg);
simon.ford@mbed.co.uk 8:00a04e5cd407 169 }
simon.ford@mbed.co.uk 8:00a04e5cd407 170 *resptr = 0;
simon.ford@mbed.co.uk 8:00a04e5cd407 171 }
simon.ford@mbed.co.uk 8:00a04e5cd407 172 } else {
simon.ford@mbed.co.uk 8:00a04e5cd407 173 /* unquoted string */
simon.ford@mbed.co.uk 8:00a04e5cd407 174 while(isalnum(*ptr) || *ptr=='_') {
simon.ford@mbed.co.uk 8:00a04e5cd407 175 ptr++;
simon.ford@mbed.co.uk 8:00a04e5cd407 176 }
simon.ford@mbed.co.uk 8:00a04e5cd407 177 int len = ptr-arg;
simon.ford@mbed.co.uk 8:00a04e5cd407 178 if(len!=0) {
simon.ford@mbed.co.uk 8:00a04e5cd407 179 res = new char[len+1];
simon.ford@mbed.co.uk 8:00a04e5cd407 180 memcpy(res, arg, len);
simon.ford@mbed.co.uk 8:00a04e5cd407 181 res[len] = 0;
simon.ford@mbed.co.uk 8:00a04e5cd407 182 }
simon.ford@mbed.co.uk 5:62573be585e9 183 }
simon.ford@mbed.co.uk 8:00a04e5cd407 184
simon.ford@mbed.co.uk 5:62573be585e9 185 if(next != NULL) {
simon.ford@mbed.co.uk 5:62573be585e9 186 *next = ptr;
simon.ford@mbed.co.uk 5:62573be585e9 187 }
simon.ford@mbed.co.uk 8:00a04e5cd407 188 return res;
simon.ford@mbed.co.uk 5:62573be585e9 189 }
simon.ford@mbed.co.uk 5:62573be585e9 190
simon.ford@mbed.co.uk 5:62573be585e9 191 template<> inline const char *parse_arg<const char*>(const char *arg, const char **next) {
simon.ford@mbed.co.uk 5:62573be585e9 192 return parse_arg<char*>(arg,next);
simon.ford@mbed.co.uk 5:62573be585e9 193 }
simon.ford@mbed.co.uk 5:62573be585e9 194
simon.ford@mbed.co.uk 4:5d1359a283bc 195
simon.ford@mbed.co.uk 4:5d1359a283bc 196 /* Function write_result
simon.ford@mbed.co.uk 4:5d1359a283bc 197 * Writes a value in to a result string in an appropriate manner
simon.ford@mbed.co.uk 4:5d1359a283bc 198 *
simon.ford@mbed.co.uk 4:5d1359a283bc 199 * Variable
simon.ford@mbed.co.uk 4:5d1359a283bc 200 * val - The value to write
simon.ford@mbed.co.uk 4:5d1359a283bc 201 * result - A pointer to the array to write the value into
simon.ford@mbed.co.uk 4:5d1359a283bc 202 */
simon.ford@mbed.co.uk 4:5d1359a283bc 203 template<typename T> void write_result(T val, char *result);
simon.ford@mbed.co.uk 4:5d1359a283bc 204
simon.ford@mbed.co.uk 4:5d1359a283bc 205 /* signed integer types */
simon.ford@mbed.co.uk 4:5d1359a283bc 206
simon.ford@mbed.co.uk 4:5d1359a283bc 207 template<> inline void write_result<char>(char val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 208 result[0] = val;
simon.ford@mbed.co.uk 4:5d1359a283bc 209 result[1] = '\0';
simon.ford@mbed.co.uk 4:5d1359a283bc 210 }
simon.ford@mbed.co.uk 4:5d1359a283bc 211
simon.ford@mbed.co.uk 4:5d1359a283bc 212 template<> inline void write_result<short int>(short int val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 213 sprintf(result, "%hi", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 214 }
simon.ford@mbed.co.uk 4:5d1359a283bc 215
simon.ford@mbed.co.uk 4:5d1359a283bc 216 template<> inline void write_result<int>(int val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 217 sprintf(result, "%i", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 218 }
simon.ford@mbed.co.uk 4:5d1359a283bc 219
simon.ford@mbed.co.uk 4:5d1359a283bc 220 template<> inline void write_result<long int>(long int val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 221 sprintf(result, "%li", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 222 }
simon.ford@mbed.co.uk 4:5d1359a283bc 223
simon.ford@mbed.co.uk 4:5d1359a283bc 224 template<> inline void write_result<long long int>(long long int val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 225 sprintf(result, "%lli", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 226 }
simon.ford@mbed.co.uk 4:5d1359a283bc 227
simon.ford@mbed.co.uk 4:5d1359a283bc 228 /* unsigned integer types */
simon.ford@mbed.co.uk 4:5d1359a283bc 229
simon.ford@mbed.co.uk 4:5d1359a283bc 230 template<> inline void write_result<unsigned char>(unsigned char val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 231 result[0] = val;
simon.ford@mbed.co.uk 4:5d1359a283bc 232 result[1] = '\0';
simon.ford@mbed.co.uk 4:5d1359a283bc 233 }
simon.ford@mbed.co.uk 4:5d1359a283bc 234
simon.ford@mbed.co.uk 4:5d1359a283bc 235 template<> inline void write_result<unsigned short int>(unsigned short int val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 236 sprintf(result, "%hu", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 237 }
simon.ford@mbed.co.uk 4:5d1359a283bc 238
simon.ford@mbed.co.uk 4:5d1359a283bc 239 template<> inline void write_result<unsigned int>(unsigned int val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 240 sprintf(result, "%u", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 241 }
simon.ford@mbed.co.uk 4:5d1359a283bc 242
simon.ford@mbed.co.uk 4:5d1359a283bc 243 template<> inline void write_result<unsigned long int>(unsigned long int val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 244 sprintf(result, "%lu", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 245 }
simon.ford@mbed.co.uk 4:5d1359a283bc 246
simon.ford@mbed.co.uk 4:5d1359a283bc 247 template<> inline void write_result<unsigned long long int>(unsigned long long int val, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 248 sprintf(result, "%llu", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 249 }
simon.ford@mbed.co.uk 4:5d1359a283bc 250
simon.ford@mbed.co.uk 4:5d1359a283bc 251 /* floating types */
simon.ford@mbed.co.uk 4:5d1359a283bc 252
simon.ford@mbed.co.uk 4:5d1359a283bc 253 template<> inline void write_result<float>(float val, char *result) {
simon.ford@mbed.co.uk 8:00a04e5cd407 254 sprintf(result, "%.17g", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 255 }
simon.ford@mbed.co.uk 4:5d1359a283bc 256
simon.ford@mbed.co.uk 4:5d1359a283bc 257 template<> inline void write_result<double>(double val, char *result) {
simon.ford@mbed.co.uk 8:00a04e5cd407 258 sprintf(result, "%.17g", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 259 }
simon.ford@mbed.co.uk 4:5d1359a283bc 260
simon.ford@mbed.co.uk 4:5d1359a283bc 261 template<> inline void write_result<long double>(long double val, char *result) {
simon.ford@mbed.co.uk 8:00a04e5cd407 262 sprintf(result, "%.17Lg", val);
simon.ford@mbed.co.uk 4:5d1359a283bc 263 }
simon.ford@mbed.co.uk 4:5d1359a283bc 264
simon.ford@mbed.co.uk 4:5d1359a283bc 265
simon.ford@mbed.co.uk 5:62573be585e9 266 /* string */
simon.ford@mbed.co.uk 5:62573be585e9 267
simon.ford@mbed.co.uk 5:62573be585e9 268 template<> inline void write_result<char*>(char *val, char *result) {
simon.ford@mbed.co.uk 6:3fd6a337c7cc 269 if(val==NULL) {
simon.ford@mbed.co.uk 6:3fd6a337c7cc 270 result[0] = 0;
simon.ford@mbed.co.uk 6:3fd6a337c7cc 271 } else {
simon.ford@mbed.co.uk 6:3fd6a337c7cc 272 strcpy(result, val);
simon.ford@mbed.co.uk 6:3fd6a337c7cc 273 }
simon.ford@mbed.co.uk 5:62573be585e9 274 }
simon.ford@mbed.co.uk 5:62573be585e9 275
simon.ford@mbed.co.uk 5:62573be585e9 276 template<> inline void write_result<const char*>(const char *val, char *result) {
simon.ford@mbed.co.uk 6:3fd6a337c7cc 277 if(val==NULL) {
simon.ford@mbed.co.uk 6:3fd6a337c7cc 278 result[0] = 0;
simon.ford@mbed.co.uk 6:3fd6a337c7cc 279 } else {
simon.ford@mbed.co.uk 6:3fd6a337c7cc 280 strcpy(result, val);
simon.ford@mbed.co.uk 6:3fd6a337c7cc 281 }
simon.ford@mbed.co.uk 5:62573be585e9 282 }
simon.ford@mbed.co.uk 5:62573be585e9 283
simon.ford@mbed.co.uk 5:62573be585e9 284
simon.ford@mbed.co.uk 5:62573be585e9 285 inline const char *next_arg(const char* next) {
simon.ford@mbed.co.uk 8:00a04e5cd407 286 while(*next == ' ') next++;
simon.ford@mbed.co.uk 8:00a04e5cd407 287 if(*next == ',' || *next == '?') next++;
simon.ford@mbed.co.uk 8:00a04e5cd407 288 while(*next == ' ') next++;
simon.ford@mbed.co.uk 5:62573be585e9 289 return next;
simon.ford@mbed.co.uk 5:62573be585e9 290 }
simon.ford@mbed.co.uk 5:62573be585e9 291
simon.ford@mbed.co.uk 5:62573be585e9 292
simon.ford@mbed.co.uk 5:62573be585e9 293 /* Function rpc_method_caller
simon.ford@mbed.co.uk 5:62573be585e9 294 */
simon.ford@mbed.co.uk 5:62573be585e9 295 template<class T, void (T::*member)(const char *,char *)>
simon.ford@mbed.co.uk 5:62573be585e9 296 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 5:62573be585e9 297 (static_cast<T*>(this_ptr)->*member)(arguments,result);
simon.ford@mbed.co.uk 5:62573be585e9 298 }
simon.ford@mbed.co.uk 5:62573be585e9 299
simon.ford@mbed.co.uk 5:62573be585e9 300
simon.ford@mbed.co.uk 5:62573be585e9 301 /* Function rpc_method_caller
simon.ford@mbed.co.uk 4:5d1359a283bc 302 */
simon.ford@mbed.co.uk 4:5d1359a283bc 303 template<class T, void (T::*member)()>
simon.ford@mbed.co.uk 5:62573be585e9 304 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 305 (static_cast<T*>(this_ptr)->*member)();
simon.ford@mbed.co.uk 4:5d1359a283bc 306 if(result != NULL) {
simon.ford@mbed.co.uk 4:5d1359a283bc 307 result[0] = '\0';
simon.ford@mbed.co.uk 4:5d1359a283bc 308 }
simon.ford@mbed.co.uk 4:5d1359a283bc 309 }
simon.ford@mbed.co.uk 4:5d1359a283bc 310
simon.ford@mbed.co.uk 4:5d1359a283bc 311
simon.ford@mbed.co.uk 5:62573be585e9 312 /* Function rpc_method_caller
simon.ford@mbed.co.uk 4:5d1359a283bc 313 */
simon.ford@mbed.co.uk 4:5d1359a283bc 314 template<class T, typename A1, void (T::*member)(A1)>
simon.ford@mbed.co.uk 5:62573be585e9 315 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 316
simon.ford@mbed.co.uk 5:62573be585e9 317 const char *next = arguments;
simon.ford@mbed.co.uk 5:62573be585e9 318 A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
simon.ford@mbed.co.uk 4:5d1359a283bc 319
simon.ford@mbed.co.uk 4:5d1359a283bc 320 (static_cast<T*>(this_ptr)->*member)(arg1);
simon.ford@mbed.co.uk 4:5d1359a283bc 321 if(result != NULL) {
simon.ford@mbed.co.uk 4:5d1359a283bc 322 result[0] = '\0';
simon.ford@mbed.co.uk 4:5d1359a283bc 323 }
simon.ford@mbed.co.uk 4:5d1359a283bc 324 }
simon.ford@mbed.co.uk 4:5d1359a283bc 325
simon.ford@mbed.co.uk 4:5d1359a283bc 326
simon.ford@mbed.co.uk 5:62573be585e9 327 /* Function rpc_method_caller
simon.ford@mbed.co.uk 4:5d1359a283bc 328 */
simon.ford@mbed.co.uk 4:5d1359a283bc 329 template<class T, typename A1, typename A2, void (T::*member)(A1,A2)>
simon.ford@mbed.co.uk 5:62573be585e9 330 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 331
simon.ford@mbed.co.uk 5:62573be585e9 332 const char *next = arguments;
simon.ford@mbed.co.uk 5:62573be585e9 333 A1 arg1 = parse_arg<A1>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 334 A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
simon.ford@mbed.co.uk 4:5d1359a283bc 335
simon.ford@mbed.co.uk 4:5d1359a283bc 336 (static_cast<T*>(this_ptr)->*member)(arg1,arg2);
simon.ford@mbed.co.uk 4:5d1359a283bc 337 if(result != NULL) {
simon.ford@mbed.co.uk 4:5d1359a283bc 338 result[0] = '\0';
simon.ford@mbed.co.uk 4:5d1359a283bc 339 }
simon.ford@mbed.co.uk 4:5d1359a283bc 340 }
simon.ford@mbed.co.uk 4:5d1359a283bc 341
simon.ford@mbed.co.uk 4:5d1359a283bc 342
simon.ford@mbed.co.uk 5:62573be585e9 343 /* Function rpc_method_caller
simon.ford@mbed.co.uk 4:5d1359a283bc 344 */
simon.ford@mbed.co.uk 8:00a04e5cd407 345 template<class T, typename A1, typename A2, typename A3, void (T::*member)(A1,A2,A3)>
simon.ford@mbed.co.uk 8:00a04e5cd407 346 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 8:00a04e5cd407 347
simon.ford@mbed.co.uk 8:00a04e5cd407 348 const char *next = arguments;
simon.ford@mbed.co.uk 8:00a04e5cd407 349 A1 arg1 = parse_arg<A1>(next_arg(next),&next);
simon.ford@mbed.co.uk 8:00a04e5cd407 350 A2 arg2 = parse_arg<A2>(next_arg(next),&next);
simon.ford@mbed.co.uk 8:00a04e5cd407 351 A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
simon.ford@mbed.co.uk 8:00a04e5cd407 352
simon.ford@mbed.co.uk 8:00a04e5cd407 353 (static_cast<T*>(this_ptr)->*member)(arg1,arg2,arg3);
simon.ford@mbed.co.uk 8:00a04e5cd407 354 if(result != NULL) {
simon.ford@mbed.co.uk 8:00a04e5cd407 355 result[0] = '\0';
simon.ford@mbed.co.uk 8:00a04e5cd407 356 }
simon.ford@mbed.co.uk 8:00a04e5cd407 357 }
simon.ford@mbed.co.uk 8:00a04e5cd407 358
simon.ford@mbed.co.uk 8:00a04e5cd407 359
simon.ford@mbed.co.uk 8:00a04e5cd407 360 /* Function rpc_method_caller
simon.ford@mbed.co.uk 8:00a04e5cd407 361 */
simon.ford@mbed.co.uk 4:5d1359a283bc 362 template<typename R, class T, R (T::*member)()>
simon.ford@mbed.co.uk 5:62573be585e9 363 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 364 R res = (static_cast<T*>(this_ptr)->*member)();
simon.ford@mbed.co.uk 4:5d1359a283bc 365 if(result != NULL) {
simon.ford@mbed.co.uk 4:5d1359a283bc 366 write_result<R>(res, result);
simon.ford@mbed.co.uk 4:5d1359a283bc 367 }
simon.ford@mbed.co.uk 4:5d1359a283bc 368 }
simon.ford@mbed.co.uk 4:5d1359a283bc 369
simon.ford@mbed.co.uk 4:5d1359a283bc 370
simon.ford@mbed.co.uk 5:62573be585e9 371 /* Function rpc_method_caller
simon.ford@mbed.co.uk 4:5d1359a283bc 372 */
simon.ford@mbed.co.uk 4:5d1359a283bc 373 template<typename R, class T, typename A1, R (T::*member)(A1)>
simon.ford@mbed.co.uk 5:62573be585e9 374 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 375
simon.ford@mbed.co.uk 5:62573be585e9 376 const char *next = arguments;
simon.ford@mbed.co.uk 5:62573be585e9 377 A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
simon.ford@mbed.co.uk 4:5d1359a283bc 378
simon.ford@mbed.co.uk 4:5d1359a283bc 379 R res = (static_cast<T*>(this_ptr)->*member)(arg1);
simon.ford@mbed.co.uk 4:5d1359a283bc 380 if(result != NULL) {
simon.ford@mbed.co.uk 4:5d1359a283bc 381 write_result<R>(res, result);
simon.ford@mbed.co.uk 4:5d1359a283bc 382 }
simon.ford@mbed.co.uk 4:5d1359a283bc 383 }
simon.ford@mbed.co.uk 4:5d1359a283bc 384
simon.ford@mbed.co.uk 4:5d1359a283bc 385
simon.ford@mbed.co.uk 5:62573be585e9 386 /* Function rpc_method_caller
simon.ford@mbed.co.uk 4:5d1359a283bc 387 */
simon.ford@mbed.co.uk 4:5d1359a283bc 388 template<typename R, class T, typename A1, typename A2, R (T::*member)(A1,A2)>
simon.ford@mbed.co.uk 5:62573be585e9 389 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 4:5d1359a283bc 390
simon.ford@mbed.co.uk 5:62573be585e9 391 const char *next = arguments;
simon.ford@mbed.co.uk 5:62573be585e9 392 A1 arg1 = parse_arg<A1>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 393 A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
simon.ford@mbed.co.uk 4:5d1359a283bc 394
simon.ford@mbed.co.uk 4:5d1359a283bc 395 R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2);
simon.ford@mbed.co.uk 4:5d1359a283bc 396 if(result != NULL) {
simon.ford@mbed.co.uk 4:5d1359a283bc 397 write_result<R>(res, result);
simon.ford@mbed.co.uk 4:5d1359a283bc 398 }
simon.ford@mbed.co.uk 4:5d1359a283bc 399 }
simon.ford@mbed.co.uk 4:5d1359a283bc 400
simon.ford@mbed.co.uk 5:62573be585e9 401
simon.ford@mbed.co.uk 5:62573be585e9 402 /* Function rpc_method_caller
simon.ford@mbed.co.uk 5:62573be585e9 403 */
simon.ford@mbed.co.uk 5:62573be585e9 404 template<typename R, class T, typename A1, typename A2, typename A3, R (T::*member)(A1,A2,A3)>
simon.ford@mbed.co.uk 5:62573be585e9 405 void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
simon.ford@mbed.co.uk 5:62573be585e9 406
simon.ford@mbed.co.uk 5:62573be585e9 407 const char *next = arguments;
simon.ford@mbed.co.uk 5:62573be585e9 408 A1 arg1 = parse_arg<A1>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 409 A2 arg2 = parse_arg<A2>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 410 A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
simon.ford@mbed.co.uk 5:62573be585e9 411
simon.ford@mbed.co.uk 5:62573be585e9 412 R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2,arg3);
simon.ford@mbed.co.uk 5:62573be585e9 413 if(result != NULL) {
simon.ford@mbed.co.uk 5:62573be585e9 414 write_result<R>(res, result);
simon.ford@mbed.co.uk 5:62573be585e9 415 }
simon.ford@mbed.co.uk 5:62573be585e9 416 }
simon.ford@mbed.co.uk 5:62573be585e9 417
simon.ford@mbed.co.uk 5:62573be585e9 418
simon.ford@mbed.co.uk 5:62573be585e9 419 /* Function rpc_function caller
simon.ford@mbed.co.uk 5:62573be585e9 420 */
simon.ford@mbed.co.uk 5:62573be585e9 421 template<typename R, R (*func)()>
simon.ford@mbed.co.uk 5:62573be585e9 422 void rpc_function_caller(const char *arguments, char *result) {
simon.ford@mbed.co.uk 5:62573be585e9 423 R res = (*func)();
simon.ford@mbed.co.uk 5:62573be585e9 424 if(result != NULL) {
simon.ford@mbed.co.uk 5:62573be585e9 425 write_result<R>(res, result);
simon.ford@mbed.co.uk 5:62573be585e9 426 }
simon.ford@mbed.co.uk 5:62573be585e9 427 }
simon.ford@mbed.co.uk 5:62573be585e9 428
simon.ford@mbed.co.uk 5:62573be585e9 429
simon.ford@mbed.co.uk 5:62573be585e9 430 /* Function rpc_function caller
simon.ford@mbed.co.uk 5:62573be585e9 431 */
simon.ford@mbed.co.uk 5:62573be585e9 432 template<typename R, typename A1, R (*func)(A1)>
simon.ford@mbed.co.uk 5:62573be585e9 433 void rpc_function_caller(const char *arguments, char *result) {
simon.ford@mbed.co.uk 5:62573be585e9 434 A1 arg1 = parse_arg<A1>(next_arg(arguments),NULL);
simon.ford@mbed.co.uk 5:62573be585e9 435 R res = (*func)(arg1);
simon.ford@mbed.co.uk 5:62573be585e9 436 if(result != NULL) {
simon.ford@mbed.co.uk 5:62573be585e9 437 write_result<R>(res, result);
simon.ford@mbed.co.uk 5:62573be585e9 438 }
simon.ford@mbed.co.uk 5:62573be585e9 439 }
simon.ford@mbed.co.uk 5:62573be585e9 440
simon.ford@mbed.co.uk 5:62573be585e9 441
simon.ford@mbed.co.uk 5:62573be585e9 442 /* Function rpc_function caller
simon.ford@mbed.co.uk 5:62573be585e9 443 */
simon.ford@mbed.co.uk 5:62573be585e9 444 template<typename R, typename A1, typename A2, R (*func)(A1,A2)>
simon.ford@mbed.co.uk 5:62573be585e9 445 void rpc_function_caller(const char *arguments, char *result) {
simon.ford@mbed.co.uk 5:62573be585e9 446
simon.ford@mbed.co.uk 5:62573be585e9 447 const char *next = arguments;
simon.ford@mbed.co.uk 5:62573be585e9 448 A1 arg1 = parse_arg<A1>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 449 A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
simon.ford@mbed.co.uk 5:62573be585e9 450
simon.ford@mbed.co.uk 5:62573be585e9 451 R res = (*func)(arg1,arg2);
simon.ford@mbed.co.uk 5:62573be585e9 452 if(result != NULL) {
simon.ford@mbed.co.uk 5:62573be585e9 453 write_result<R>(res, result);
simon.ford@mbed.co.uk 5:62573be585e9 454 }
simon.ford@mbed.co.uk 5:62573be585e9 455 }
simon.ford@mbed.co.uk 5:62573be585e9 456
simon.ford@mbed.co.uk 5:62573be585e9 457
simon.ford@mbed.co.uk 5:62573be585e9 458 /* Function rpc_function caller
simon.ford@mbed.co.uk 5:62573be585e9 459 */
simon.ford@mbed.co.uk 5:62573be585e9 460 template<typename R, typename A1, typename A2, typename A3, R (*func)(A1,A2,A3)>
simon.ford@mbed.co.uk 5:62573be585e9 461 void rpc_function_caller(const char *arguments, char *result) {
simon.ford@mbed.co.uk 5:62573be585e9 462
simon.ford@mbed.co.uk 5:62573be585e9 463 const char *next = arguments;
simon.ford@mbed.co.uk 5:62573be585e9 464 A1 arg1 = parse_arg<A1>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 465 A2 arg2 = parse_arg<A2>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 466 A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
simon.ford@mbed.co.uk 5:62573be585e9 467
simon.ford@mbed.co.uk 5:62573be585e9 468 R res = (*func)(arg1,arg2,arg3);
simon.ford@mbed.co.uk 5:62573be585e9 469 if(result != NULL) {
simon.ford@mbed.co.uk 5:62573be585e9 470 write_result<R>(res, result);
simon.ford@mbed.co.uk 5:62573be585e9 471 }
simon.ford@mbed.co.uk 5:62573be585e9 472 }
simon.ford@mbed.co.uk 5:62573be585e9 473
simon.ford@mbed.co.uk 5:62573be585e9 474
simon.ford@mbed.co.uk 5:62573be585e9 475 /* Function rpc_function caller
simon.ford@mbed.co.uk 5:62573be585e9 476 */
simon.ford@mbed.co.uk 5:62573be585e9 477 template<typename R, typename A1, typename A2, typename A3, typename A4, R (*func)(A1,A2,A3,A4)>
simon.ford@mbed.co.uk 5:62573be585e9 478 void rpc_function_caller(const char *arguments, char *result) {
simon.ford@mbed.co.uk 5:62573be585e9 479
simon.ford@mbed.co.uk 5:62573be585e9 480 const char *next = arguments;
simon.ford@mbed.co.uk 5:62573be585e9 481 A1 arg1 = parse_arg<A1>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 482 A2 arg2 = parse_arg<A2>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 483 A3 arg3 = parse_arg<A3>(next_arg(next),&next);
simon.ford@mbed.co.uk 5:62573be585e9 484 A4 arg4 = parse_arg<A4>(next_arg(next),NULL);
simon.ford@mbed.co.uk 5:62573be585e9 485
simon.ford@mbed.co.uk 5:62573be585e9 486 R res = (*func)(arg1,arg2,arg3,arg4);
simon.ford@mbed.co.uk 5:62573be585e9 487 if(result != NULL) {
simon.ford@mbed.co.uk 5:62573be585e9 488 write_result<R>(res, result);
simon.ford@mbed.co.uk 5:62573be585e9 489 }
simon.ford@mbed.co.uk 5:62573be585e9 490 }
simon.ford@mbed.co.uk 5:62573be585e9 491
simon.ford@mbed.co.uk 5:62573be585e9 492
simon.ford@mbed.co.uk 4:5d1359a283bc 493 struct rpc_method {
simon.ford@mbed.co.uk 4:5d1359a283bc 494 const char *name;
simon.ford@mbed.co.uk 5:62573be585e9 495 typedef void (*caller_t)(Base*, const char*, char*);
simon.ford@mbed.co.uk 5:62573be585e9 496 typedef const struct rpc_method *(*super_t)(Base*);
simon.ford@mbed.co.uk 5:62573be585e9 497 union {
simon.ford@mbed.co.uk 5:62573be585e9 498 caller_t caller;
simon.ford@mbed.co.uk 5:62573be585e9 499 super_t super;
simon.ford@mbed.co.uk 5:62573be585e9 500 };
simon.ford@mbed.co.uk 4:5d1359a283bc 501 };
simon.ford@mbed.co.uk 5:62573be585e9 502
simon.ford@mbed.co.uk 5:62573be585e9 503 template<class C>
simon.ford@mbed.co.uk 5:62573be585e9 504 const struct rpc_method *rpc_super(Base *this_ptr) {
simon.ford@mbed.co.uk 5:62573be585e9 505 return static_cast<C*>(this_ptr)->C::get_rpc_methods();
simon.ford@mbed.co.uk 5:62573be585e9 506 }
simon.ford@mbed.co.uk 5:62573be585e9 507
simon.ford@mbed.co.uk 4:5d1359a283bc 508 #define RPC_METHOD_END { NULL, NULL }
simon.ford@mbed.co.uk 5:62573be585e9 509 #define RPC_METHOD_SUPER(C) { NULL, (rpc_method::caller_t)(rpc_method::super_t)rpc_super<C> }
simon.ford@mbed.co.uk 4:5d1359a283bc 510
simon.ford@mbed.co.uk 4:5d1359a283bc 511 /* Function rpc
simon.ford@mbed.co.uk 4:5d1359a283bc 512 * Parse a string describing a call and then do it
simon.ford@mbed.co.uk 4:5d1359a283bc 513 *
simon.ford@mbed.co.uk 4:5d1359a283bc 514 * Variables
simon.ford@mbed.co.uk 4:5d1359a283bc 515 * call - A pointer to a string describing the call, which has
simon.ford@mbed.co.uk 4:5d1359a283bc 516 * the form /object/method arg ... argn. Arguments are
simon.ford@mbed.co.uk 4:5d1359a283bc 517 * delimited by space characters, and the string is terminated
simon.ford@mbed.co.uk 4:5d1359a283bc 518 * by a null character.
simon.ford@mbed.co.uk 4:5d1359a283bc 519 * result - A pointer to an array to write the result into.
simon.ford@mbed.co.uk 4:5d1359a283bc 520 */
simon.ford@mbed.co.uk 4:5d1359a283bc 521 bool rpc(const char *buf, char *result = 0);
simon.ford@mbed.co.uk 4:5d1359a283bc 522
simon.ford@mbed.co.uk 5:62573be585e9 523
simon.ford@mbed.co.uk 4:5d1359a283bc 524 } /* namespace mbed */
simon.ford@mbed.co.uk 4:5d1359a283bc 525
simon.ford@mbed.co.uk 4:5d1359a283bc 526 #endif