ScopePool.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef _ScopePool_hxx_
00023 #define _ScopePool_hxx_
00024 
00025 #include "AttributePool.hxx"
00026 #include "DescriptionScope.hxx"
00027 
00028 // TODO TO-TEST:
00029 // Reading an non existent attribute
00030 // Not reading an existent attribute
00031 // Unordered attributes
00032 // Twice present attributes
00033 
00034 namespace CLAM
00035 {
00041         class ScopePool : public Component
00042         {
00043                 friend class AttributePoolStorageProxy;
00044                 class AttributePoolStorageProxy : public Component
00045                 {
00046                                 ScopePool & pool;
00047                         public:
00048                                 AttributePoolStorageProxy(ScopePool & scopePool)
00049                                         : pool(scopePool)
00050                                 {
00051                                 }
00052                                 const char* GetClassName() const { return "AttributeProxy"; }
00053                                 void StoreOn(CLAM::Storage&) const {}
00054                                 void LoadFrom(Storage & storage)
00055                                 {
00056                                         std::string name;
00057                                         XMLAdapter<std::string> nameAdapter(name,"name",false);
00058                                         storage.Load(nameAdapter);
00059                                         unsigned attributeIndex = pool._spec.GetIndexSafe(name);
00060                                         pool._attributePools[attributeIndex].Allocate(pool._size);
00061                                         XMLComponentAdapter adapter(pool._attributePools[attributeIndex]);
00062                                         storage.Load(adapter);
00063                                 }
00064                 };
00065         public:
00066                 typedef std::vector<AttributePool> AttributesData;
00067         private:
00068                 unsigned _size;
00069                 const DescriptionScope & _spec;
00070                 AttributesData _attributePools;
00071         public:
00072                 ScopePool(const DescriptionScope & spec, unsigned size=0)
00073                         : _size(size), _spec(spec), _attributePools(spec.GetNAttributes())
00074                 {
00075                         AttributesData::iterator it = _attributePools.begin();
00076                         AttributesData::iterator end = _attributePools.end();
00077                         for (unsigned i=0; it!=end; i++, it++)
00078                         {
00079                                 it->SetDefinition(_spec.GetAttribute(i));
00080                         }
00081                 }
00082                 ~ScopePool();
00083                 const char * GetClassName() const { return "ScopePool"; }
00084                 void StoreOn(Storage & storage) const
00085                 {
00086                         XMLAdapter<std::string> nameAdapter(_spec.GetName(),"name",false);
00087                         storage.Store(nameAdapter);
00088                         XMLAdapter<unsigned> sizeAdapter(_size,"size",false);
00089                         storage.Store(sizeAdapter);
00090                         for (unsigned attribute=0; attribute<_attributePools.size(); attribute++)
00091                         {
00092                                 if (!_attributePools[attribute].GetData()) continue;
00093                                 XMLComponentAdapter adapter(_attributePools[attribute],"AttributePool",true);
00094                                 storage.Store(adapter);
00095                         }
00096                 }
00097                 void LoadFrom(Storage & storage)
00098                 {
00099                         std::string name;
00100                         XMLAdapter<std::string> nameAdapter(name,"name",false);
00101                         storage.Load(nameAdapter);
00102                         CLAM_ASSERT(name==_spec.GetName(),
00103                                 ("The schema expected a scope named '"+_spec.GetName()+
00104                                  "', but the XML contains the scope '"+ name+"' instead").c_str());
00105                         unsigned newSize;
00106                         XMLAdapter<unsigned> sizeAdapter(newSize,"size",false);
00107                         storage.Load(sizeAdapter);
00108                         Reallocate(newSize);
00109                         for (unsigned attribute=0; attribute<_attributePools.size(); attribute++)
00110                                 _attributePools[attribute].Deallocate();
00111                         AttributePoolStorageProxy proxy(*this);
00112                         XMLComponentAdapter adapter(proxy,"AttributePool",true);
00113                         while (storage.Load(adapter)) {} // do nothing
00114                 }
00115                 void Insert(unsigned pos)
00116                 {
00117                         AttributesData::iterator it = _attributePools.begin();
00118                         AttributesData::iterator end = _attributePools.end();
00119                         for (unsigned i=0; it!=end; i++, it++)
00120                         {
00121                                 it->Insert(pos);
00122                         }
00123                         _size++;
00124                 }
00125                 void Remove(unsigned pos)
00126                 {
00127                         AttributesData::iterator it = _attributePools.begin();
00128                         AttributesData::iterator end = _attributePools.end();
00129                         for (unsigned i=0; it!=end; i++, it++)
00130                         {
00131                                 it->Remove(pos);
00132                         }
00133                         _size--;
00134                 }
00135         private:
00136                 void Reallocate(unsigned newSize)
00137                 {
00138                         _size = newSize;
00139                         AttributesData::iterator it = _attributePools.begin();
00140                         AttributesData::iterator end = _attributePools.end();
00141                         for (unsigned i=0; it!=end; i++, it++)
00142                         {
00143                                 if (!it->GetData()) continue;
00144                                 it->Deallocate();
00145                                 it->Allocate(_size);
00146                         }
00147                 }
00148         public:
00149                 unsigned GetNAttributes() const
00150                 {
00151                         return _spec.GetNAttributes();
00152                 }
00153                 unsigned GetSize() const
00154                 {
00155                         return _size;
00156                 }
00157                 void SetSize(unsigned newSize)
00158                 {
00159                         Reallocate(newSize);
00160                 }
00161 
00162                 bool IsInstantiated(const std::string & attributeName) const
00163                 {
00164                         unsigned attribPos = _spec.GetIndex(attributeName);
00165                         const void * data = _attributePools[attribPos].GetData();
00166                         return data!=0;
00167                 }
00168                 template <typename AttributeType>
00169                 const AttributeType * GetReadPool(const std::string & name) const
00170                 {
00171                         unsigned attribPos = _spec.GetIndex(name);
00172                         _spec.CheckType(attribPos,(AttributeType*)0);
00173                         const void * data = _attributePools[attribPos].GetData();
00174                         CLAM_ASSERT(data,
00175                                 (std::string()+"Getting data from a non instanciated attribute '"+_spec.GetName()+"':'"+name+"'").c_str());
00176                         return &(*(const std::vector<AttributeType>*) data )[0];
00177                 }
00178 
00179                 template <typename AttributeType>
00180                 AttributeType * GetWritePool(const std::string & name)
00181                 {
00182                         unsigned attribPos = _spec.GetIndex(name);
00183                         _spec.CheckType(attribPos,(AttributeType*)0);
00184                         void * data = _attributePools[attribPos].GetData();
00185                         if (!data)
00186                         {
00187                                 _attributePools[attribPos].Allocate(_size);
00188                                 data = _attributePools[attribPos].GetData();
00189                         }
00190 
00191                         return &(*(std::vector<AttributeType>*) data )[0];
00192                 }
00193         };
00194 
00195 }
00196 
00197 
00198 #endif// _ScopePool_hxx_
00199 
Generated by  doxygen 1.6.3