00001 // This file may be redistributed and modified only under the terms of 00002 // the GNU Lesser General Public License (See COPYING for details). 00003 // Copyright (C) 2000-2001 Stefanus Du Toit, Karsten-O. Laux and Al Riddoch 00004 00005 #ifndef ATLAS_MESSAGE_ELEMENT_H 00006 #define ATLAS_MESSAGE_ELEMENT_H 00007 00008 #include <Atlas/Exception.h> 00009 00010 #include <string> 00011 #include <map> 00012 #include <vector> 00013 00014 namespace Atlas { namespace Message { 00015 00017 class WrongTypeException : public Atlas::Exception 00018 { 00019 public: 00020 WrongTypeException() : Atlas::Exception("Wrong Message::Element type") { } 00021 }; 00022 00023 class Element; 00024 00025 typedef long IntType; 00026 typedef double FloatType; 00027 typedef void * PtrType; 00028 typedef std::string StringType; 00029 typedef std::map<std::string, Element> MapType; 00030 typedef std::vector<Element> ListType; 00031 00057 class Element 00058 { 00059 public: 00060 enum Type { 00061 TYPE_NONE, 00062 TYPE_INT, 00063 TYPE_FLOAT, 00064 TYPE_PTR, 00065 TYPE_STRING, 00066 TYPE_MAP, 00067 TYPE_LIST 00068 }; 00069 00070 private: 00071 // These are now legacy typedefs. New code should use the 00072 // Atlas::Message::*Type versions. 00073 typedef Atlas::Message::IntType IntType; 00074 typedef Atlas::Message::FloatType FloatType; 00075 typedef Atlas::Message::PtrType PtrType; 00076 typedef Atlas::Message::StringType StringType; 00077 typedef Atlas::Message::MapType MapType; 00078 typedef Atlas::Message::ListType ListType; 00079 00081 void clear(Type new_type = TYPE_NONE); 00082 00083 public: 00085 Element() 00086 : t(TYPE_NONE) 00087 { 00088 } 00089 00091 ~Element() 00092 { 00093 clear(); 00094 } 00095 00097 Element(const Element& obj); 00098 00100 Element(int v) 00101 : t(TYPE_INT), i(v) 00102 { 00103 } 00104 00106 Element(bool v) 00107 : t(TYPE_INT), i(v) 00108 { 00109 } 00110 00112 Element(IntType v) 00113 : t(TYPE_INT), i(v) 00114 { 00115 } 00116 00118 Element(float v) 00119 : t(TYPE_FLOAT), f(v) 00120 { 00121 } 00122 00124 Element(FloatType v) 00125 : t(TYPE_FLOAT), f(v) 00126 { 00127 } 00128 00130 Element(PtrType v) 00131 : t(TYPE_PTR), p(v) 00132 { 00133 } 00134 00136 Element(const char* v) 00137 : t(TYPE_STRING) 00138 { 00139 if(v) 00140 s = new DataType<StringType>(v); 00141 else 00142 s = new DataType<StringType>(); 00143 } 00144 00146 Element(const StringType& v) 00147 : t(TYPE_STRING) 00148 { 00149 s = new DataType<StringType>(v); 00150 } 00152 Element(const MapType& v) 00153 : t(TYPE_MAP) 00154 { 00155 m = new DataType<MapType>(v); 00156 } 00158 Element(const ListType& v) 00159 : t(TYPE_LIST) 00160 { 00161 l = new DataType<ListType>(v); 00162 } 00163 00165 Element& operator=(const Element& obj); 00166 00167 Element& operator=(int v) 00168 { 00169 if (TYPE_INT != t) 00170 { 00171 clear(TYPE_INT); 00172 } 00173 i = v; 00174 return *this; 00175 } 00176 00177 Element& operator=(bool v) 00178 { 00179 if (TYPE_INT != t) 00180 { 00181 clear(TYPE_INT); 00182 } 00183 i = v; 00184 return *this; 00185 } 00186 00187 Element& operator=(IntType v) 00188 { 00189 if (TYPE_INT != t) 00190 { 00191 clear(TYPE_INT); 00192 } 00193 i = v; 00194 return *this; 00195 } 00196 00197 Element& operator=(float v) 00198 { 00199 if (TYPE_FLOAT != t) 00200 { 00201 clear(TYPE_FLOAT); 00202 } 00203 f = v; 00204 return *this; 00205 } 00206 00207 Element& operator=(FloatType v) 00208 { 00209 if (TYPE_FLOAT != t) 00210 { 00211 clear(TYPE_FLOAT); 00212 } 00213 f = v; 00214 return *this; 00215 } 00216 00217 Element& operator=(PtrType v) 00218 { 00219 if (TYPE_PTR != t) 00220 { 00221 clear(TYPE_PTR); 00222 } 00223 p = v; 00224 return *this; 00225 } 00226 00227 Element& operator=(const char * v) 00228 { 00229 if (TYPE_STRING != t || !s->unique()) 00230 { 00231 clear(TYPE_STRING); 00232 s = new DataType<StringType>(v); 00233 } else { 00234 *s = StringType(v); 00235 } 00236 return *this; 00237 } 00238 00239 Element& operator=(const StringType & v) 00240 { 00241 if (TYPE_STRING != t || !s->unique()) 00242 { 00243 clear(TYPE_STRING); 00244 s = new DataType<StringType>(v); 00245 } else { 00246 *s = v; 00247 } 00248 return *this; 00249 } 00250 00251 Element& operator=(const MapType & v) 00252 { 00253 if (TYPE_MAP != t || !m->unique()) 00254 { 00255 clear(TYPE_MAP); 00256 m = new DataType<MapType>(v); 00257 } else { 00258 *m = v; 00259 } 00260 return *this; 00261 } 00262 00263 Element& operator=(const ListType & v) 00264 { 00265 if (TYPE_LIST != t || !l->unique()) 00266 { 00267 clear(TYPE_LIST); 00268 l = new DataType<ListType>(v); 00269 } else { 00270 *l = v; 00271 } 00272 return *this; 00273 } 00274 00276 bool operator==(const Element& o) const; 00277 00278 #if defined(__GNUC__) && __GNUC__ < 3 00279 bool operator!=(const Element& o) const 00280 { 00281 return !(*this == o); 00282 } 00283 #endif // defined(__GNUC__) && __GNUC__ < 3 00284 00286 template<class C> 00287 bool operator!=(C c) const 00288 { 00289 return !(*this == c); 00290 } 00291 00293 bool operator==(IntType v) const 00294 { 00295 return (t == TYPE_INT && i == v); 00296 } 00297 00299 bool operator==(FloatType v) const 00300 { 00301 return t == TYPE_FLOAT && f == v; 00302 } 00303 00305 bool operator==(PtrType v) const 00306 { 00307 return t == TYPE_PTR && p == v; 00308 } 00309 00311 bool operator==(const char * v) const 00312 { 00313 if(t == TYPE_STRING) 00314 return (*s == v); 00315 return false; 00316 } 00317 00319 bool operator==(const StringType& v) const 00320 { 00321 if(t == TYPE_STRING) 00322 return (*s == v); 00323 return false; 00324 } 00325 00327 bool operator==(const MapType& v) const 00328 { 00329 if(t == TYPE_MAP) 00330 return (*m == v); 00331 return false; 00332 } 00333 00335 bool operator==(const ListType& v) const 00336 { 00337 if (t == TYPE_LIST) 00338 return (*l == v); 00339 return false; 00340 } 00341 00343 Type getType() const { return t; } 00345 bool isNone() const { return (t == TYPE_NONE); } 00347 bool isInt() const { return (t == TYPE_INT); } 00349 bool isFloat() const { return (t == TYPE_FLOAT); } 00351 bool isPtr() const { return (t == TYPE_PTR); } 00353 bool isNum() const { return ((t == TYPE_FLOAT) || (t == TYPE_INT)); } 00355 bool isString() const { return (t == TYPE_STRING); } 00357 bool isMap() const { return (t == TYPE_MAP); } 00359 bool isList() const { return (t == TYPE_LIST); } 00360 00362 IntType asInt() const throw (WrongTypeException) 00363 { 00364 if (t == TYPE_INT) return i; 00365 throw WrongTypeException(); 00366 } 00367 IntType Int() const 00368 { 00369 return i; 00370 } 00372 FloatType asFloat() const throw (WrongTypeException) 00373 { 00374 if (t == TYPE_FLOAT) return f; 00375 throw WrongTypeException(); 00376 } 00377 FloatType Float() const 00378 { 00379 return f; 00380 } 00382 PtrType asPtr() const throw (WrongTypeException) 00383 { 00384 if (t == TYPE_PTR) return p; 00385 throw WrongTypeException(); 00386 } 00387 PtrType Ptr() const 00388 { 00389 return p; 00390 } 00392 FloatType asNum() const throw (WrongTypeException) 00393 { 00394 if (t == TYPE_FLOAT) return f; 00395 if (t == TYPE_INT) return FloatType(i); 00396 throw WrongTypeException(); 00397 } 00399 const std::string& asString() const throw (WrongTypeException) 00400 { 00401 if (t == TYPE_STRING) return *s; 00402 throw WrongTypeException(); 00403 } 00405 std::string& asString() throw (WrongTypeException) 00406 { 00407 if (t == TYPE_STRING) return *(s = s->makeUnique()); 00408 throw WrongTypeException(); 00409 } 00410 const StringType& String() const 00411 { 00412 return *s; 00413 } 00414 StringType& String() 00415 { 00416 return *(s = s->makeUnique()); 00417 } 00419 const MapType& asMap() const throw (WrongTypeException) 00420 { 00421 if (t == TYPE_MAP) return *m; 00422 throw WrongTypeException(); 00423 } 00425 MapType& asMap() throw (WrongTypeException) 00426 { 00427 if (t == TYPE_MAP) return *(m = m->makeUnique()); 00428 throw WrongTypeException(); 00429 } 00430 const MapType& Map() const 00431 { 00432 return *m; 00433 } 00434 MapType& Map() 00435 { 00436 return *(m = m->makeUnique()); 00437 } 00439 const ListType& asList() const throw (WrongTypeException) 00440 { 00441 if (t == TYPE_LIST) return *l; 00442 throw WrongTypeException(); 00443 } 00445 ListType& asList() throw (WrongTypeException) 00446 { 00447 if (t == TYPE_LIST) return *(l = l->makeUnique()); 00448 throw WrongTypeException(); 00449 } 00450 const ListType& List() const 00451 { 00452 return *l; 00453 } 00454 ListType& List() 00455 { 00456 return *(l = l->makeUnique()); 00457 } 00458 00459 static const char * typeName(Type); 00460 00461 protected: 00462 00463 template<class C> 00464 class DataType 00465 { 00466 public: 00467 DataType() : _refcount(1) {} 00468 DataType(const C& c) : _refcount(1), _data(c) {} 00469 00470 DataType& operator=(const C& c) {_data = c; return *this;} 00471 00472 bool operator==(const C& c) const {return _data == c;} 00473 00474 void ref() {++_refcount;} 00475 void unref() {if(--_refcount == 0) delete this;} 00476 00477 bool unique() const {return _refcount == 1;} 00478 DataType* makeUnique() 00479 { 00480 if(unique()) 00481 return this; 00482 unref(); // _refcount > 1, so this is fine 00483 return new DataType(_data); 00484 } 00485 00486 operator C&() {return _data;} 00487 // operator const C&() const {return _data;} 00488 00489 private: 00490 DataType(const DataType&); // unimplemented 00491 DataType& operator=(const DataType&); // unimplemented 00492 00493 unsigned long _refcount; 00494 C _data; 00495 }; 00496 00497 Type t; 00498 union { 00499 IntType i; 00500 FloatType f; 00501 void* p; 00502 DataType<StringType>* s; 00503 DataType<MapType>* m; 00504 DataType<ListType>* l; 00505 }; 00506 }; 00507 00508 } } // namespace Atlas::Message 00509 00510 00511 #endif // ATLAS_MESSAGE_ELEMENT_H
Copyright 2000-2004 the respective authors.
This document can be licensed under the terms of the GNU Free Documentation License or the GNU General Public License and may be freely distributed under the terms given by one of these licenses.