BaseObject.h

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.