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