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 UImxConfig : public Config {
00012 public:
00014         mxArray *mxconfig;
00016         UImxConfig ( const char * filename ) {
00017                 Config config;
00018                 config.readFile ( filename );
00019                 mxconfig = group2mxstruct ( config.getRoot() );
00020         }
00022         UImxConfig ( const Setting &setting ) {
00023                 mxconfig = group2mxstruct ( setting );
00024         }
00025 
00026 private:
00028         mxArray* array2mxvector ( const Setting &setting )  {
00029                 if ( !setting.isArray() ) mexErrMsgTxt ( "Given setting is not an array" );
00030                 double *elements = new double[setting.getLength() ];
00031                 for ( int i = 0; i < setting.getLength(); i++ ) {
00032                         if ( setting.getType() == Setting::TypeInt ) { 
00033                                 elements[i] = setting[i];
00034                         } else {
00035                                 elements[i] = ( int ) setting[i];
00036                         }
00037                 }
00038                 vec &v = * ( new vec ( elements, setting.getLength() ) );
00039                 mxArray *result = mxCreateDoubleMatrix ( 1, setting.getLength(), mxREAL );
00040                 vec2mxArray ( v, result );
00041                 delete &v;
00042                 delete [] elements;
00043                 return result;
00044         }
00045 
00047         mxArray* list2mxmatrix ( const Setting &setting )  {
00048                 if ( !setting.isList() || ( "matrix" != setting[0] ) )
00049                         mexErrMsgTxt ( "Given setting is not a matrix" );
00050                 int rows = setting[1];
00051                 int cols = setting[2];
00052                 if ( setting[3].getLength() != rows*cols )
00053                         mexErrMsgTxt ( "Matrix elements do not fit to rows*cols" );
00054                 double *elements = new double[rows*cols];
00055                 for ( int i = 0; i < rows*cols; i++ ) {
00056                         elements[i] = setting[3][i];
00057                 }
00058                 mat &m = * ( new mat ( elements, rows, cols ) );
00059                 mxArray *result = mxCreateDoubleMatrix ( rows, cols, mxREAL );
00060                 mat2mxArray ( m, result );
00061                 delete &m;
00062                 delete [] elements;
00063                 return result;
00064         }
00065         
00067         mxArray* group2mxstruct ( const Setting &setting ) {
00068                 if ( !setting.isGroup() ) mexErrMsgTxt ( "Given setting is not a group." );
00069                 const char ** keys = new const char*[setting.getLength() ];
00070                 for ( int i = 0; i < setting.getLength(); i++ ) {
00071                         keys[i] = setting[i].getName();
00072                 }
00073                 mxArray *result = mxCreateStructMatrix ( 1, 1, setting.getLength(), keys );
00074                 delete keys;
00075                 for ( int i = 0; i < setting.getLength(); i++ ) {
00076                         Setting &value = setting[i];
00077                         mxArray *old = mxGetFieldByNumber ( result, 0, i );
00078                         if ( old ) mxDestroyArray ( old );
00079                         switch ( value.getType() ) {
00080                         case Setting::TypeString:
00081                                 mxSetFieldByNumber ( result, 0, i, mxCreateString ( value ) );
00082                                 break;
00083                         case Setting::TypeBoolean:
00084                                 mxSetFieldByNumber ( result, 0, i, mxCreateLogicalScalar ( value ) );
00085                                 break;
00086                         case Setting::TypeGroup:
00087                                 mxSetFieldByNumber ( result, 0, i, group2mxstruct ( value ) );
00088                                 break;
00089                         case Setting::TypeList:
00090                                 mxSetFieldByNumber ( result, 0, i, list2mxcell ( value ) );
00091                                 break;
00092                         case Setting::TypeArray:
00093                                 mxSetFieldByNumber ( result, 0, i, array2mxvector ( value ) );
00094                                 break;
00095                         case Setting::TypeInt:
00096                         case Setting::TypeInt64:
00097                                 mxSetFieldByNumber ( result, 0, i, mxCreateDoubleScalar ( ( int ) value ) );
00098                                 break;
00099                         case Setting::TypeFloat:
00100                                 mxSetFieldByNumber ( result, 0, i, mxCreateDoubleScalar ( value ) );
00101                                 break;
00102                         default:
00103                                 
00104                                 mexErrMsgTxt ( "Unknown type of a setting." );
00105                         }
00106                 }
00107                 return result;
00108 
00109         }
00111         mxArray* list2mxcell ( const Setting &setting )  {
00112                 if ( !setting.isList() ) mexErrMsgTxt ( "Given setting is not a list." );
00113                 if ( setting.getLength() == 0 ) {
00114                         mxArray *result = mxCreateCellMatrix ( 1, 0 );
00115                         return result;
00116                 }
00117                 if ( ( setting[0].getType() == Setting::TypeString ) && ( "matrix" == setting[0] ) ) {
00118                         return list2mxmatrix ( setting );
00119                 }
00120                 mxArray *result = mxCreateCellMatrix ( 1, setting.getLength() );
00121                 for ( int i = 0; i < setting.getLength(); i++ ) {
00122                         Setting &value = setting[i];
00123                         mxArray *old = mxGetCell ( result, i );
00124                         if ( old ) mxDestroyArray ( old );
00125                         switch ( value.getType() ) {
00126                         case Setting::TypeString:
00127                                 mxSetCell ( result, i, mxCreateString ( value ) );
00128                                 break;
00129                         case Setting::TypeBoolean:
00130                                 mxSetCell ( result, i, mxCreateLogicalScalar ( value ) );
00131                                 break;
00132                         case Setting::TypeGroup:
00133                                 mxSetCell ( result, i, group2mxstruct ( value ) );
00134                                 break;
00135                         case Setting::TypeList:
00136                                 mxSetCell ( result, i, list2mxcell ( value ) );
00137                                 break;
00138                         case Setting::TypeArray:
00139                                 mxSetCell ( result, i, array2mxvector ( value ) );
00140                                 break;
00141                         case Setting::TypeInt:
00142                         case Setting::TypeInt64:
00143                                 mxSetCell ( result, i, mxCreateDoubleScalar ( ( int ) value ) );
00144                                 break;
00145                         case Setting::TypeFloat:
00146                                 mxSetCell ( result, i, mxCreateDoubleScalar ( value ) );
00147                                 break;
00148                         default:
00149                                 
00150                                 mexErrMsgTxt ( "Unknown type of a setting." );
00151                         }
00152                 }
00153                 return result;
00154         }
00155 };