Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

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