00001 #ifndef MXPARSE_H
00002 #define MXPARSE_H
00003 
00004 
00005 #include "../base/libconfig/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(); 
00021                 if ( !mxIsStruct ( mxarray ) ) {
00022                         mexErrMsgTxt ( "Given mxArray is not a struct." );
00023                 };
00024                 
00025                 fillGroup ( setting, mxarray );
00026                 setAutoConvert ( true );
00027         }
00028         UImxArray() : Config() {
00029                 setAutoConvert ( true );
00030         }
00032         void addList ( const mxArray *mxarray, const char* name ) {
00033                 Setting & setting = this->getRoot(); 
00034                 Setting & child = setting.add ( name, Setting::TypeList );
00035                 fillList ( child, mxarray );
00036         }
00038         void addGroup ( const mxArray *mxarray, const char* name ) {
00039                 Setting & setting = this->getRoot(); 
00040                 Setting & child = setting.add ( name, Setting::TypeGroup );
00041                 fillGroup ( child, mxarray );
00042         }
00044         operator Setting&() {
00045                 return getRoot();
00046         }
00047 private:
00048         void storeNumeric ( Setting &setting, const mxArray *value, string key = "" ) {
00049                 
00050                 if ( !mxIsNumeric ( value ) ) {
00051                         mexErrMsgTxt ( "Given mxArray is not numeric." );
00052                 };
00053                 
00054                 mat val;
00055                 if (mxGetM(value)>0) {
00056                         val = mxArray2mat ( value );
00057                 }
00058                 if ( ( val.rows() == 1 ) && ( val.cols() == 1 ) ) {
00059                         Setting &child = ( key == "" ) ? setting.add ( Setting::TypeFloat )
00060                                          : setting.add ( key, Setting::TypeFloat );
00061                         child = val ( 0, 0 );
00062                 } else {
00063                         Setting &child = ( key == "" ) ? setting.add ( Setting::TypeList )
00064                                          : setting.add ( key, Setting::TypeList );
00065                         Setting &label = child.add ( Setting::TypeString );
00066                         label = "matrix";
00067                         Setting &rows = child.add ( Setting::TypeInt );
00068                         Setting &cols = child.add ( Setting::TypeInt );
00069                         Setting &elements = child.add ( Setting::TypeArray );
00070                         cols = val.cols();
00071                         rows = val.rows();
00072                         for ( int i = 0; i < val.rows(); i++ ) {
00073                                 for ( int j = 0; j < val.cols(); j++ ) {
00074                                         Setting &el = elements.add ( Setting::TypeFloat );
00075                                         el = val ( i, j );
00076                                 }
00077                         }
00078                 }
00079         }
00080 
00081         void fillGroup ( Setting &setting, const mxArray *mxarray ) {
00082                 if ( !mxIsStruct ( mxarray ) ) {
00083                         mexErrMsgTxt ( "Given mxArray is not a struct." );
00084                 };
00085                 for ( int i = 0; i < mxGetNumberOfFields ( mxarray ); i++ ) {
00086                         const char *key = mxGetFieldNameByNumber ( mxarray, i );
00087                         mxArray *value = mxGetField ( mxarray, 0, key );
00088                         if ( mxIsChar ( value ) ) {
00089                                 Setting &child = setting.add ( key, Setting::TypeString );
00090                                 child = mxArray2string ( value );
00091                         }
00092                         if ( mxIsLogical ( value ) ) {
00093                                 Setting &child = setting.add ( key, Setting::TypeBoolean );
00094                                 child = ( bool ) mxArray2bin ( value );
00095                         }
00096                         if ( mxIsStruct ( value ) ) {
00097                                 Setting &child = setting.add ( key, Setting::TypeGroup );
00098                                 fillGroup ( child, value );
00099                         }
00100                         if ( mxIsCell ( value ) ) {
00101                                 Setting &child = setting.add ( key, Setting::TypeList );
00102                                 fillList ( child, value );
00103                         }
00104                         if ( mxIsNumeric ( value ) ) {
00105                                 storeNumeric ( setting, value, ( string ) key );
00106                         }
00107                 }
00108         }
00109 
00110         void fillList ( Setting &setting, const mxArray *mxarray ) {
00111                 if ( !mxIsCell ( mxarray ) ) {
00112                         mexErrMsgTxt ( "Given mxArray is not a cell." );
00113                 };
00114                 for ( unsigned int i = 0; i < (unsigned int) mxGetNumberOfElements ( mxarray ); i++ ) {
00115                         mxArray *value = mxGetCell ( mxarray, i );
00116                         if ( mxIsChar ( value ) ) {
00117                                 Setting &child = setting.add ( Setting::TypeString );
00118                                 child = mxArray2string ( value );
00119                         }
00120                         if ( mxIsLogical ( value ) ) {
00121                                 Setting &child = setting.add ( Setting::TypeBoolean );
00122                                 child = ( bool ) mxArray2bin ( value );
00123                         }
00124                         if ( mxIsStruct ( value ) ) {
00125                                 Setting &child = setting.add ( Setting::TypeGroup );
00126                                 fillGroup ( child, value );
00127                         }
00128                         if ( mxIsCell ( value ) ) {
00129                                 Setting &child = setting.add ( Setting::TypeList );
00130                                 fillList ( child, value );
00131                         }
00132                         if ( mxIsNumeric ( value ) ) {
00133                                 storeNumeric ( setting, value );
00134                         }
00135                 }
00136         }
00137 };
00138 
00139 #endif //MXPARSE_H