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                 mat val = mxArray2mat ( value );
00054                 if ( ( val.rows() == 1 ) && ( val.cols() == 1 ) ) {
00055                         Setting &child = ( key == "" ) ? setting.add ( Setting::TypeFloat )
00056                                          : setting.add ( key, Setting::TypeFloat );
00057                         child = val ( 0, 0 );
00058                 } else {
00059                         Setting &child = ( key == "" ) ? setting.add ( Setting::TypeList )
00060                                          : setting.add ( key, Setting::TypeList );
00061                         Setting &label = child.add ( Setting::TypeString );
00062                         label = "matrix";
00063                         Setting &rows = child.add ( Setting::TypeInt );
00064                         Setting &cols = child.add ( Setting::TypeInt );
00065                         Setting &elements = child.add ( Setting::TypeArray );
00066                         cols = val.cols();
00067                         rows = val.rows();
00068                         for ( int i = 0; i < val.rows(); i++ ) {
00069                                 for ( int j = 0; j < val.cols(); j++ ) {
00070                                         Setting &el = elements.add ( Setting::TypeFloat );
00071                                         el = val ( i, j );
00072                                 }
00073                         }
00074                 }
00075         }
00076 
00077         void fillGroup ( Setting &setting, const mxArray *mxarray ) {
00078                 if ( !mxIsStruct ( mxarray ) ) {
00079                         mexErrMsgTxt ( "Given mxArray is not a struct." );
00080                 };
00081                 for ( int i = 0; i < mxGetNumberOfFields ( mxarray ); i++ ) {
00082                         const char *key = mxGetFieldNameByNumber ( mxarray, i );
00083                         mxArray *value = mxGetField ( mxarray, 0, key );
00084                         if ( mxIsChar ( value ) ) {
00085                                 Setting &child = setting.add ( key, Setting::TypeString );
00086                                 child = mxArray2string ( value );
00087                         }
00088                         if ( mxIsLogical ( value ) ) {
00089                                 Setting &child = setting.add ( key, Setting::TypeBoolean );
00090                                 child = ( bool ) mxArray2bin ( value );
00091                         }
00092                         if ( mxIsStruct ( value ) ) {
00093                                 Setting &child = setting.add ( key, Setting::TypeGroup );
00094                                 fillGroup ( child, value );
00095                         }
00096                         if ( mxIsCell ( value ) ) {
00097                                 Setting &child = setting.add ( key, Setting::TypeList );
00098                                 fillList ( child, value );
00099                         }
00100                         if ( mxIsNumeric ( value ) ) {
00101                                 storeNumeric ( setting, value, ( string ) key );
00102                         }
00103                 }
00104         }
00105 
00106         void fillList ( Setting &setting, const mxArray *mxarray ) {
00107                 if ( !mxIsCell ( mxarray ) ) {
00108                         mexErrMsgTxt ( "Given mxArray is not a cell." );
00109                 };
00110                 for ( unsigned int i = 0; i < (unsigned int) mxGetNumberOfElements ( mxarray ); i++ ) {
00111                         mxArray *value = mxGetCell ( mxarray, i );
00112                         if ( mxIsChar ( value ) ) {
00113                                 Setting &child = setting.add ( Setting::TypeString );
00114                                 child = mxArray2string ( value );
00115                         }
00116                         if ( mxIsLogical ( value ) ) {
00117                                 Setting &child = setting.add ( Setting::TypeBoolean );
00118                                 child = ( bool ) mxArray2bin ( value );
00119                         }
00120                         if ( mxIsStruct ( value ) ) {
00121                                 Setting &child = setting.add ( Setting::TypeGroup );
00122                                 fillGroup ( child, value );
00123                         }
00124                         if ( mxIsCell ( value ) ) {
00125                                 Setting &child = setting.add ( Setting::TypeList );
00126                                 fillList ( child, value );
00127                         }
00128                         if ( mxIsNumeric ( value ) ) {
00129                                 storeNumeric ( setting, value );
00130                         }
00131                 }
00132         }
00133 };
00134 
00135 #endif //MXPARSE_H