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 &rows = child.add( Setting::TypeInt );
00051 Setting &cols = 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(uint 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 };