00001 /*------------------------------------------------------------------------------ 00002 Name: ClientProperty.h 00003 Project: xmlBlaster.org 00004 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file 00005 Comment: Handling one client property of QosData 00006 ------------------------------------------------------------------------------*/ 00007 #ifndef _UTIL_QOS_CLIENTPROPERTY_H 00008 #define _UTIL_QOS_CLIENTPROPERTY_H 00009 00010 #include <util/xmlBlasterDef.h> 00011 #include <util/Constants.h> 00012 #include <util/Base64.h> 00013 #include <util/lexical_cast.h> 00014 #include <typeinfo> 00015 #include <vector> 00016 #include <string> 00017 #include <iostream> // temporary for cerr 00018 00019 namespace org { namespace xmlBlaster { namespace util { namespace qos { 00020 00042 class Dll_Export ClientProperty 00043 { 00044 private: 00046 std::string name_; // Can't be const because of: operator=() error: non-static const member `const std::string name_', can't use default assignment operator 00048 std::string value_; 00049 std::string encoding_; 00050 mutable std::string type_; 00051 mutable std::string charset_; 00052 00053 template <typename T_VALUE> void guessType(const T_VALUE& value) const; 00054 bool needsEncoding() const; 00055 00056 public: 00057 00080 template <typename T_VALUE> ClientProperty( 00081 const std::string& name, 00082 const T_VALUE& value, 00083 const std::string& type="", 00084 const std::string& encoding="", 00085 const std::string& charset="" 00086 ); 00087 00093 ClientProperty(bool dummy, 00094 const std::string& name, 00095 const std::string& type, 00096 const std::string& encoding, 00097 const std::string& charset 00098 ); 00099 00108 ClientProperty(const std::string& name, 00109 const char *value, 00110 const std::string& type=""); 00111 00120 ClientProperty(const std::string& name, 00121 const std::vector<unsigned char>& value, 00122 const std::string& type=""); 00123 00136 //virtual ~ClientProperty(); 00137 00142 const std::string& getName() const; 00143 00150 std::string getType() const; 00151 00157 std::string getEncoding() const; 00158 00164 std::string getCharset() const; 00165 00170 void setCharset(const std::string& charset); 00171 00175 bool isBase64() const; 00176 00180 std::string getValueRaw() const; 00181 00186 std::string getStringValue() const; 00187 00192 std::vector<unsigned char> getValue() const; 00193 00199 template <typename T_VALUE> void getValue(T_VALUE& value) const; 00200 00204 void setValue(const std::string& value); 00205 00209 void setValueRaw(const std::string& value); 00210 00218 std::string toXml(std::string extraOffset="", bool clearText=false, std::string tagName="clientProperty") const; 00219 }; 00220 00221 00222 // All template based function definitions follow here 00223 // to be available outside the shared library 00224 template <typename T_VALUE> ClientProperty::ClientProperty( 00225 const std::string& name, 00226 const T_VALUE& value, 00227 const std::string& type, 00228 const std::string& encoding, 00229 const std::string& charset 00230 ) 00231 : name_(name), 00232 value_(""), 00233 encoding_(encoding), 00234 type_(type), 00235 charset_(charset) 00236 { 00237 if (type_ == "") { 00238 guessType(value); // guess type from T_VALUE 00239 } 00240 00241 // Convert the given value type to a std::string value_ 00242 00243 value_ = lexical_cast<std::string>(value); 00244 00245 if (needsEncoding()) { 00246 std::vector<unsigned char> vec; 00247 vec.reserve(value_.size()); 00248 encoding_ = org::xmlBlaster::util::Constants::ENCODING_BASE64; 00249 copy(value_.begin(), value_.end(), back_inserter(vec)); 00250 value_ = org::xmlBlaster::util::Base64::Encode(vec); 00251 } 00252 } 00253 00254 template <typename T_VALUE> void ClientProperty::guessType(const T_VALUE& value) const { 00255 const char *cPC=0; 00256 char *cP=0; 00257 unsigned char *cUP=0; 00258 const unsigned char *cUPC=0; 00259 int64_t ll=0L; // Assumed to be 'long long int' (C99) == _int64 (Windows), Windows does not like double LL like 0LL; 00260 std::vector<char> vc; 00261 std::vector<unsigned char> vuc; 00262 00263 if (typeid(value) == typeid(std::string(""))) 00264 type_ = std::string(""); // "String" 00265 else if (typeid(value) == typeid(true)) 00266 type_ = org::xmlBlaster::util::Constants::TYPE_BOOLEAN; 00267 else if (typeid(value) == typeid(char(0))) 00268 type_ = org::xmlBlaster::util::Constants::TYPE_BYTE; 00269 else if (typeid(value) == typeid(cP) || typeid(value) == typeid(cPC) || 00270 typeid(value) == typeid("A") || typeid(value).name() == std::string("A13_c")) 00271 type_ = std::string(""); // "String" 00272 else if (typeid(value) == typeid(cUP) || typeid(value) == typeid(cUPC)) 00273 type_ = org::xmlBlaster::util::Constants::TYPE_BLOB; 00274 else if (typeid(value) == typeid(vc) || typeid(value) == typeid(vuc)) 00275 type_ = org::xmlBlaster::util::Constants::TYPE_BLOB; 00276 else if (typeid(value) == typeid(short(0))) 00277 type_ = org::xmlBlaster::util::Constants::TYPE_SHORT; 00278 else if (typeid(value) == typeid(int(0))) 00279 type_ = org::xmlBlaster::util::Constants::TYPE_INT; 00280 else if (typeid(value) == typeid(long(0L))) 00281 type_ = org::xmlBlaster::util::Constants::TYPE_LONG; 00282 else if (typeid(value) == typeid(ll)) 00283 type_ = org::xmlBlaster::util::Constants::TYPE_LONG; 00284 else if (typeid(value) == typeid(float(1.10))) 00285 type_ = org::xmlBlaster::util::Constants::TYPE_FLOAT; 00286 else if (typeid(value) == typeid(double(1.7L))) 00287 type_ = org::xmlBlaster::util::Constants::TYPE_DOUBLE; 00288 else { 00289 type_ = org::xmlBlaster::util::Constants::TYPE_BLOB; 00290 std::cerr << "Warning: ClientProperty typeid=" << typeid(value).name() << " is unknown, we handle it as a blob" << std::endl; 00291 } 00292 } 00293 00294 template <typename T_VALUE> void ClientProperty::getValue(T_VALUE& value) const { 00295 if (isBase64()) { 00296 if (type_ == org::xmlBlaster::util::Constants::TYPE_BLOB) { 00297 // TODO: detect it on compile time 00298 std::cerr << "Sorry, binary data type '" << typeid(value).name() 00299 << "' is not supported using getValue(value), please use 'std::vector<unsigned char> getValue()' instead" 00300 << std::endl; 00301 value = lexical_cast<T_VALUE>(getStringValue()); 00302 } 00303 else { 00304 value = lexical_cast<T_VALUE>(getStringValue()); 00305 } 00306 } 00307 else { 00308 value = lexical_cast<T_VALUE>(value_); 00309 } 00310 } 00311 00312 }}}} 00313 00314 #endif 00315