#include "../base/libconfig/libconfig.h++" #include #include #include using namespace itpp; using namespace std; using namespace libconfig; //! Class for writing Settings into Matlab's mxArray class UImxArray : public Config { public: //! Build an instance of Config with fields filled from the given \a mxarray UImxArray ( const mxArray *mxarray ) : Config() { Setting & setting = this->getRoot(); //setting is a group if ( !mxIsStruct ( mxarray ) ) { mexErrMsgTxt ( "Given mxArray is not a struct." ); }; //mexCallMATLAB(0, NULL, 1, (mxArray **) &mxarray, "dump"); fillGroup ( setting, mxarray ); setAutoConvert ( true ); } UImxArray() : Config() { setAutoConvert ( true ); } //! Add libconfig's \c list to the structure void addList ( const mxArray *mxarray, const char* name ) { Setting & setting = this->getRoot(); //setting is a group Setting & child = setting.add ( name, Setting::TypeList ); fillList ( child, mxarray ); } //! Add libconfig's \c group to the structure void addGroup ( const mxArray *mxarray, const char* name ) { Setting & setting = this->getRoot(); //setting is a group Setting & child = setting.add ( name, Setting::TypeGroup ); fillGroup ( child, mxarray ); } //! Operator for more convenient access to this Confic operator Setting&() { return getRoot(); } private: void storeNumeric ( Setting &setting, const mxArray *value, string key = "" ) { //TODO: integer matrices if ( !mxIsNumeric ( value ) ) { mexErrMsgTxt ( "Given mxArray is not numeric." ); }; mat val = mxArray2mat ( value ); if ( ( val.rows() == 1 ) && ( val.cols() == 1 ) ) { Setting &child = ( key == "" ) ? setting.add ( Setting::TypeFloat ) : setting.add ( key, Setting::TypeFloat ); child = val ( 0, 0 ); } else { Setting &child = ( key == "" ) ? setting.add ( Setting::TypeList ) : setting.add ( key, Setting::TypeList ); Setting &label = child.add ( Setting::TypeString ); label = "matrix"; Setting &rows = child.add ( Setting::TypeInt ); Setting &cols = child.add ( Setting::TypeInt ); Setting &elements = child.add ( Setting::TypeArray ); cols = val.cols(); rows = val.rows(); for ( int i = 0; i < val.rows(); i++ ) { for ( int j = 0; j < val.cols(); j++ ) { Setting &el = elements.add ( Setting::TypeFloat ); el = val ( i, j ); } } } } void fillGroup ( Setting &setting, const mxArray *mxarray ) { if ( !mxIsStruct ( mxarray ) ) { mexErrMsgTxt ( "Given mxArray is not a struct." ); }; for ( int i = 0; i < mxGetNumberOfFields ( mxarray ); i++ ) { const char *key = mxGetFieldNameByNumber ( mxarray, i ); mxArray *value = mxGetField ( mxarray, 0, key ); if ( mxIsChar ( value ) ) { Setting &child = setting.add ( key, Setting::TypeString ); child = mxArray2string ( value ); } if ( mxIsLogical ( value ) ) { Setting &child = setting.add ( key, Setting::TypeBoolean ); child = ( bool ) mxArray2bin ( value ); } if ( mxIsStruct ( value ) ) { Setting &child = setting.add ( key, Setting::TypeGroup ); fillGroup ( child, value ); } if ( mxIsCell ( value ) ) { Setting &child = setting.add ( key, Setting::TypeList ); fillList ( child, value ); } if ( mxIsNumeric ( value ) ) { storeNumeric ( setting, value, ( string ) key ); } } } void fillList ( Setting &setting, const mxArray *mxarray ) { if ( !mxIsCell ( mxarray ) ) { mexErrMsgTxt ( "Given mxArray is not a cell." ); }; for ( unsigned int i = 0; i < mxGetNumberOfElements ( mxarray ); i++ ) { mxArray *value = mxGetCell ( mxarray, i ); if ( mxIsChar ( value ) ) { Setting &child = setting.add ( Setting::TypeString ); child = mxArray2string ( value ); } if ( mxIsLogical ( value ) ) { Setting &child = setting.add ( Setting::TypeBoolean ); child = ( bool ) mxArray2bin ( value ); } if ( mxIsStruct ( value ) ) { Setting &child = setting.add ( Setting::TypeGroup ); fillGroup ( child, value ); } if ( mxIsCell ( value ) ) { Setting &child = setting.add ( Setting::TypeList ); fillList ( child, value ); } if ( mxIsNumeric ( value ) ) { storeNumeric ( setting, value ); } } } };