00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __casadbus_variant_h__
00030 #define __casadbus_variant_h__
00031
00032 #include <string>
00033 #include <vector>
00034 #include <complex>
00035
00036 namespace casa {
00037 namespace dbus {
00038
00039 class record;
00040
00041 class variant {
00042
00043 public:
00044
00045 enum TYPE { RECORD, BOOL, INT, DOUBLE, COMPLEX, STRING, BOOLVEC, INTVEC, DOUBLEVEC, COMPLEXVEC, STRINGVEC };
00046
00047 static TYPE compatible_type( TYPE one, TYPE two );
00048
00049 class error {
00050 public:
00051 error( std::string msg ) : message_(msg) { }
00052 const std::string &message( ) const { return message_; }
00053 private:
00054 std::string message_;
00055 };
00056
00057 class overflow : public error {
00058 public:
00059 overflow( std::string lbl ) : error(lbl + ": overflow error") { }
00060 };
00061
00062 variant *clone() const { return new variant(*this); }
00063 int compare(const variant*) const;
00064
00065 variant( );
00066 variant(const variant &);
00067
00068 variant(bool arg) : typev(BOOL), shape_(1,1) { val.b = arg; }
00069 variant(int arg) : typev(INT), shape_(1,1) { val.i = arg; }
00070 variant(double arg) : typev(DOUBLE), shape_(1,1) { val.d = arg; }
00071 variant(std::complex<double> arg) : typev(COMPLEX) { val.c = new std::complex<double>(arg); }
00072 variant(const char *arg) : typev(STRING), shape_(1,1)
00073 { val.s = new std::string(arg); }
00074 variant(const std::string &arg) : typev(STRING), shape_(1,1)
00075 { val.s = new std::string(arg); }
00076
00077 variant(const std::vector<bool> &arg) : typev(BOOLVEC), shape_(1,arg.size())
00078 { val.bv = new std::vector<bool>(arg); }
00079 variant(const std::vector<bool> &arg, const std::vector<int> &theshape) : typev(BOOLVEC), shape_(theshape)
00080 { val.bv = new std::vector<bool>(arg); }
00081 variant(std::vector<bool> *arg) : typev(BOOLVEC), shape_(1,arg->size())
00082 { val.bv = arg; }
00083 variant(std::vector<bool> *arg, std::vector<int> &theshape) : typev(BOOLVEC), shape_(theshape)
00084 { val.bv = arg; }
00085
00086 variant(const std::vector<int> &arg) : typev(INTVEC), shape_(1,arg.size())
00087 { val.iv = new std::vector<int>(arg); }
00088 variant(const std::vector<int> &arg, const std::vector<int> &theshape) : typev(INTVEC), shape_(theshape)
00089 { val.iv = new std::vector<int>(arg); }
00090 variant(std::vector<int> *arg) : typev(INTVEC), shape_(1, arg->size())
00091 { val.iv = arg; }
00092 variant(std::vector<int> *arg, std::vector<int> &theshape) : typev(INTVEC), shape_(theshape)
00093 { val.iv = arg; }
00094
00095 variant(const std::vector<double> &arg) : typev(DOUBLEVEC), shape_(1,arg.size())
00096 { val.dv = new std::vector<double>(arg); }
00097 variant(const std::vector<double> &arg, const std::vector<int> &theshape) : typev(DOUBLEVEC), shape_(theshape)
00098 { val.dv = new std::vector<double>(arg); }
00099 variant(std::vector<double> *arg) : typev(DOUBLEVEC), shape_(1,arg->size())
00100 { val.dv = arg; }
00101 variant(std::vector<double> *arg, std::vector<int> &theshape) : typev(DOUBLEVEC), shape_(theshape)
00102 { val.dv = arg; }
00103
00104 variant(const std::vector<std::complex<double> > &arg) : typev(COMPLEXVEC), shape_(1, arg.size())
00105 { val.cv = new std::vector<std::complex<double> >(arg); }
00106 variant(const std::vector<std::complex<double> > &arg, const std::vector<int> &theshape) : typev(COMPLEXVEC), shape_(theshape)
00107 { val.cv = new std::vector<std::complex<double> >(arg); }
00108 variant(std::vector<std::complex<double> > *arg) : typev(COMPLEXVEC), shape_(1,arg->size())
00109 { val.cv = arg; }
00110 variant(std::vector<std::complex<double> > *arg, std::vector<int> &theshape) : typev(COMPLEXVEC), shape_(theshape)
00111 { val.cv = arg; }
00112
00113 variant(const std::vector<std::string> &arg, const std::vector<int> &theshape) : typev(STRINGVEC), shape_(theshape)
00114 { val.sv = new std::vector<std::string>(arg); }
00115 variant(const std::vector<std::string> &arg) : typev(STRINGVEC), shape_(1,arg.size())
00116 { val.sv = new std::vector<std::string>(arg); }
00117 variant(std::vector<std::string> *arg) : typev(STRINGVEC), shape_(1, arg->size())
00118 { val.sv = arg; }
00119 variant(std::vector<std::string> *arg, std::vector<int> &theshape) : typev(STRINGVEC), shape_(theshape)
00120 { val.sv = arg; }
00121
00122 variant(record &arg);
00123 variant(record *arg);
00124
00125 ~variant( );
00126
00127 bool toBool( ) const;
00128 int toInt( ) const;
00129 double toDouble( ) const;
00130 std::complex<double> toComplex( ) const;
00131 std::string toString( bool no_brackets=false ) const;
00132 std::vector<bool> toBoolVec( ) const;
00133 std::vector<int> toIntVec( ) const;
00134 std::vector<double> toDoubleVec( ) const;
00135 std::vector<std::complex<double> > toComplexVec( ) const;
00136 std::vector<std::string> toStringVec( ) const;
00137
00138
00139
00140
00141
00142 bool &asBool( );
00143 int &asInt( );
00144 double &asDouble( );
00145 std::complex<double> &asComplex( );
00146 std::string &asString( );
00147 std::vector<int> &asIntVec( int size=-1 );
00148 std::vector<bool> &asBoolVec( int size=-1 );
00149 std::vector<double> &asDoubleVec( int size=-1 );
00150 std::vector<std::complex<double> > &asComplexVec( int size=-1 );
00151 std::vector<std::string> &asStringVec( int size=-1 );
00152 record &asRecord( );
00153
00154 void as( TYPE t, int size=-1 );
00155
00156
00157
00158 bool getBool( ) const throw(error);
00159 int getInt( ) const throw(error);
00160 double getDouble( ) const throw(error);
00161 const std::complex<double> &getComplex( ) const throw(error);
00162 const std::string &getString( ) const throw(error);
00163 const std::vector<int> &getIntVec( ) const throw(error);
00164 const std::vector<bool> &getBoolVec( ) const throw(error);
00165 const std::vector<double> &getDoubleVec( ) const throw(error);
00166 const std::vector<std::complex<double> > &getComplexVec( ) const throw(error);
00167 const std::vector<std::string> &getStringVec( ) const throw(error);
00168 const record &getRecord( ) const throw(error);
00169 const std::vector<int> &shape() const;
00170 const std::vector<int> &arrayshape() const {return shape();}
00171
00172
00173
00174 bool &getBoolMod( ) throw(error);
00175 int &getIntMod( ) throw(error);
00176 double &getDoubleMod( ) throw(error);
00177 std::complex<double> &getComplexMod( ) throw(error);
00178 std::string &getStringMod( ) throw(error);
00179 std::vector<int> &getIntVecMod( ) throw(error);
00180 std::vector<bool> &getBoolVecMod( ) throw(error);
00181 std::vector<double> &getDoubleVecMod( ) throw(error);
00182 std::vector<std::complex<double> > &getComplexVecMod( ) throw(error);
00183 std::vector<std::string> &getStringVecMod( ) throw(error);
00184 record &getRecordMod( ) throw(error);
00185 std::vector<int> &shape();
00186 std::vector<int> &arrayshape() {return shape();}
00187
00188 const std::string &typeString( ) const;
00189 const char *sig( ) const;
00190 TYPE type( ) const { return typev; }
00191
00192 void push(bool, bool conform = true);
00193 void push(int, bool conform = true);
00194 void push(double, bool conform = true);
00195 void push(std::complex<double>, bool conform = true);
00196 void push(const std::string&, bool conform = true);
00197
00198 void place(bool, unsigned int index, bool conform = true);
00199 void place(int, unsigned int index, bool conform = true);
00200 void place(double, unsigned int index, bool conform = true);
00201 void place(std::complex<double>, unsigned int index, bool conform = true);
00202 void place(const std::string&, unsigned int index, bool conform = true);
00203
00204 int size( ) const { return typev >= BOOLVEC ? vec_size() : 1; }
00205 void resize( int size );
00206
00207 private:
00208
00209
00210 int shape_size( ) const;
00211
00212
00213 static unsigned int record_id_count;
00214
00215 int vec_size( ) const;
00216 TYPE typev;
00217 union {
00218 bool b;
00219 std::vector<bool> *bv;
00220 int i;
00221 std::vector<int> *iv;
00222 double d;
00223 std::vector<double> *dv;
00224 std::complex<double> *c;
00225 std::vector<std::complex<double> > *cv;
00226 std::string *s;
00227 std::vector<std::string> *sv;
00228 record *recordv;
00229 } val;
00230 std::vector<int> shape_;
00231
00232 std::string create_message( const std::string s ) const;
00233 };
00234
00235 }
00236 }
00237 #endif