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