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

Revision 925, 9.1 kB (checked in by smidl, 14 years ago)

new mexpdf

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