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 UImxArray : public Config {
00011 public:
00012         UImxArray(const mxArray *mxarray) : Config() {
00013                 Setting & setting = this->getRoot(); 
00014                 if (!mxIsStruct(mxarray)) { mexErrMsgTxt("Given mxArray is not a struct."); };
00015                 
00016                 fillGroup(setting, mxarray);
00017                 setAutoConvert(true);
00018         }
00019         UImxArray() : Config() {                
00020                 setAutoConvert(true);
00021         }       
00022         void addList(const mxArray *mxarray, const char* name){
00023                 Setting & setting = this->getRoot(); 
00024                 Setting & child = setting.add(name,Setting::TypeList);
00025                 fillList(child,mxarray);
00026         }
00027         void addGroup(const mxArray *mxarray, const char* name){
00028                 Setting & setting = this->getRoot(); 
00029                 Setting & child = setting.add(name,Setting::TypeGroup);
00030                 fillGroup(child,mxarray);
00031         }
00032         operator Setting&()
00033         {
00034                  return getRoot();
00035         }
00036 private:
00037         void storeNumeric(Setting &setting, const mxArray *value, string key = "") {
00038                 
00039                 if (!mxIsNumeric(value)) { mexErrMsgTxt("Given mxArray is not numeric."); };
00040                 mat val = mxArray2mat(value);
00041                 if ((val.rows() == 1) && (val.cols() == 1)) {
00042                         Setting &child = (key=="") ? setting.add(Setting::TypeFloat)
00043                                                    : setting.add(key, Setting::TypeFloat);
00044                         child = val(0,0);
00045                 } else {
00046                         Setting &child = (key=="") ? setting.add(Setting::TypeList)
00047                                                    : setting.add(key, Setting::TypeList);
00048                         Setting &label = child.add(Setting::TypeString);
00049                         label = "matrix";
00050                         Setting &cols = child.add( Setting::TypeInt );
00051                         Setting &rows = child.add( Setting::TypeInt );
00052                         Setting &elements = child.add( Setting::TypeArray );
00053                         cols = val.cols();
00054                         rows = val.rows();
00055                         for (int i=0; i<val.rows(); i++) {
00056                                 for (int j=0; j<val.cols(); j++) {
00057                                         Setting &el = elements.add(Setting::TypeFloat);
00058                                         el = val(i,j);
00059                                 }
00060                         }
00061                 }
00062         }
00063 
00064         void fillGroup(Setting &setting, const mxArray *mxarray) {
00065                 if (!mxIsStruct(mxarray)) { mexErrMsgTxt("Given mxArray is not a struct."); };
00066                 for(int i=0; i < mxGetNumberOfFields(mxarray); i++) {
00067                         const char *key = mxGetFieldNameByNumber(mxarray, i);
00068                         mxArray *value = mxGetField(mxarray, 0, key);
00069                         if (mxIsChar(value)) {
00070                                 Setting &child = setting.add(key, Setting::TypeString);
00071                                 child = mxArray2string(value);
00072                         }
00073                         if (mxIsLogical(value)) {
00074                                 Setting &child = setting.add(key, Setting::TypeBoolean);
00075                                 child = (bool) mxArray2bin(value);
00076                         }
00077                         if (mxIsStruct(value)) {
00078                                 Setting &child = setting.add(key, Setting::TypeGroup);
00079                                 fillGroup(child, value);
00080                         }
00081                         if (mxIsCell(value)) {
00082                                 Setting &child = setting.add(key, Setting::TypeList);
00083                                 fillList(child, value);
00084                         }
00085                         if (mxIsNumeric(value)) {
00086                                 storeNumeric(setting, value, (string)key);
00087                         }
00088                 }
00089         }
00090         
00091         void fillList(Setting &setting, const mxArray *mxarray) {
00092                 if (!mxIsCell(mxarray)) { mexErrMsgTxt("Given mxArray is not a cell."); };
00093                 for(int i=0; i < mxGetNumberOfElements(mxarray); i++) {
00094                         mxArray *value = mxGetCell(mxarray, i);
00095                         if (mxIsChar(value)) {
00096                                 Setting &child = setting.add(Setting::TypeString);
00097                                 child = mxArray2string(value);
00098                         }
00099                         if (mxIsLogical(value)) {
00100                                 Setting &child = setting.add(Setting::TypeBoolean);
00101                                 child = (bool) mxArray2bin(value);
00102                         }
00103                         if (mxIsStruct(value)) {
00104                                 Setting &child = setting.add(Setting::TypeGroup);
00105                                 fillGroup(child, value);
00106                         }
00107                         if (mxIsCell(value)) {
00108                                 Setting &child = setting.add(Setting::TypeList);
00109                                 fillList(child, value);
00110                         }
00111                         if (mxIsNumeric(value)) {
00112                                 storeNumeric(setting, value);
00113                         }
00114                 }
00115         }
00116 };