root/library/bdm/mex/mex_parser.h @ 933

Revision 933, 9.2 kB (checked in by smidl, 15 years ago)

bdmtoolbox updated for new loggers

  • Property svn:eol-style set to native
RevLine 
[593]1#ifndef MXPARSE_H
2#define MXPARSE_H
3
4
[700]5#include "base/libconfig/lib/libconfig.h++"
[331]6#include <itpp/itbase.h>
[327]7#include <itpp/itmex.h>
8#include <stdlib.h>
9
[593]10
[331]11using namespace itpp;
[327]12using namespace std;
13using namespace libconfig;
14
[536]15//! Class for writing Settings into Matlab's mxArray
[327]16class UImxArray : public Config {
17public:
[536]18        //! Build an instance of Config with fields filled from the given \a mxarray
[477]19        UImxArray ( const mxArray *mxarray ) : Config() {
[327]20                Setting & setting = this->getRoot(); //setting is a group
[477]21                if ( !mxIsStruct ( mxarray ) ) {
22                        mexErrMsgTxt ( "Given mxArray is not a struct." );
23                };
[756]24
[327]25                //mexCallMATLAB(0, NULL, 1, (mxArray **) &mxarray, "dump");
[477]26                fillGroup ( setting, mxarray );
27                setAutoConvert ( true );
[327]28        }
[477]29        UImxArray() : Config() {
30                setAutoConvert ( true );
31        }
[536]32        //! Add libconfig's \c list to the structure
[477]33        void addList ( const mxArray *mxarray, const char* name ) {
[388]34                Setting & setting = this->getRoot(); //setting is a group
[477]35                Setting & child = setting.add ( name, Setting::TypeList );
36                fillList ( child, mxarray );
[388]37        }
[536]38        //! Add libconfig's \c group to the structure
[477]39        void addGroup ( const mxArray *mxarray, const char* name ) {
[392]40                Setting & setting = this->getRoot(); //setting is a group
[477]41                Setting & child = setting.add ( name, Setting::TypeGroup );
42                fillGroup ( child, mxarray );
[392]43        }
[756]44        //! Operator for more convenient access to this Config
[477]45        operator Setting&() {
46                return getRoot();
[392]47        }
[756]48
[327]49private:
[477]50        void storeNumeric ( Setting &setting, const mxArray *value, string key = "" ) {
[327]51                //TODO: integer matrices
[477]52                if ( !mxIsNumeric ( value ) ) {
53                        mexErrMsgTxt ( "Given mxArray is not numeric." );
54                };
[613]55                //treat empty matrices independently
56                mat val;
[796]57                if ( mxGetM ( value ) > 0 && mxGetN(value)>0) {
[613]58                        val = mxArray2mat ( value );
59                }
[477]60                if ( ( val.rows() == 1 ) && ( val.cols() == 1 ) ) {
61                        Setting &child = ( key == "" ) ? setting.add ( Setting::TypeFloat )
62                                         : setting.add ( key, Setting::TypeFloat );
63                        child = val ( 0, 0 );
[327]64                } else {
[477]65                        Setting &child = ( key == "" ) ? setting.add ( Setting::TypeList )
66                                         : setting.add ( key, Setting::TypeList );
67                        Setting &label = child.add ( Setting::TypeString );
[371]68                        label = "matrix";
[477]69                        Setting &rows = child.add ( Setting::TypeInt );
70                        Setting &cols = child.add ( Setting::TypeInt );
71                        Setting &elements = child.add ( Setting::TypeArray );
[327]72                        cols = val.cols();
[345]73                        rows = val.rows();
[477]74                        for ( int i = 0; i < val.rows(); i++ ) {
75                                for ( int j = 0; j < val.cols(); j++ ) {
76                                        Setting &el = elements.add ( Setting::TypeFloat );
77                                        el = val ( i, j );
[327]78                                }
79                        }
80                }
81        }
82
[477]83        void fillGroup ( Setting &setting, const mxArray *mxarray ) {
84                if ( !mxIsStruct ( mxarray ) ) {
85                        mexErrMsgTxt ( "Given mxArray is not a struct." );
86                };
87                for ( int i = 0; i < mxGetNumberOfFields ( mxarray ); i++ ) {
88                        const char *key = mxGetFieldNameByNumber ( mxarray, i );
89                        mxArray *value = mxGetField ( mxarray, 0, key );
90                        if ( mxIsChar ( value ) ) {
91                                Setting &child = setting.add ( key, Setting::TypeString );
92                                child = mxArray2string ( value );
[933]93                                } else {
[477]94                        if ( mxIsLogical ( value ) ) {
95                                Setting &child = setting.add ( key, Setting::TypeBoolean );
96                                child = ( bool ) mxArray2bin ( value );
[933]97                        } else {
[477]98                        if ( mxIsStruct ( value ) ) {
99                                Setting &child = setting.add ( key, Setting::TypeGroup );
100                                fillGroup ( child, value );
[933]101                        } else {
[477]102                        if ( mxIsCell ( value ) ) {
103                                Setting &child = setting.add ( key, Setting::TypeList );
104                                fillList ( child, value );
[933]105                        } else {
[477]106                        if ( mxIsNumeric ( value ) ) {
107                                storeNumeric ( setting, value, ( string ) key );
[933]108                        } else {
109                        // it is neither of above - treat it as an address
110                        // if (mxIsObject(value)){ <== should be tested but it is broken in matlab...
111                       
[925]112                                Setting &child = setting.add(key, Setting::TypeInt64);
113                                child = (long)value;
114                        }
[933]115                        }
116                        }
117                        }
118                                }
[327]119                }
120        }
[477]121
122        void fillList ( Setting &setting, const mxArray *mxarray ) {
123                if ( !mxIsCell ( mxarray ) ) {
124                        mexErrMsgTxt ( "Given mxArray is not a cell." );
125                };
[737]126                for ( unsigned int i = 0; i < ( unsigned int ) mxGetNumberOfElements ( mxarray ); i++ ) {
[477]127                        mxArray *value = mxGetCell ( mxarray, i );
128                        if ( mxIsChar ( value ) ) {
129                                Setting &child = setting.add ( Setting::TypeString );
130                                child = mxArray2string ( value );
[327]131                        }
[477]132                        if ( mxIsLogical ( value ) ) {
133                                Setting &child = setting.add ( Setting::TypeBoolean );
134                                child = ( bool ) mxArray2bin ( value );
[327]135                        }
[477]136                        if ( mxIsStruct ( value ) ) {
137                                Setting &child = setting.add ( Setting::TypeGroup );
138                                fillGroup ( child, value );
[327]139                        }
[477]140                        if ( mxIsCell ( value ) ) {
141                                Setting &child = setting.add ( Setting::TypeList );
142                                fillList ( child, value );
[327]143                        }
[477]144                        if ( mxIsNumeric ( value ) ) {
145                                storeNumeric ( setting, value );
[327]146                        }
147                }
148        }
[756]149
150public:
151        //! Convert existing Setting to Matlab arrays
152        static mxArray * create_mxArray( const Setting &setting )
153        {
154                return group2mxstruct ( setting );
155        }
156
157        //! Convert existing Setting to Matlab arrays
158        mxArray * create_mxArray(  )
159        {
160                return group2mxstruct ( *this );
161        }
162
163private:
164        //! Convert libconfig's array to Matlab vector
165        static mxArray* array2mxvector ( const Setting &setting )  {
166                if ( !setting.isArray() ) mexErrMsgTxt ( "Given setting is not an array" );
167                mxArray *result = mxCreateDoubleMatrix ( 1, setting.getLength(), mxREAL );
168                double *elements = mxGetPr ( result );
169                for ( int i = 0; i < setting.getLength(); i++ ) {
170                        if ( setting.getType() == Setting::TypeInt ) { //TODO: tady je chyba -- zaporna cisla nejsou TypeInt
171                                elements[i] = ( int ) setting[i];
172                        } else {
173                                elements[i] =  setting[i];
174                        }
175                }
176                return result;
177        }
178
179        //! Convert libconfig's array to Matlab matrix
180        static mxArray* list2mxmatrix ( const Setting &setting )  {
181                if ( !setting.isList() || ( strcmp ( "matrix", setting[0] ) != 0 ) )
182                        mexErrMsgTxt ( "Given setting is not a matrix" );
183                int rows = setting[1];
184                int cols = setting[2];
185                if ( setting[3].getLength() != rows*cols )
186                        mexErrMsgTxt ( "Matrix elements do not fit to rows*cols" );
187                double *elements = new double[rows*cols];
188                for ( int i = 0; i < rows*cols; i++ ) {
189                        elements[i] = setting[3][i];
190                }
191                mat &m = * ( new mat ( elements, rows, cols ) );
192                mxArray *result = mxCreateDoubleMatrix ( rows, cols, mxREAL );
193                mat2mxArray ( m, result );
194                delete &m;
195                delete [] elements;
196                return result;
197        }
198
199        //! Convert libconfig's gourp to Matlab structure
200        static mxArray* group2mxstruct ( const Setting &setting ) {
201                if ( !setting.isGroup() ) mexErrMsgTxt ( "Given setting is not a group." );
202                const char ** keys = new const char*[setting.getLength() ];
203                for ( int i = 0; i < setting.getLength(); i++ ) {
204                        keys[i] = setting[i].getName();
205                }
206                mxArray *result = mxCreateStructMatrix ( 1, 1, setting.getLength(), keys );
207                delete keys;
208                for ( int i = 0; i < setting.getLength(); i++ ) {
209                        Setting &value = setting[i];
210                        mxArray *old = mxGetFieldByNumber ( result, 0, i );
211                        if ( old ) mxDestroyArray ( old );
212                        switch ( value.getType() ) {
213                        case Setting::TypeString:
214                                mxSetFieldByNumber ( result, 0, i, mxCreateString ( value ) );
215                                break;
216                        case Setting::TypeBoolean:
217                                mxSetFieldByNumber ( result, 0, i, mxCreateLogicalScalar ( value ) );
218                                break;
219                        case Setting::TypeGroup:
220                                mxSetFieldByNumber ( result, 0, i, group2mxstruct ( value ) );
221                                break;
222                        case Setting::TypeList:
223                                mxSetFieldByNumber ( result, 0, i, list2mxcell ( value ) );
224                                break;
225                        case Setting::TypeArray:
226                                mxSetFieldByNumber ( result, 0, i, array2mxvector ( value ) );
227                                break;
228                        case Setting::TypeInt:
229                        case Setting::TypeInt64:
230                                mxSetFieldByNumber ( result, 0, i, mxCreateDoubleScalar ( ( int ) value ) );
231                                break;
232                        case Setting::TypeFloat:
233                                mxSetFieldByNumber ( result, 0, i, mxCreateDoubleScalar ( value ) );
234                                break;
235                        default:
236                                //this should never happen
237                                mexErrMsgTxt ( "Unknown type of a setting." );
238                        }
239                }
240                return result;
241
242        }
243        //! Convert libconfig's list  to Matlab cell
244        static mxArray* list2mxcell ( const Setting &setting )  {
245                if ( !setting.isList() ) mexErrMsgTxt ( "Given setting is not a list." );
246                if ( setting.getLength() == 0 ) {
247                        mxArray *result = mxCreateCellMatrix ( 1, 0 );
248                        return result;
249                }
250
251                if ( ( setting[0].getType() == Setting::TypeString ) ) {
252                        string s = ( setting[0] );
253                        if ( s == "matrix" ) {
254                                return list2mxmatrix ( setting );
255                        }
256                }
257                mxArray *result = mxCreateCellMatrix ( 1, setting.getLength() );
258                for ( int i = 0; i < setting.getLength(); i++ ) {
259                        Setting &value = setting[i];
260                        mxArray *old = mxGetCell ( result, i );
261                        if ( old ) mxDestroyArray ( old );
262                        switch ( value.getType() ) {
263                        case Setting::TypeString:
264                                mxSetCell ( result, i, mxCreateString ( value ) );
265                                break;
266                        case Setting::TypeBoolean:
267                                mxSetCell ( result, i, mxCreateLogicalScalar ( value ) );
268                                break;
269                        case Setting::TypeGroup:
270                                mxSetCell ( result, i, group2mxstruct ( value ) );
271                                break;
272                        case Setting::TypeList:
273                                mxSetCell ( result, i, list2mxcell ( value ) );
274                                break;
275                        case Setting::TypeArray:
276                                mxSetCell ( result, i, array2mxvector ( value ) );
277                                break;
278                        case Setting::TypeInt:
279                        case Setting::TypeInt64:
280                                mxSetCell ( result, i, mxCreateDoubleScalar ( ( int ) value ) );
281                                break;
282                        case Setting::TypeFloat:
283                                mxSetCell ( result, i, mxCreateDoubleScalar ( value ) );
284                                break;
285                        default:
286                                //this should never happen
287                                mexErrMsgTxt ( "Unknown type of a setting." );
288                        }
289                }
290                return result;
291        }
[327]292};
[593]293
294#endif //MXPARSE_H
Note: See TracBrowser for help on using the browser.