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