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