DescriptionAttributes.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 _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 
Generated by  doxygen 1.6.3