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 
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.