Atlas-C++
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 // $Id$
00006 
00007 #ifndef ATLAS_OBJECTS_BASEOBJECT_H
00008 #define ATLAS_OBJECTS_BASEOBJECT_H
00009 
00010 #include <Atlas/Message/MEncoder.h>
00011 #include <Atlas/Message/Element.h>
00012 #include <Atlas/Bridge.h>
00013 #include <Atlas/Exception.h>
00014 
00015 #include <map>
00016 #include <list>
00017 #include <string>
00018 
00019 #include <assert.h>
00020 
00021 namespace Atlas {
00022 
00026 namespace Objects {
00027 
00032 class NoSuchAttrException : public Atlas::Exception
00033 {
00035     std::string m_name;
00036   public:
00037     NoSuchAttrException(const std::string& name) :
00038              Atlas::Exception("No such attribute"), m_name(name) {}
00039     virtual ~NoSuchAttrException() throw ();
00041     const std::string & getName() const {
00042         return m_name;
00043     }
00044 };
00045 
00046 static const int BASE_OBJECT_NO = 0;
00047 
00067 class BaseObjectData
00068 {
00069 public:
00074     BaseObjectData(BaseObjectData *defaults);
00075 
00076     virtual ~BaseObjectData();
00077 
00079     int getClassNo() const 
00080     {
00081         return m_class_no;
00082     }
00083 
00084     int getAttrFlags() const
00085     {
00086         return m_attrFlags;
00087     }
00088 
00089     virtual BaseObjectData * copy() const = 0;
00090 
00092     virtual bool instanceOf(int classNo) const;
00093     
00095     bool hasAttr(const std::string& name) const;
00097     bool hasAttrFlag(int flag) const;
00100     const Atlas::Message::Element getAttr(const std::string& name)
00101         const throw (NoSuchAttrException);
00104     virtual int copyAttr(const std::string& name,
00105                          Atlas::Message::Element & attr) const;
00107     virtual void setAttr(const std::string& name,
00108                          const Atlas::Message::Element& attr);
00110     virtual void removeAttr(const std::string& name);
00112     virtual void removeAttrFlag(int flag);
00113 
00116     const Atlas::Message::MapType asMessage() const;
00117 
00119     virtual void addToMessage(Atlas::Message::MapType &) const;
00120 
00122     virtual void sendContents(Atlas::Bridge & b) const;
00123 
00124     //move to protected once SmartPtr <-> BaseObject order established
00125     inline void incRef();
00126     inline void decRef();
00127 
00133     static BaseObjectData *alloc() {assert(0); return NULL;} //not callable
00138     virtual void free() = 0;
00139 
00140     class const_iterator;
00141 
00142     // FIXME should this hold a reference to the object it's
00143     // iterating over?
00144 
00159     class iterator
00160     {
00161     public:
00162         friend class BaseObjectData;
00163         friend class const_iterator;
00164 
00165         iterator() : m_obj(0), m_val("", *this) {}
00166         iterator(const iterator& I) : m_obj(I.m_obj),
00167             m_current_class(I.m_current_class),
00168             m_I(I.m_I), m_val(I.m_val.first, *this) {}
00169         iterator(BaseObjectData& obj, int current_class);
00170 
00171         // default destructor is fine unless we hold a reference to m_obj
00172 
00173         iterator& operator=(const iterator& I);
00174 
00175         iterator& operator++(); // preincrement
00176 
00177         inline iterator operator++(int); // postincrement
00178 
00179         bool operator==(const iterator& I) const;
00180 
00181         bool operator!=(const iterator& I) const {return !operator==(I);}
00182 
00183         class PsuedoElement
00184         {
00185             public:
00186                 PsuedoElement(const iterator& I) : m_I(I) {}
00187 
00188                 operator Message::Element() const;
00189                 // this acts on const PsuedoElement instead of PsuedoElement
00190                 // so that we can assign to attributes refered to by
00191                 // a const iterator& (as opposed to a const_iterator, where
00192                 // we can't, but that's done later)
00193                 const PsuedoElement& operator=(const Message::Element& val) const;
00194 
00195             private:
00196                 const iterator& m_I;
00197         };
00198 
00199         friend class PsuedoElement;
00200 
00201         typedef std::pair<std::string,PsuedoElement> value_type;
00202 
00203         const value_type& operator*() const {return m_val;}
00204         const value_type* operator->() const {return &m_val;}
00205 
00206     private:
00207         BaseObjectData *m_obj; // pointer to object whose args we're iterating
00208         int m_current_class; // m_class_no for current class in the iteration
00209         Message::MapType::iterator m_I; // iterator in m_obj->m_attributes
00210         value_type m_val;
00211     };
00212     friend class iterator;
00213 
00214     // FIXME should this hold a reference to the object it's
00215     // iterating over?
00216     class const_iterator
00217     {
00218     public:
00219         friend class BaseObjectData;
00220 
00221         const_iterator() : m_obj(0), m_val("", *this) {}
00222         const_iterator(const 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 iterator& I) : m_obj(I.m_obj),
00226             m_current_class(I.m_current_class),
00227             m_I(I.m_I), m_val(I.m_val.first, *this) {}
00228         const_iterator(const BaseObjectData& obj, int current_class);
00229 
00230         // default destructor is fine unless we hold a reference to m_obj
00231 
00232         const_iterator& operator=(const const_iterator& I);
00233 
00234         const_iterator& operator++(); // preincrement
00235 
00236         inline const_iterator operator++(int); // postincrement
00237 
00238         bool operator==(const const_iterator& I) const;
00239 
00240         bool operator!=(const const_iterator& I) const {return !operator==(I);}
00241 
00242         class PsuedoElement
00243         {
00244             public:
00245                 PsuedoElement(const const_iterator& I) : m_I(I) {}
00246 
00247                 operator Message::Element() const;
00248 
00249             private:
00250                 const const_iterator& m_I;
00251         };
00252 
00253         friend class PsuedoElement;
00254 
00255         typedef std::pair<std::string,PsuedoElement> value_type;
00256 
00257         const value_type& operator*() const {return m_val;}
00258         const value_type* operator->() const {return &m_val;}
00259 
00260     private:
00261         const BaseObjectData *m_obj; // pointer to object whose args we're iterating
00262         int m_current_class; // m_class_no for current class in the iteration
00263         Message::MapType::const_iterator m_I; // const_iterator in m_obj->m_attributes
00264         value_type m_val;
00265     };
00266 
00267     friend class const_iterator;
00268 
00269     iterator begin() {return iterator(*this, -1);}
00270     iterator end() {return iterator(*this, BASE_OBJECT_NO);}
00271     iterator find(const std::string&);
00272 
00273     const_iterator begin() const {return const_iterator(*this, -1);}
00274     const_iterator end() const {return const_iterator(*this, BASE_OBJECT_NO);}
00275     const_iterator find(const std::string&) const;
00276 
00277 protected:
00278 
00280     virtual int getAttrClass(const std::string& name) const;
00281 
00283     virtual int getAttrFlag(const std::string& name) const;
00284 
00286     virtual void iterate(int& current_class, std::string& attr) const;
00287 
00288     int m_class_no; //each class has different enum
00289     int m_refCount; //how many instances 
00290     BaseObjectData *m_defaults;
00291     //this will be defined in each subclass separately, so no need here for it
00292     //static BaseObjectData *begin; 
00293     BaseObjectData *m_next;
00294     std::map<std::string, Atlas::Message::Element> m_attributes;
00295     // is attribute in this object or in default object?
00296     int m_attrFlags;
00297 };
00298 
00299 void BaseObjectData::incRef() {
00300     m_refCount++;
00301 }
00302 
00303 void BaseObjectData::decRef() {
00304     //why zero based refCount? avoids one m_refCount-- ;-)
00305     assert( m_refCount >= 0 );
00306     if(!m_refCount) {
00307         free();
00308         return;
00309     }
00310     m_refCount--;
00311 }
00312 
00313 BaseObjectData::iterator BaseObjectData::iterator::operator++(int) // postincrement
00314 {
00315     iterator tmp = *this;
00316     operator++();
00317     return tmp;
00318 }
00319 
00320 BaseObjectData::const_iterator BaseObjectData::const_iterator::operator++(int) // postincrement
00321 {
00322     const_iterator tmp = *this;
00323     operator++();
00324     return tmp;
00325 }
00326 
00327 
00328 } } // namespace Atlas::Objects
00329 
00330 #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.