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