mex_parser.h
00001 #ifndef MXPARSE_H 00002 #define MXPARSE_H 00003 00004 00005 #include "base/libconfig/lib/libconfig.h++" 00006 #include <itpp/itbase.h> 00007 #include <itpp/itmex.h> 00008 #include <stdlib.h> 00009 00010 00011 using namespace itpp; 00012 using namespace std; 00013 using namespace libconfig; 00014 00016 class UImxArray : public Config { 00017 public: 00019 UImxArray ( const mxArray *mxarray ) : Config() { 00020 Setting & setting = this->getRoot(); //setting is a group 00021 if ( !mxIsStruct ( mxarray ) ) { 00022 mexErrMsgTxt ( "Given mxArray is not a struct." ); 00023 }; 00024 00025 //mexCallMATLAB(0, NULL, 1, (mxArray **) &mxarray, "dump"); 00026 fillGroup ( setting, mxarray ); 00027 setAutoConvert ( true ); 00028 } 00029 UImxArray() : Config() { 00030 setAutoConvert ( true ); 00031 } 00033 void addList ( const mxArray *mxarray, const char* name ) { 00034 Setting & setting = this->getRoot(); //setting is a group 00035 Setting & child = setting.add ( name, Setting::TypeList ); 00036 fillList ( child, mxarray ); 00037 } 00039 void addGroup ( const mxArray *mxarray, const char* name ) { 00040 Setting & setting = this->getRoot(); //setting is a group 00041 Setting & child = setting.add ( name, Setting::TypeGroup ); 00042 fillGroup ( child, mxarray ); 00043 } 00045 operator Setting&() { 00046 return getRoot(); 00047 } 00048 00049 private: 00050 void storeNumeric ( Setting &setting, const mxArray *value, string key = "" ) { 00051 //TODO: integer matrices 00052 if ( !mxIsNumeric ( value ) ) { 00053 mexErrMsgTxt ( "Given mxArray is not numeric." ); 00054 }; 00055 //treat empty matrices independently 00056 mat val; 00057 if ( mxGetM ( value ) > 0 && mxGetN(value)>0) { 00058 val = mxArray2mat ( value ); 00059 } 00060 if ( ( val.rows() == 1 ) && ( val.cols() == 1 ) ) { 00061 Setting &child = ( key == "" ) ? setting.add ( Setting::TypeFloat ) 00062 : setting.add ( key, Setting::TypeFloat ); 00063 child = val ( 0, 0 ); 00064 } else { 00065 Setting &child = ( key == "" ) ? setting.add ( Setting::TypeList ) 00066 : setting.add ( key, Setting::TypeList ); 00067 Setting &label = child.add ( Setting::TypeString ); 00068 label = "matrix"; 00069 Setting &rows = child.add ( Setting::TypeInt ); 00070 Setting &cols = child.add ( Setting::TypeInt ); 00071 Setting &elements = child.add ( Setting::TypeArray ); 00072 cols = val.cols(); 00073 rows = val.rows(); 00074 for ( int i = 0; i < val.rows(); i++ ) { 00075 for ( int j = 0; j < val.cols(); j++ ) { 00076 Setting &el = elements.add ( Setting::TypeFloat ); 00077 el = val ( i, j ); 00078 } 00079 } 00080 } 00081 } 00082 00083 void fillGroup ( Setting &setting, const mxArray *mxarray ) { 00084 if ( !mxIsStruct ( mxarray ) ) { 00085 mexErrMsgTxt ( "Given mxArray is not a struct." ); 00086 }; 00087 for ( int i = 0; i < mxGetNumberOfFields ( mxarray ); i++ ) { 00088 const char *key = mxGetFieldNameByNumber ( mxarray, i ); 00089 mxArray *value = mxGetField ( mxarray, 0, key ); 00090 if ( mxIsChar ( value ) ) { 00091 Setting &child = setting.add ( key, Setting::TypeString ); 00092 child = mxArray2string ( value ); 00093 } else { 00094 if ( mxIsLogical ( value ) ) { 00095 Setting &child = setting.add ( key, Setting::TypeBoolean ); 00096 child = ( bool ) mxArray2bin ( value ); 00097 } else { 00098 if ( mxIsStruct ( value ) ) { 00099 Setting &child = setting.add ( key, Setting::TypeGroup ); 00100 fillGroup ( child, value ); 00101 } else { 00102 if ( mxIsCell ( value ) ) { 00103 Setting &child = setting.add ( key, Setting::TypeList ); 00104 fillList ( child, value ); 00105 } else { 00106 if ( mxIsNumeric ( value ) ) { 00107 storeNumeric ( setting, value, ( string ) key ); 00108 } else { 00109 // it is neither of above - treat it as an address 00110 // if (mxIsObject(value)){ <== should be tested but it is broken in matlab... 00111 00112 Setting &child = setting.add(key, Setting::TypeInt64); 00113 child = (long long)value; 00114 } 00115 } 00116 } 00117 } 00118 } 00119 } 00120 } 00121 00122 void fillList ( Setting &setting, const mxArray *mxarray ) { 00123 if ( !mxIsCell ( mxarray ) ) { 00124 mexErrMsgTxt ( "Given mxArray is not a cell." ); 00125 }; 00126 for ( unsigned int i = 0; i < ( unsigned int ) mxGetNumberOfElements ( mxarray ); i++ ) { 00127 mxArray *value = mxGetCell ( mxarray, i ); 00128 if ( mxIsChar ( value ) ) { 00129 Setting &child = setting.add ( Setting::TypeString ); 00130 child = mxArray2string ( value ); 00131 } 00132 if ( mxIsLogical ( value ) ) { 00133 Setting &child = setting.add ( Setting::TypeBoolean ); 00134 child = ( bool ) mxArray2bin ( value ); 00135 } 00136 if ( mxIsStruct ( value ) ) { 00137 Setting &child = setting.add ( Setting::TypeGroup ); 00138 fillGroup ( child, value ); 00139 } 00140 if ( mxIsCell ( value ) ) { 00141 Setting &child = setting.add ( Setting::TypeList ); 00142 fillList ( child, value ); 00143 } 00144 if ( mxIsNumeric ( value ) ) { 00145 storeNumeric ( setting, value ); 00146 } 00147 } 00148 } 00149 00150 public: 00152 static mxArray * create_mxArray( const Setting &setting ) 00153 { 00154 return group2mxstruct ( setting ); 00155 } 00156 00158 mxArray * create_mxArray( ) 00159 { 00160 return group2mxstruct ( *this ); 00161 } 00162 00163 private: 00165 static mxArray* array2mxvector ( const Setting &setting ) { 00166 if ( !setting.isArray() ) mexErrMsgTxt ( "Given setting is not an array" ); 00167 mxArray *result = mxCreateDoubleMatrix ( 1, setting.getLength(), mxREAL ); 00168 double *elements = mxGetPr ( result ); 00169 for ( int i = 0; i < setting.getLength(); i++ ) { 00170 if ( setting.getType() == Setting::TypeInt ) { //TODO: tady je chyba -- zaporna cisla nejsou TypeInt 00171 elements[i] = ( int ) setting[i]; 00172 } else { 00173 elements[i] = setting[i]; 00174 } 00175 } 00176 return result; 00177 } 00178 00180 static mxArray* list2mxmatrix ( const Setting &setting ) { 00181 if ( !setting.isList() || ( strcmp ( "matrix", setting[0] ) != 0 ) ) 00182 mexErrMsgTxt ( "Given setting is not a matrix" ); 00183 int rows = setting[1]; 00184 int cols = setting[2]; 00185 if ( setting[3].getLength() != rows*cols ) 00186 mexErrMsgTxt ( "Matrix elements do not fit to rows*cols" ); 00187 double *elements = new double[rows*cols]; 00188 for ( int i = 0; i < rows*cols; i++ ) { 00189 elements[i] = setting[3][i]; 00190 } 00191 mat &m = * ( new mat ( elements, rows, cols ) ); 00192 mxArray *result = mxCreateDoubleMatrix ( rows, cols, mxREAL ); 00193 mat2mxArray ( m, result ); 00194 delete &m; 00195 delete [] elements; 00196 return result; 00197 } 00198 00200 static mxArray* group2mxstruct ( const Setting &setting ) { 00201 if ( !setting.isGroup() ) mexErrMsgTxt ( "Given setting is not a group." ); 00202 const char ** keys = new const char*[setting.getLength() ]; 00203 for ( int i = 0; i < setting.getLength(); i++ ) { 00204 keys[i] = setting[i].getName(); 00205 } 00206 mxArray *result = mxCreateStructMatrix ( 1, 1, setting.getLength(), keys ); 00207 delete keys; 00208 for ( int i = 0; i < setting.getLength(); i++ ) { 00209 Setting &value = setting[i]; 00210 mxArray *old = mxGetFieldByNumber ( result, 0, i ); 00211 if ( old ) mxDestroyArray ( old ); 00212 switch ( value.getType() ) { 00213 case Setting::TypeString: 00214 mxSetFieldByNumber ( result, 0, i, mxCreateString ( value ) ); 00215 break; 00216 case Setting::TypeBoolean: 00217 mxSetFieldByNumber ( result, 0, i, mxCreateLogicalScalar ( value ) ); 00218 break; 00219 case Setting::TypeGroup: 00220 mxSetFieldByNumber ( result, 0, i, group2mxstruct ( value ) ); 00221 break; 00222 case Setting::TypeList: 00223 mxSetFieldByNumber ( result, 0, i, list2mxcell ( value ) ); 00224 break; 00225 case Setting::TypeArray: 00226 mxSetFieldByNumber ( result, 0, i, array2mxvector ( value ) ); 00227 break; 00228 case Setting::TypeInt: 00229 case Setting::TypeInt64: 00230 mxSetFieldByNumber ( result, 0, i, mxCreateDoubleScalar ( ( int ) value ) ); 00231 break; 00232 case Setting::TypeFloat: 00233 mxSetFieldByNumber ( result, 0, i, mxCreateDoubleScalar ( value ) ); 00234 break; 00235 default: 00236 //this should never happen 00237 mexErrMsgTxt ( "Unknown type of a setting." ); 00238 } 00239 } 00240 return result; 00241 00242 } 00244 static mxArray* list2mxcell ( const Setting &setting ) { 00245 if ( !setting.isList() ) mexErrMsgTxt ( "Given setting is not a list." ); 00246 if ( setting.getLength() == 0 ) { 00247 mxArray *result = mxCreateCellMatrix ( 1, 0 ); 00248 return result; 00249 } 00250 00251 if ( ( setting[0].getType() == Setting::TypeString ) ) { 00252 string s = ( setting[0] ); 00253 if ( s == "matrix" ) { 00254 return list2mxmatrix ( setting ); 00255 } 00256 } 00257 mxArray *result = mxCreateCellMatrix ( 1, setting.getLength() ); 00258 for ( int i = 0; i < setting.getLength(); i++ ) { 00259 Setting &value = setting[i]; 00260 mxArray *old = mxGetCell ( result, i ); 00261 if ( old ) mxDestroyArray ( old ); 00262 switch ( value.getType() ) { 00263 case Setting::TypeString: 00264 mxSetCell ( result, i, mxCreateString ( value ) ); 00265 break; 00266 case Setting::TypeBoolean: 00267 mxSetCell ( result, i, mxCreateLogicalScalar ( value ) ); 00268 break; 00269 case Setting::TypeGroup: 00270 mxSetCell ( result, i, group2mxstruct ( value ) ); 00271 break; 00272 case Setting::TypeList: 00273 mxSetCell ( result, i, list2mxcell ( value ) ); 00274 break; 00275 case Setting::TypeArray: 00276 mxSetCell ( result, i, array2mxvector ( value ) ); 00277 break; 00278 case Setting::TypeInt: 00279 case Setting::TypeInt64: 00280 mxSetCell ( result, i, mxCreateDoubleScalar ( ( int ) value ) ); 00281 break; 00282 case Setting::TypeFloat: 00283 mxSetCell ( result, i, mxCreateDoubleScalar ( value ) ); 00284 break; 00285 default: 00286 //this should never happen 00287 mexErrMsgTxt ( "Unknown type of a setting." ); 00288 } 00289 } 00290 return result; 00291 } 00292 }; 00293 00294 #endif //MXPARSE_H
Generated on 2 Dec 2013 for mixpp by 1.4.7