CLAM-Development
1.1
|
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