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