00001 #include "../base/libconfig/libconfig.h++"
00002 #include <itpp/itbase.h>
00003 #include <itpp/itmex.h>
00004 #include <stdlib.h>
00005 
00006 using namespace itpp;
00007 using namespace std;
00008 using namespace libconfig;
00009 
00011 class UImxArray : public Config {
00012 public:
00014         UImxArray ( const mxArray *mxarray ) : Config() {
00015                 Setting & setting = this->getRoot(); 
00016                 if ( !mxIsStruct ( mxarray ) ) {
00017                         mexErrMsgTxt ( "Given mxArray is not a struct." );
00018                 };
00019                 
00020                 fillGroup ( setting, mxarray );
00021                 setAutoConvert ( true );
00022         }
00023         UImxArray() : Config() {
00024                 setAutoConvert ( true );
00025         }
00027         void addList ( const mxArray *mxarray, const char* name ) {
00028                 Setting & setting = this->getRoot(); 
00029                 Setting & child = setting.add ( name, Setting::TypeList );
00030                 fillList ( child, mxarray );
00031         }
00033         void addGroup ( const mxArray *mxarray, const char* name ) {
00034                 Setting & setting = this->getRoot(); 
00035                 Setting & child = setting.add ( name, Setting::TypeGroup );
00036                 fillGroup ( child, mxarray );
00037         }
00039         operator Setting&() {
00040                 return getRoot();
00041         }
00042 private:
00043         void storeNumeric ( Setting &setting, const mxArray *value, string key = "" ) {
00044                 
00045                 if ( !mxIsNumeric ( value ) ) {
00046                         mexErrMsgTxt ( "Given mxArray is not numeric." );
00047                 };
00048                 mat val = mxArray2mat ( value );
00049                 if ( ( val.rows() == 1 ) && ( val.cols() == 1 ) ) {
00050                         Setting &child = ( key == "" ) ? setting.add ( Setting::TypeFloat )
00051                                          : setting.add ( key, Setting::TypeFloat );
00052                         child = val ( 0, 0 );
00053                 } else {
00054                         Setting &child = ( key == "" ) ? setting.add ( Setting::TypeList )
00055                                          : setting.add ( key, Setting::TypeList );
00056                         Setting &label = child.add ( Setting::TypeString );
00057                         label = "matrix";
00058                         Setting &rows = child.add ( Setting::TypeInt );
00059                         Setting &cols = child.add ( Setting::TypeInt );
00060                         Setting &elements = child.add ( Setting::TypeArray );
00061                         cols = val.cols();
00062                         rows = val.rows();
00063                         for ( int i = 0; i < val.rows(); i++ ) {
00064                                 for ( int j = 0; j < val.cols(); j++ ) {
00065                                         Setting &el = elements.add ( Setting::TypeFloat );
00066                                         el = val ( i, j );
00067                                 }
00068                         }
00069                 }
00070         }
00071 
00072         void fillGroup ( Setting &setting, const mxArray *mxarray ) {
00073                 if ( !mxIsStruct ( mxarray ) ) {
00074                         mexErrMsgTxt ( "Given mxArray is not a struct." );
00075                 };
00076                 for ( int i = 0; i < mxGetNumberOfFields ( mxarray ); i++ ) {
00077                         const char *key = mxGetFieldNameByNumber ( mxarray, i );
00078                         mxArray *value = mxGetField ( mxarray, 0, key );
00079                         if ( mxIsChar ( value ) ) {
00080                                 Setting &child = setting.add ( key, Setting::TypeString );
00081                                 child = mxArray2string ( value );
00082                         }
00083                         if ( mxIsLogical ( value ) ) {
00084                                 Setting &child = setting.add ( key, Setting::TypeBoolean );
00085                                 child = ( bool ) mxArray2bin ( value );
00086                         }
00087                         if ( mxIsStruct ( value ) ) {
00088                                 Setting &child = setting.add ( key, Setting::TypeGroup );
00089                                 fillGroup ( child, value );
00090                         }
00091                         if ( mxIsCell ( value ) ) {
00092                                 Setting &child = setting.add ( key, Setting::TypeList );
00093                                 fillList ( child, value );
00094                         }
00095                         if ( mxIsNumeric ( value ) ) {
00096                                 storeNumeric ( setting, value, ( string ) key );
00097                         }
00098                 }
00099         }
00100 
00101         void fillList ( Setting &setting, const mxArray *mxarray ) {
00102                 if ( !mxIsCell ( mxarray ) ) {
00103                         mexErrMsgTxt ( "Given mxArray is not a cell." );
00104                 };
00105                 for ( uint i = 0; i < mxGetNumberOfElements ( mxarray ); i++ ) {
00106                         mxArray *value = mxGetCell ( mxarray, i );
00107                         if ( mxIsChar ( value ) ) {
00108                                 Setting &child = setting.add ( Setting::TypeString );
00109                                 child = mxArray2string ( value );
00110                         }
00111                         if ( mxIsLogical ( value ) ) {
00112                                 Setting &child = setting.add ( Setting::TypeBoolean );
00113                                 child = ( bool ) mxArray2bin ( value );
00114                         }
00115                         if ( mxIsStruct ( value ) ) {
00116                                 Setting &child = setting.add ( Setting::TypeGroup );
00117                                 fillGroup ( child, value );
00118                         }
00119                         if ( mxIsCell ( value ) ) {
00120                                 Setting &child = setting.add ( Setting::TypeList );
00121                                 fillList ( child, value );
00122                         }
00123                         if ( mxIsNumeric ( value ) ) {
00124                                 storeNumeric ( setting, value );
00125                         }
00126                 }
00127         }
00128 };