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 _DescriptionAttributes_hxx_ 00023 #define _DescriptionAttributes_hxx_ 00024 00025 #include <typeinfo> 00026 #include "Assert.hxx" 00027 #include "Storage.hxx" 00028 #include "XMLAdapter.hxx" 00029 #include "XMLArrayAdapter.hxx" 00030 #include "XMLComponentAdapter.hxx" 00031 #include "Component.hxx" 00032 #include <typeinfo> 00033 #include <vector> 00034 00035 namespace CLAM 00036 { 00043 class AbstractAttribute : public Component 00044 { 00045 public: 00046 AbstractAttribute(const std::string & attributeName) 00047 : _attributeName(attributeName) {} 00048 AbstractAttribute(const std::string & scopeName, const std::string & attributeName) 00049 : _scopeName(scopeName), _attributeName(attributeName) {} 00050 virtual ~AbstractAttribute(); 00051 00052 const char * GetClassName() const { return "AbstractAttribute"; } 00053 void StoreOn(Storage & storage) const 00054 { 00055 XMLAdapter<std::string> scopeAttribute(_scopeName, "scope", false); 00056 storage.Store(scopeAttribute); 00057 00058 XMLAdapter<std::string> nameAttribute(_attributeName, "name", false); 00059 storage.Store(nameAttribute); 00060 00061 XmlDumpSchemaType(storage); 00062 } 00063 void LoadFrom(Storage & storage) 00064 { 00065 } 00066 00068 const std::string & GetName() const { return _attributeName; } 00070 const std::string & GetScope() const { return _scopeName; } 00071 00073 virtual void * Allocate(unsigned size) const = 0; 00075 virtual void Deallocate(void * data) const = 0; 00077 virtual void Insert(void * data, unsigned pos) const = 0; 00079 virtual void Remove(void * data, unsigned pos) const = 0; 00080 00082 virtual void XmlDumpData(Storage & storage, const void * data, unsigned size ) const = 0; 00084 virtual void XmlRestoreData(Storage & storage, void * data, unsigned size ) const = 0; 00085 00087 virtual void XmlDumpSchemaType(Storage & storage) const = 0; 00088 00090 template <typename TypeToCheck> 00091 void CheckType() const 00092 { 00093 if (typeid(TypeToCheck)==TypeInfo()) return; 00094 std::ostringstream os; 00095 os << "Attribute '" << _scopeName << ":" << _attributeName 00096 << "' has been used as type '" << typeid(TypeToCheck).name() 00097 << "' but it really was of type '" << TypeInfo().name() << "'"; 00098 CLAM_ASSERT(typeid(TypeToCheck)==TypeInfo(), 00099 os.str().c_str()); 00100 } 00101 protected: 00103 virtual const std::type_info & TypeInfo() const = 0; 00104 private: 00105 std::string _scopeName; 00106 std::string _attributeName; 00107 }; 00108 00114 template <typename AttributeType> 00115 class Attribute : public AbstractAttribute 00116 { 00117 public: 00118 Attribute(const std::string & attributeName) 00119 : AbstractAttribute(attributeName) {} 00120 Attribute(const std::string & scopeName, const std::string & attributeName) 00121 : AbstractAttribute(scopeName, attributeName) {} 00122 typedef AttributeType DataType; 00123 virtual void * Allocate(unsigned size) const 00124 { 00125 return new std::vector<DataType>(size); 00126 } 00127 virtual void Deallocate(void * data) const 00128 { 00129 delete (std::vector<DataType>*)data; 00130 } 00131 virtual void Insert(void * data, unsigned pos) const 00132 { 00133 std::vector<DataType> * vector = (std::vector<DataType> *) data; 00134 vector->insert(vector->begin()+pos, DataType()); 00135 } 00136 virtual void Remove(void * data, unsigned pos) const 00137 { 00138 std::vector<DataType> * vector = (std::vector<DataType> *) data; 00139 vector->erase(vector->begin()+pos); 00140 } 00141 virtual void XmlDumpData(Storage & storage, const void * data, unsigned size ) const 00142 { 00143 XMLAdapter<std::string> nameAdapter(GetName(),"name",false); 00144 storage.Store(nameAdapter); 00145 const std::vector<DataType> * vector = (const std::vector<DataType> *) data; 00146 XmlDumpConcreteData(storage,&(*vector)[0],size,(DataType*)0); 00147 } 00148 virtual void XmlRestoreData(Storage & storage, void * data, unsigned size ) const 00149 { 00150 std::string name; 00151 XMLAdapter<std::string> nameAdapter(name,"name",false); 00152 storage.Load(nameAdapter); 00153 CLAM_ASSERT(name==GetName(), 00154 ("The schema expected an attribute named '" + GetScope() + ":" + GetName() + 00155 "' but the XML file contained '" + GetScope() + ":" + name + "'").c_str()); 00156 std::vector<DataType> * vector = (std::vector<DataType> *) data; 00157 XmlRestoreConcreteData(storage,&(*vector)[0],size,(DataType*)0); 00158 } 00159 void XmlDumpSchemaType(Storage & storage) const 00160 { 00161 DataType * typeDiscriminator = 0; 00162 std::string type = XmlTypeId(typeDiscriminator, typeDiscriminator); 00163 XMLAdapter<std::string> typeAttribute(type, "type", false); 00164 storage.Store(typeAttribute); 00165 } 00166 private: 00167 template <typename T> 00168 std::string XmlTypeId(const T * realType, void * discriminator ) const 00169 { 00170 // return "Unknown"; 00171 return typeid(T).name(); 00172 } 00173 template <typename T> 00174 std::string XmlTypeId(const T * realType, Component * discriminator ) const 00175 { 00176 T dummy; 00177 return dummy.GetClassName(); 00178 } 00179 template <typename T> 00180 std::string XmlTypeId(const T * realType, float * discriminator ) const 00181 { 00182 return "Float"; 00183 } 00184 template <typename T> 00185 std::string XmlTypeId(const T * realType, std::string * discriminator ) const 00186 { 00187 return "String"; 00188 } 00189 template <typename T> 00190 void XmlDumpConcreteData(Storage & storage, const T * data, unsigned size, void * discriminator ) const 00191 { 00192 XMLArrayAdapter<DataType> dataAdapter((DataType*)data, size); 00193 storage.Store(dataAdapter); 00194 } 00195 template <typename T> 00196 void XmlDumpConcreteData(Storage & storage, const T * data, unsigned size, Component * discriminator ) const 00197 { 00198 for (unsigned i=0 ; i < size ; i++ ) 00199 { 00200 XMLComponentAdapter componentAdapter(data[i],data[i].GetClassName(),true); 00201 storage.Store(componentAdapter); 00202 } 00203 } 00204 template <typename T> 00205 void XmlRestoreConcreteData(Storage & storage, T * data, unsigned size, void * discriminator ) const 00206 { 00207 XMLArrayAdapter<DataType> dataAdapter(data, size); 00208 storage.Load(dataAdapter); 00209 } 00210 template <typename T> 00211 void XmlRestoreConcreteData(Storage & storage, T * data, unsigned size, Component * discriminator ) const 00212 { 00213 for (unsigned i=0 ; i < size ; i++ ) 00214 { 00215 XMLComponentAdapter componentAdapter(data[i],data[i].GetClassName(),true); 00216 storage.Load(componentAdapter); 00217 } 00218 } 00219 protected: 00220 virtual const std::type_info & TypeInfo() const 00221 { 00222 return typeid(DataType); 00223 } 00224 }; 00225 00226 } 00227 00228 00229 00230 #endif// _DescriptionAttributes_hxx_ 00231