00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <rosmatlab/param.h>
00030 #include <rosmatlab/exception.h>
00031
00032 #include <rosmatlab/options.h>
00033 #include <ros/param.h>
00034
00035 #include <mex.h>
00036
00037 namespace rosmatlab {
00038 namespace param {
00039
00040 using namespace XmlRpc;
00041
00042 mxArray *toMatlab(XmlRpcValue& value) {
00043 mxArray *array = 0;
00044
00045 switch(value.getType()) {
00046 case XmlRpcValue::TypeBoolean:
00047 array = mxCreateLogicalScalar(static_cast<bool>(value));
00048 break;
00049
00050 case XmlRpcValue::TypeInt:
00051 array = mxCreateDoubleScalar(static_cast<int>(value));
00052 break;
00053
00054 case XmlRpcValue::TypeDouble:
00055 array = mxCreateDoubleScalar(static_cast<double>(value));
00056 break;
00057
00058 case XmlRpcValue::TypeString:
00059 array = mxCreateString(static_cast<std::string>(value).c_str());
00060 break;
00061
00062 case XmlRpcValue::TypeDateTime:
00063
00064 break;
00065
00066 case XmlRpcValue::TypeBase64:
00067
00068 break;
00069
00070 case XmlRpcValue::TypeArray:
00071 {
00072 mxArray *a = mxCreateCellMatrix(value.size(), 1);
00073 for(int i = 0; i < value.size(); ++i) {
00074 mxSetCell(a, i, toMatlab(value[i]));
00075 }
00076 array = a;
00077 }
00078 break;
00079
00080 case XmlRpcValue::TypeStruct:
00081 {
00082 std::vector<const char *> fieldnames;
00083 XmlRpcValue::iterator it;
00084 for(it = value.begin(); it != value.end(); ++it) {
00085 fieldnames.push_back(it->first.c_str());
00086 }
00087 mxArray *s = mxCreateStructMatrix(1, 1, fieldnames.size(), fieldnames.data());
00088 for(it = value.begin(); it != value.end(); ++it) {
00089 mxSetField(s, 0, it->first.c_str(), toMatlab(it->second));
00090 }
00091 array = s;
00092 }
00093 break;
00094
00095 default:
00096 break;
00097 }
00098
00099 return array;
00100 }
00101
00102 void fromMatlabBool(const mxArray *array, XmlRpcValue& value) {
00103 size_t n = mxGetNumberOfElements(array);
00104 mxLogical *data = mxGetLogicals(array);
00105
00106 if (n == 1) {
00107 value = XmlRpcValue(data[0]);
00108 } else {
00109 value.setSize(n);
00110 for(int i = 0; i < n; ++i) value[i] = data[i];
00111 }
00112 }
00113
00114 void fromMatlabString(const mxArray *array, XmlRpcValue& value) {
00115 size_t n = mxGetNumberOfElements(array);
00116 std::vector<char> buffer(n + 1);
00117 if (mxGetString(array, buffer.data(), buffer.size()) == 0) {
00118 value = buffer.data();
00119 }
00120 }
00121
00122 template <typename From, typename To>
00123 void fromMatlabNumeric(const mxArray *array, XmlRpcValue& value) {
00124 size_t n = mxGetNumberOfElements(array);
00125 const From *data = static_cast<const From *>(mxGetData(array));
00126
00127 if (n == 1) {
00128 value = static_cast<To>(*data);
00129 } else {
00130 value.setSize(n);
00131 for(int i = 0; i < n; ++i) value[i] = static_cast<To>(data[i]);
00132 }
00133 }
00134
00135 bool fromMatlab(const mxArray *array, XmlRpcValue& value) {
00136
00137 value.clear();
00138
00139 switch(mxGetClassID(array)) {
00140 case mxCELL_CLASS:
00141
00142 break;
00143
00144 case mxSTRUCT_CLASS:
00145
00146 break;
00147
00148 case mxLOGICAL_CLASS:
00149 fromMatlabBool(array, value);
00150 break;
00151
00152 case mxCHAR_CLASS:
00153 fromMatlabString(array, value);
00154 break;
00155
00156 case mxDOUBLE_CLASS:
00157 fromMatlabNumeric<double, double>(array, value);
00158 break;
00159
00160 case mxSINGLE_CLASS:
00161 fromMatlabNumeric<float, double>(array, value);
00162 break;
00163
00164 case mxINT8_CLASS:
00165 fromMatlabNumeric<int8_t, int>(array, value);
00166 break;
00167
00168 case mxUINT8_CLASS:
00169 fromMatlabNumeric<uint8_t, int>(array, value);
00170 break;
00171
00172 case mxINT16_CLASS:
00173 fromMatlabNumeric<int16_t, int>(array, value);
00174 break;
00175
00176 case mxUINT16_CLASS:
00177 fromMatlabNumeric<uint16_t, int>(array, value);
00178 break;
00179
00180 case mxINT32_CLASS:
00181 fromMatlabNumeric<int32_t, int>(array, value);
00182 break;
00183
00184 case mxUINT32_CLASS:
00185 fromMatlabNumeric<uint32_t, int>(array, value);
00186 break;
00187
00188 case mxINT64_CLASS:
00189 fromMatlabNumeric<int64_t, int>(array, value);
00190 break;
00191
00192 case mxUINT64_CLASS:
00193 fromMatlabNumeric<uint64_t, int>(array, value);
00194 break;
00195
00196 case mxFUNCTION_CLASS:
00197
00198 break;
00199
00200 default:
00201 break;
00202 }
00203
00204 return value.valid();
00205 }
00206
00207 void get(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00208 {
00209 std::string key;
00210 XmlRpcValue value;
00211
00212 if (nrhs > 0) key = Options::getString(prhs[0]);
00213
00214
00215 try {
00216 if (!ros::param::get(key, value)) {
00217 plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
00218 return;
00219 }
00220 } catch (ros::InvalidNameException& e) {
00221 throw Exception("ros.param.get", e.what());
00222 }
00223
00224
00225 plhs[0] = toMatlab(value);
00226 if (!plhs[0]) {
00227 throw Exception("ros.param.get", "Could not convert the parameter value of " + key + " to Matlab (unknown type)");
00228 plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
00229 return;
00230 }
00231
00232 return;
00233 }
00234
00235 void set(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00236 {
00237 if (nrhs < 2) {
00238 throw ArgumentException("ros.param.set", 2);
00239 }
00240
00241 std::string key = Options::getString(prhs[0]);
00242 XmlRpcValue value;
00243
00244
00245 if (!fromMatlab(prhs[1], value)) {
00246 throw Exception("ros.param.set", "Could not convert the parameter value for " + key + " to a XmlRpcValue");
00247 return;
00248 }
00249
00250
00251 try {
00252 ros::param::set(key, value);
00253 } catch (ros::InvalidNameException& e) {
00254 throw Exception("ros.param.set", e.what());
00255 }
00256 }
00257
00258 void del(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00259 {
00260 if (nrhs < 1) {
00261 throw ArgumentException("ros.param.delete", 1);
00262 }
00263
00264 std::string key = Options::getString(prhs[0]);
00265 bool result = ros::param::del(key);
00266 if (nlhs > 0) plhs[0] = mxCreateLogicalScalar(result);
00267 }
00268
00269 void has(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00270 {
00271 if (nrhs < 1) {
00272 throw ArgumentException("ros.param.has", 1);
00273 }
00274
00275 std::string key = Options::getString(prhs[0]);
00276 plhs[0] = mxCreateLogicalScalar(ros::param::has(key));
00277 }
00278
00279 }
00280 }