DynamicType.hxx

Go to the documentation of this file.
00001 /* DynamicType.hxx: interface for the DynamicType class.
00002  * written by Pau Arumí - May 2001
00003  * new version (that stores every type) : 21-July-2001
00004  *
00005  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00006  *                         UNIVERSITAT POMPEU FABRA
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 #ifndef _DynamicType_
00026 #define _DynamicType_
00027 
00028 #include "XMLAdapter.hxx"
00029 #include "XMLIterableAdapter.hxx"
00030 #include "XMLComponentAdapter.hxx"
00031 
00032 #include "DynamicTypeMacros.hxx"  //this file is not included anywhere but here.
00033 
00034 #include "Component.hxx"
00035 #include "DataTypes.hxx"
00036 
00037 #include <new>
00038 
00039 namespace CLAM {
00040 
00042 // Class DynamicType declaration :
00043 //
00045 
00046 
00070 class DynamicType : public Component
00071 {
00072 public:
00080         DynamicType(const int nAttr);
00081 
00091         DynamicType(const DynamicType& prototype, const bool shareData, const bool deepCopy);
00092         DynamicType(const DynamicType& prototype);
00093         virtual ~DynamicType();
00094         
00095         virtual const char* GetClassName() const =0;
00096 protected:
00105         void DefaultInit() {
00106         
00107         };
00108 
00113         virtual void InformAll() {
00114                         // lets calculates the offsets of the "Pre allocated mode"
00115                 CLAM_DEBUG_ASSERT(typeDescTable,"static table don't exist. in DT::InformAll()");
00116                 int adder=0;
00117                 for (unsigned int i=0; i<numAttr; i++) {
00118                         typeDescTable[i].offset = adder;
00119                         adder += typeDescTable[i].size;
00120                 }
00121                 maxAttrSize = adder;
00122 
00123         };
00124 
00125 public:
00133         void CopyInit(const DynamicType & dt) {
00134         };
00135 
00145         bool UpdateData();
00146         
00147 private:
00148         // Types of the constructors and destructors that all registerd type must have.
00149         // A pointer to these functions is stored into the typeDescTable. (an array of TAttr) 
00150         // The definition of TAttr is following:
00151         typedef void* (*t_new)(void* pos);
00152         typedef void* (*t_new_copy)(void* pos,void* orig);
00153         typedef void (*t_destructor)(void* pos);
00154 
00155         virtual void InformAttr_ (unsigned id, const char* name, unsigned size, const char* type, const bool isPtr,
00156                                const t_new, const t_new_copy, const t_destructor);
00157 
00158 protected:
00159         inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
00160                                   const t_new, const t_new_copy, const t_destructor, const Component* ptr);
00161 
00162         inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
00163                                   const t_new, const t_new_copy, const t_destructor, const DynamicType* ptr);
00164 
00165         inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
00166                                   const t_new, const t_new_copy, const t_destructor, const void* ptr);
00167         
00168         void AddAttr_ (const unsigned i, const unsigned size);
00169         void RemoveAttr_ (const unsigned id);
00170 
00171 public:
00172         unsigned GetNDynamicAttributes() const { return numAttr; }
00173         const char * GetDynamicAttributeName(unsigned i) { return typeDescTable[i].id; }
00174         virtual const std::type_info & GetTypeId(unsigned i) const=0;
00175         bool AttributeIsComponent(unsigned i) const {return typeDescTable[i].isComponent; }
00176         bool AttributeIsDynamictype(unsigned i) const {return typeDescTable[i].isDynamicType; }
00177         bool IsAttributeInstantiated(unsigned i) const {return dynamicTable[i].offs!=-1; }
00178         const void * GetAttributeAsVoidPtr(unsigned i) const {
00179                 return GetPtrToData_(i);
00180         }
00181         const Component * GetAttributeAsComponent(unsigned i) const {
00182                 if (!typeDescTable[i].isComponent) return 0;
00183                 return static_cast<const Component *> (GetPtrToData_(i));
00184         }
00185         Component * GetAttributeAsComponent(unsigned i) {
00186                 if (! (typeDescTable[i].isComponent)) return 0;
00187                 return static_cast<Component *> (GetPtrToData_(i));
00188         }
00189         void FullfilsInvariant() const;
00190 
00191         virtual Component* DeepCopy() const;
00192 public:
00193         enum {idLength = 120, typeLength = 120}; //TODO: rise exception if the type is too long
00194 
00195 protected:
00196         enum {shrinkThreshold = 80}; // Bytes.  That constant means that when updating data, if the
00197                                      // used data disminish an amount superior that this threshold,
00198                                      // data will be reallocated (shrunk)
00199         // item of the typeDescTable, that is static created only once in the concrete class constructor
00200         struct TAttr
00201         {
00202                 char id[idLength];                   
00203                 char type[typeLength];
00204                 int size;
00205                 int offset;
00206                 t_new newObj;
00207                 t_new_copy newObjCopy;
00208                 t_destructor destructObj;
00209 
00210 //              bool isInformed : 1;   Deprecated!! Now the concrete constr. calls InformAll() chain.method.
00211                 bool isComponent : 1;
00212                 bool isStorable : 1;
00213                 bool isDynamicType : 1;
00214                 bool isPointer : 1;
00215         };
00216 
00217         // item of the dynamicTable, that holds the dynamic information of the dynamic type
00218         struct TDynInfo
00219         {
00220                 int offs;  // attribute offset of the data table. Has a -1 value when
00221                            // the attr is not instantiated (have no entry at the data table).
00222                 bool hasBeenAdded : 1;
00223                 bool hasBeenRemoved : 1;
00224         };
00225         virtual DynamicType& GetDynamicTypeCopy(const bool shareData = false, const bool deep = false) const =0;
00226         virtual Component* ShallowCopy() const;
00227         DynamicType& operator= (const DynamicType& source);
00228 
00229 
00230         // Public Accesors to protected data. Necesary in the implementation of Branches (aggregates)
00231         inline unsigned    GetNumAttr() const { return numAttr; };
00232         inline unsigned    GetNumActiveAttr() const { return numActiveAttr; }
00233         inline char*       GetData() const { return data; }
00234         inline void        SetData(char* srcData) { data = srcData;}
00235         inline TDynInfo*   GetDynamicTable() const { return dynamicTable; }
00236         inline TAttr*      GetTypeDescTable() const { return typeDescTable; }
00237         inline unsigned    GetDataSize() const { return dataSize; }
00238         inline bool        IsInstanciate() const { return (data != 0); }
00239         inline bool        OwnsItsMemory() const { return bOwnsItsMemory; }
00240         inline void        SetOwnsItsMemory(const bool owns) { bOwnsItsMemory = owns; }
00241         inline bool        ExistAttr(unsigned id) const;
00242         inline void        SetPreAllocateAllAttributes() { bPreAllocateAllAttributes=true; }
00243 
00244 
00245 public:
00246         // Developing tools:
00247         void Debug() const;
00248 
00249 protected:
00250         
00251         unsigned        numActiveAttr;
00252         char            *data;
00253         TDynInfo        *dynamicTable;
00254         TAttr           *typeDescTable;
00255         unsigned        dataSize;
00256         bool            bOwnsItsMemory;
00257         unsigned                numAttr;    // the total number of dyn. attrs.
00258         unsigned                maxAttrSize;    // the total dyn. attrs. size
00259         unsigned        allocatedDataSize;
00260 
00261         inline int      DynTableRefCounter();
00262         inline void     InitDynTableRefCounter();
00263         inline int      DecrementDynTableRefCounter();
00264         inline int      IncrementDynTableRefCounter();
00265 
00266 private:
00267         inline bool   AttrHasData(unsigned i) const { return (dynamicTable[i].offs > -1); };
00268         inline void   RemoveAllMem();
00269         inline void*  GetPtrToData_(const unsigned id) const;
00270         inline void*  GetDataAsPtr_(const unsigned id) const;
00271         inline void   SetDataAsPtr_(const unsigned id, void* p);
00272         
00274         void BeMemoryOwner();
00280         void UpdateDataByShrinking();
00281 
00286         void UpdateDataByStandardMode();
00287         
00291         void UpdateDataGoingToPreAllocatedMode();
00292         
00296         void UpdateDataInPreAllocatedMode();
00297 
00298         void SelfCopyPrototype(const DynamicType &orig);
00299         void SelfSharedCopy(const DynamicType &orig);
00300         void SelfShallowCopy(const DynamicType &orig);
00301         void SelfDeepCopy(const DynamicType &orig);
00302         bool bPreAllocateAllAttributes;
00303 
00304 public:
00305         virtual void StoreOn(CLAM::Storage & storage) const {
00306                 this->StoreDynAttributes(storage);
00307         }
00308         virtual void LoadFrom(CLAM::Storage & storage) {
00309                 this->LoadDynAttributes(storage);
00310         }
00311         template <unsigned int NAttrib> 
00312         class AttributePositionBase { 
00313         public:
00314                 static const int value;
00315         };
00316         
00317 protected:
00318         virtual void StoreDynAttributes(CLAM::Storage & s) const=0;
00319         virtual void LoadDynAttributes(CLAM::Storage & s)=0;
00320         template <typename AttribType>
00321         void StoreAttribute(StaticTrue* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) const 
00322         {
00323                 CLAM::XMLAdapter<AttribType> adapter(object, name, true);
00324                 s.Store (adapter);
00325         }
00326         template <typename AttribType>
00327         void StoreAttribute(StaticFalse* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) const
00328         {
00329                 CLAM::XMLComponentAdapter adapter(object, name, true);
00330                 s.Store (adapter);
00331         } 
00332         template <typename AttribType>
00333         void StoreIterableAttribute(CLAM::Storage &s ,AttribType & object, const char* name, const char* elemName) const
00334         {
00335                 CLAM::XMLIterableAdapter<AttribType> adapter(object, elemName, name, true);
00336                 s.Store (adapter);
00337         } 
00338 
00339         template <typename AttribType>
00340         bool LoadAttribute(StaticTrue* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) {
00341                 CLAM::XMLAdapter<AttribType> adapter(object, name, true);
00342                 return s.Load (adapter);        
00343         }
00344         template <typename AttribType>
00345         bool LoadAttribute(StaticFalse* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) {
00346                 CLAM::XMLComponentAdapter adapter(object, name, true);
00347                 return s.Load (adapter);        
00348         } 
00349         template <typename AttribType>
00350         bool LoadIterableAttribute(CLAM::Storage &s ,AttribType & object, const char* name, const char* elemName) {
00351                 CLAM::XMLIterableAdapter<AttribType> adapter(object, elemName, name, true);
00352                 return s.Load (adapter);
00353         } 
00354 };
00355 
00356 
00358 // STATIC MEMBERS DEFINITION
00359 
00360 template <unsigned int NAttrib> const int DynamicType::AttributePositionBase<NAttrib>::value = NAttrib;
00361 
00363 // IMPLEMENTATION OF INLINE FUNCTIONS
00364 
00365 inline bool DynamicType::ExistAttr(unsigned id) const 
00366 { 
00367 
00368         if (!data) return false;
00369 
00370         TDynInfo &inf = dynamicTable[id];
00371         return (inf.offs != -1 && !inf.hasBeenAdded && !inf.hasBeenRemoved); 
00372 }
00373 
00374 inline void* DynamicType::GetDataAsPtr_(const unsigned id) const
00375 {
00376         return *(void**)&data[dynamicTable[id].offs];
00377 }
00378 
00379 inline void* DynamicType::GetPtrToData_(const unsigned id) const
00380 {
00381         return (void*)&data[dynamicTable[id].offs];
00382 }
00383 
00384 inline void DynamicType::SetDataAsPtr_(const unsigned id, void* p)
00385 {
00386         *(void**)&data[dynamicTable[id].offs] = p;
00387 }
00388 
00389 
00391 
00392 
00393 
00394 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
00395                                        const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const void* ptr)
00396 {
00397         InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
00398         typeDescTable[val].isComponent = false;
00399         typeDescTable[val].isDynamicType = false;
00400         typeDescTable[val].isStorable = false;
00401 }
00402 
00403 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
00404                                        const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const Component* ptr)
00405 {
00406         InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
00407         typeDescTable[val].isComponent = true;
00408         typeDescTable[val].isDynamicType = false;
00409         typeDescTable[val].isStorable = false;
00410 }
00411 
00412 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
00413                                        const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const DynamicType* ptr)
00414 {
00415         InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
00416         typeDescTable[val].isComponent = true;
00417         typeDescTable[val].isDynamicType = true;
00418         typeDescTable[val].isStorable = false;
00419 }
00420 
00421 
00422 } //namespace CLAM
00423 
00424 #endif // !defined _DynamicType_
00425 
Generated by  doxygen 1.6.3