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); 00110 00113 const Atlas::Message::MapType asMessage() const; 00114 00116 virtual void addToMessage(Atlas::Message::MapType &) const; 00117 00119 virtual void sendContents(Atlas::Bridge & b) const; 00120 00121 //move to protected once SmartPtr <-> BaseObject order established 00122 inline void incRef(); 00123 inline void decRef(); 00124 00130 static BaseObjectData *alloc() {assert(0); return NULL;} //not callable 00135 virtual void free() = 0; 00136 00137 class const_iterator; 00138 00139 // FIXME should this hold a reference to the object it's 00140 // iterating over? 00141 00156 class iterator 00157 { 00158 public: 00159 friend class BaseObjectData; 00160 friend class const_iterator; 00161 00162 iterator() : m_obj(0), m_val("", *this) {} 00163 iterator(const iterator& I) : m_obj(I.m_obj), 00164 m_current_class(I.m_current_class), 00165 m_I(I.m_I), m_val(I.m_val.first, *this) {} 00166 iterator(BaseObjectData& obj, int current_class); 00167 00168 // default destructor is fine unless we hold a reference to m_obj 00169 00170 iterator& operator=(const iterator& I); 00171 00172 iterator& operator++(); // preincrement 00173 00174 inline iterator operator++(int); // postincrement 00175 00176 bool operator==(const iterator& I) const; 00177 00178 bool operator!=(const iterator& I) const {return !operator==(I);} 00179 00180 class PsuedoElement 00181 { 00182 public: 00183 PsuedoElement(const iterator& I) : m_I(I) {} 00184 00185 operator Message::Element() const; 00186 // this acts on const PsuedoElement instead of PsuedoElement 00187 // so that we can assign to attributes refered to by 00188 // a const iterator& (as opposed to a const_iterator, where 00189 // we can't, but that's done later) 00190 const PsuedoElement& operator=(const Message::Element& val) const; 00191 00192 private: 00193 const iterator& m_I; 00194 }; 00195 00196 friend class PsuedoElement; 00197 00198 typedef std::pair<std::string,PsuedoElement> value_type; 00199 00200 const value_type& operator*() const {return m_val;} 00201 const value_type* operator->() const {return &m_val;} 00202 00203 private: 00204 BaseObjectData *m_obj; // pointer to object whose args we're iterating 00205 int m_current_class; // m_class_no for current class in the iteration 00206 Message::MapType::iterator m_I; // iterator in m_obj->m_attributes 00207 value_type m_val; 00208 }; 00209 friend class iterator; 00210 00211 // FIXME should this hold a reference to the object it's 00212 // iterating over? 00213 class const_iterator 00214 { 00215 public: 00216 friend class BaseObjectData; 00217 00218 const_iterator() : m_obj(0), m_val("", *this) {} 00219 const_iterator(const const_iterator& I) : m_obj(I.m_obj), 00220 m_current_class(I.m_current_class), 00221 m_I(I.m_I), m_val(I.m_val.first, *this) {} 00222 const_iterator(const iterator& I) : m_obj(I.m_obj), 00223 m_current_class(I.m_current_class), 00224 m_I(I.m_I), m_val(I.m_val.first, *this) {} 00225 const_iterator(const BaseObjectData& obj, int current_class); 00226 00227 // default destructor is fine unless we hold a reference to m_obj 00228 00229 const_iterator& operator=(const const_iterator& I); 00230 00231 const_iterator& operator++(); // preincrement 00232 00233 inline const_iterator operator++(int); // postincrement 00234 00235 bool operator==(const const_iterator& I) const; 00236 00237 bool operator!=(const const_iterator& I) const {return !operator==(I);} 00238 00239 class PsuedoElement 00240 { 00241 public: 00242 PsuedoElement(const const_iterator& I) : m_I(I) {} 00243 00244 operator Message::Element() const; 00245 00246 private: 00247 const const_iterator& m_I; 00248 }; 00249 00250 friend class PsuedoElement; 00251 00252 typedef std::pair<std::string,PsuedoElement> value_type; 00253 00254 const value_type& operator*() const {return m_val;} 00255 const value_type* operator->() const {return &m_val;} 00256 00257 private: 00258 const BaseObjectData *m_obj; // pointer to object whose args we're iterating 00259 int m_current_class; // m_class_no for current class in the iteration 00260 Message::MapType::const_iterator m_I; // const_iterator in m_obj->m_attributes 00261 value_type m_val; 00262 }; 00263 00264 friend class const_iterator; 00265 00266 iterator begin() {return iterator(*this, -1);} 00267 iterator end() {return iterator(*this, BASE_OBJECT_NO);} 00268 iterator find(const std::string&); 00269 00270 const_iterator begin() const {return const_iterator(*this, -1);} 00271 const_iterator end() const {return const_iterator(*this, BASE_OBJECT_NO);} 00272 const_iterator find(const std::string&) const; 00273 00274 protected: 00275 00277 virtual int getAttrClass(const std::string& name) const; 00278 00280 virtual int getAttrFlag(const std::string& name) const; 00281 00283 virtual void iterate(int& current_class, std::string& attr) const; 00284 00285 int m_class_no; //each class has different enum 00286 int m_refCount; //how many instances 00287 BaseObjectData *m_defaults; 00288 //this will be defined in each subclass separately, so no need here for it 00289 //static BaseObjectData *begin; 00290 BaseObjectData *m_next; 00291 std::map<std::string, Atlas::Message::Element> m_attributes; 00292 // is attribute in this object or in default object? 00293 int m_attrFlags; 00294 }; 00295 00296 void BaseObjectData::incRef() { 00297 m_refCount++; 00298 } 00299 00300 void BaseObjectData::decRef() { 00301 //why zero based refCount? avoids one m_refCount-- ;-) 00302 assert( m_refCount >= 0 ); 00303 if(!m_refCount) { 00304 free(); 00305 return; 00306 } 00307 m_refCount--; 00308 } 00309 00310 BaseObjectData::iterator BaseObjectData::iterator::operator++(int) // postincrement 00311 { 00312 iterator tmp = *this; 00313 operator++(); 00314 return tmp; 00315 } 00316 00317 BaseObjectData::const_iterator BaseObjectData::const_iterator::operator++(int) // postincrement 00318 { 00319 const_iterator tmp = *this; 00320 operator++(); 00321 return tmp; 00322 } 00323 00324 00325 } } // namespace Atlas::Objects 00326 00327 #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.