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-2004 Stefanus Du Toit, Aloril and Al Riddoch 00004 00005 #ifndef ATLAS_OBJECTS_BASEOBJECT_H 00006 #define ATLAS_OBJECTS_BASEOBJECT_H 00007 00008 #include <Atlas/Message/MEncoder.h> 00009 #include <Atlas/Message/Element.h> 00010 #include <Atlas/Bridge.h> 00011 #include <Atlas/Exception.h> 00012 00013 #include <map> 00014 #include <list> 00015 #include <string> 00016 00017 #include <assert.h> 00018 00019 namespace Atlas { 00020 00024 namespace Objects { 00025 00030 class NoSuchAttrException : public Atlas::Exception 00031 { 00033 std::string m_name; 00034 public: 00035 NoSuchAttrException(const std::string& name) : 00036 Atlas::Exception("No such attribute"), m_name(name) {} 00037 virtual ~NoSuchAttrException() throw (); 00039 const std::string & getName() const { 00040 return m_name; 00041 } 00042 }; 00043 00044 static const int BASE_OBJECT_NO = 0; 00045 00065 class BaseObjectData 00066 { 00067 public: 00072 BaseObjectData(BaseObjectData *defaults) : 00073 m_class_no(BASE_OBJECT_NO), m_defaults(defaults) 00074 { 00075 if(defaults) m_attrFlags = 0; 00076 else m_attrFlags = -1; //this is default object: all attributes here 00077 m_refCount = 0; 00078 } 00079 00080 virtual ~BaseObjectData(); 00081 00083 int getClassNo() const 00084 { 00085 return m_class_no; 00086 } 00087 00088 virtual BaseObjectData * copy() const = 0; 00089 00091 virtual bool instanceOf(int classNo) const; 00092 00094 bool hasAttr(const std::string& name) const; 00096 bool hasAttrFlag(int flag) const; 00099 const Atlas::Message::Element getAttr(const std::string& name) 00100 const throw (NoSuchAttrException); 00103 virtual int copyAttr(const std::string& name, 00104 Atlas::Message::Element & attr) const; 00106 virtual void setAttr(const std::string& name, 00107 const Atlas::Message::Element& attr); 00109 virtual void removeAttr(const std::string& name); 00111 virtual void removeAttrFlag(int flag); 00112 00115 const Atlas::Message::MapType asMessage() const; 00116 00118 virtual void addToMessage(Atlas::Message::MapType &) const; 00119 00121 virtual void sendContents(Atlas::Bridge & b) const; 00122 00123 //move to protected once SmartPtr <-> BaseObject order established 00124 inline void incRef(); 00125 inline void decRef(); 00126 00132 static BaseObjectData *alloc() {assert(0); return NULL;} //not callable 00137 virtual void free() = 0; 00138 00139 class const_iterator; 00140 00141 // FIXME should this hold a reference to the object it's 00142 // iterating over? 00143 00158 class iterator 00159 { 00160 public: 00161 friend class BaseObjectData; 00162 friend class const_iterator; 00163 00164 iterator() : m_obj(0), m_val("", *this) {} 00165 iterator(const iterator& I) : m_obj(I.m_obj), 00166 m_current_class(I.m_current_class), 00167 m_I(I.m_I), m_val(I.m_val.first, *this) {} 00168 iterator(BaseObjectData& obj, int current_class); 00169 00170 // default destructor is fine unless we hold a reference to m_obj 00171 00172 iterator& operator=(const iterator& I); 00173 00174 iterator& operator++(); // preincrement 00175 00176 inline iterator operator++(int); // postincrement 00177 00178 bool operator==(const iterator& I) const; 00179 00180 bool operator!=(const iterator& I) const {return !operator==(I);} 00181 00182 class PsuedoElement 00183 { 00184 public: 00185 PsuedoElement(const iterator& I) : m_I(I) {} 00186 00187 operator Message::Element() const; 00188 // this acts on const PsuedoElement instead of PsuedoElement 00189 // so that we can assign to attributes refered to by 00190 // a const iterator& (as opposed to a const_iterator, where 00191 // we can't, but that's done later) 00192 const PsuedoElement& operator=(const Message::Element& val) const; 00193 00194 private: 00195 const iterator& m_I; 00196 }; 00197 00198 friend class PsuedoElement; 00199 00200 typedef std::pair<std::string,PsuedoElement> value_type; 00201 00202 const value_type& operator*() const {return m_val;} 00203 const value_type* operator->() const {return &m_val;} 00204 00205 private: 00206 BaseObjectData *m_obj; // pointer to object whose args we're iterating 00207 int m_current_class; // m_class_no for current class in the iteration 00208 Message::MapType::iterator m_I; // iterator in m_obj->m_attributes 00209 value_type m_val; 00210 }; 00211 friend class iterator; 00212 00213 // FIXME should this hold a reference to the object it's 00214 // iterating over? 00215 class const_iterator 00216 { 00217 public: 00218 friend class BaseObjectData; 00219 00220 const_iterator() : m_obj(0), m_val("", *this) {} 00221 const_iterator(const const_iterator& I) : m_obj(I.m_obj), 00222 m_current_class(I.m_current_class), 00223 m_I(I.m_I), m_val(I.m_val.first, *this) {} 00224 const_iterator(const iterator& I) : m_obj(I.m_obj), 00225 m_current_class(I.m_current_class), 00226 m_I(I.m_I), m_val(I.m_val.first, *this) {} 00227 const_iterator(const BaseObjectData& obj, int current_class); 00228 00229 // default destructor is fine unless we hold a reference to m_obj 00230 00231 const_iterator& operator=(const const_iterator& I); 00232 00233 const_iterator& operator++(); // preincrement 00234 00235 inline const_iterator operator++(int); // postincrement 00236 00237 bool operator==(const const_iterator& I) const; 00238 00239 bool operator!=(const const_iterator& I) const {return !operator==(I);} 00240 00241 class PsuedoElement 00242 { 00243 public: 00244 PsuedoElement(const const_iterator& I) : m_I(I) {} 00245 00246 operator Message::Element() const; 00247 00248 private: 00249 const const_iterator& m_I; 00250 }; 00251 00252 friend class PsuedoElement; 00253 00254 typedef std::pair<std::string,PsuedoElement> value_type; 00255 00256 const value_type& operator*() const {return m_val;} 00257 const value_type* operator->() const {return &m_val;} 00258 00259 private: 00260 const BaseObjectData *m_obj; // pointer to object whose args we're iterating 00261 int m_current_class; // m_class_no for current class in the iteration 00262 Message::MapType::const_iterator m_I; // const_iterator in m_obj->m_attributes 00263 value_type m_val; 00264 }; 00265 00266 friend class const_iterator; 00267 00268 iterator begin() {return iterator(*this, -1);} 00269 iterator end() {return iterator(*this, BASE_OBJECT_NO);} 00270 iterator find(const std::string&); 00271 00272 const_iterator begin() const {return const_iterator(*this, -1);} 00273 const_iterator end() const {return const_iterator(*this, BASE_OBJECT_NO);} 00274 const_iterator find(const std::string&) const; 00275 00276 protected: 00277 00279 virtual int getAttrClass(const std::string& name) const; 00280 00282 virtual int getAttrFlag(const std::string& name) const; 00283 00285 virtual void iterate(int& current_class, std::string& attr) const; 00286 00287 int m_class_no; //each class has different enum 00288 int m_refCount; //how many instances 00289 BaseObjectData *m_defaults; 00290 //this will be defined in each subclass separately, so no need here for it 00291 //static BaseObjectData *begin; 00292 BaseObjectData *m_next; 00293 std::map<std::string, Atlas::Message::Element> m_attributes; 00294 // is attribute in this object or in default object? 00295 int m_attrFlags; 00296 }; 00297 00298 void BaseObjectData::incRef() { 00299 m_refCount++; 00300 } 00301 00302 void BaseObjectData::decRef() { 00303 //why zero based refCount? avoids one m_refCount-- ;-) 00304 assert( m_refCount >= 0 ); 00305 if(!m_refCount) { 00306 free(); 00307 return; 00308 } 00309 m_refCount--; 00310 } 00311 00312 BaseObjectData::iterator BaseObjectData::iterator::operator++(int) // postincrement 00313 { 00314 iterator tmp = *this; 00315 operator++(); 00316 return tmp; 00317 } 00318 00319 BaseObjectData::const_iterator BaseObjectData::const_iterator::operator++(int) // postincrement 00320 { 00321 const_iterator tmp = *this; 00322 operator++(); 00323 return tmp; 00324 } 00325 00326 00327 } } // namespace Atlas::Objects 00328 00329 #endif
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.