CLAM-Development  1.4.0
DescriptionAttributes.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #ifndef _DescriptionAttributes_hxx_
23 #define _DescriptionAttributes_hxx_
24 
25 #include <typeinfo>
26 #include "Assert.hxx"
27 #include "Storage.hxx"
28 #include "XMLAdapter.hxx"
29 #include "XMLArrayAdapter.hxx"
30 #include "XMLComponentAdapter.hxx"
31 #include "Component.hxx"
32 #include <typeinfo>
33 #include <vector>
34 
35 namespace CLAM
36 {
44  {
45  public:
46  AbstractAttribute(const std::string & attributeName)
47  : _attributeName(attributeName) {}
48  AbstractAttribute(const std::string & scopeName, const std::string & attributeName)
49  : _scopeName(scopeName), _attributeName(attributeName) {}
50  virtual ~AbstractAttribute();
51 
52  const char * GetClassName() const { return "AbstractAttribute"; }
53  void StoreOn(Storage & storage) const
54  {
55  XMLAdapter<std::string> scopeAttribute(_scopeName, "scope", false);
56  storage.Store(scopeAttribute);
57 
58  XMLAdapter<std::string> nameAttribute(_attributeName, "name", false);
59  storage.Store(nameAttribute);
60 
61  XmlDumpSchemaType(storage);
62  }
63  void LoadFrom(Storage & storage)
64  {
65  }
66 
68  const std::string & GetName() const { return _attributeName; }
70  const std::string & GetScope() const { return _scopeName; }
71 
73  virtual void * Allocate(unsigned size) const = 0;
75  virtual void Deallocate(void * data) const = 0;
77  virtual void Insert(void * data, unsigned pos) const = 0;
79  virtual void Remove(void * data, unsigned pos) const = 0;
80 
82  virtual void XmlDumpData(Storage & storage, const void * data, unsigned size ) const = 0;
84  virtual void XmlRestoreData(Storage & storage, void * data, unsigned size ) const = 0;
85 
87  virtual void XmlDumpSchemaType(Storage & storage) const = 0;
88 
90  template <typename TypeToCheck>
91  void CheckType() const
92  {
93  if (typeid(TypeToCheck)==TypeInfo()) return;
94  std::ostringstream os;
95  os << "Attribute '" << _scopeName << ":" << _attributeName
96  << "' has been used as type '" << typeid(TypeToCheck).name()
97  << "' but it really was of type '" << TypeInfo().name() << "'";
98  CLAM_ASSERT(typeid(TypeToCheck)==TypeInfo(),
99  os.str().c_str());
100  }
101  protected:
103  virtual const std::type_info & TypeInfo() const = 0;
104  private:
105  std::string _scopeName;
106  std::string _attributeName;
107  };
108 
114  template <typename AttributeType>
116  {
117  public:
118  Attribute(const std::string & attributeName)
119  : AbstractAttribute(attributeName) {}
120  Attribute(const std::string & scopeName, const std::string & attributeName)
121  : AbstractAttribute(scopeName, attributeName) {}
122  typedef AttributeType DataType;
123  virtual void * Allocate(unsigned size) const
124  {
125  return new std::vector<DataType>(size);
126  }
127  virtual void Deallocate(void * data) const
128  {
129  delete (std::vector<DataType>*)data;
130  }
131  virtual void Insert(void * data, unsigned pos) const
132  {
133  std::vector<DataType> * vector = (std::vector<DataType> *) data;
134  vector->insert(vector->begin()+pos, DataType());
135  }
136  virtual void Remove(void * data, unsigned pos) const
137  {
138  std::vector<DataType> * vector = (std::vector<DataType> *) data;
139  vector->erase(vector->begin()+pos);
140  }
141  virtual void XmlDumpData(Storage & storage, const void * data, unsigned size ) const
142  {
143  XMLAdapter<std::string> nameAdapter(GetName(),"name",false);
144  storage.Store(nameAdapter);
145  const std::vector<DataType> * vector = (const std::vector<DataType> *) data;
146  XmlDumpConcreteData(storage,&(*vector)[0],size,(DataType*)0);
147  }
148  virtual void XmlRestoreData(Storage & storage, void * data, unsigned size ) const
149  {
150  std::string name;
151  XMLAdapter<std::string> nameAdapter(name,"name",false);
152  storage.Load(nameAdapter);
153  CLAM_ASSERT(name==GetName(),
154  ("The schema expected an attribute named '" + GetScope() + ":" + GetName() +
155  "' but the XML file contained '" + GetScope() + ":" + name + "'").c_str());
156  std::vector<DataType> * vector = (std::vector<DataType> *) data;
157  XmlRestoreConcreteData(storage,&(*vector)[0],size,(DataType*)0);
158  }
159  void XmlDumpSchemaType(Storage & storage) const
160  {
161  DataType * typeDiscriminator = 0;
162  std::string type = XmlTypeId(typeDiscriminator, typeDiscriminator);
163  XMLAdapter<std::string> typeAttribute(type, "type", false);
164  storage.Store(typeAttribute);
165  }
166  private:
167  template <typename T>
168  std::string XmlTypeId(const T * realType, void * discriminator ) const
169  {
170  // return "Unknown";
171  return typeid(T).name();
172  }
173  template <typename T>
174  std::string XmlTypeId(const T * realType, Component * discriminator ) const
175  {
176  T dummy;
177  return dummy.GetClassName();
178  }
179  template <typename T>
180  std::string XmlTypeId(const T * realType, float * discriminator ) const
181  {
182  return "Float";
183  }
184  template <typename T>
185  std::string XmlTypeId(const T * realType, std::string * discriminator ) const
186  {
187  return "String";
188  }
189  template <typename T>
190  void XmlDumpConcreteData(Storage & storage, const T * data, unsigned size, void * discriminator ) const
191  {
192  XMLArrayAdapter<DataType> dataAdapter((DataType*)data, size);
193  storage.Store(dataAdapter);
194  }
195  template <typename T>
196  void XmlDumpConcreteData(Storage & storage, const T * data, unsigned size, Component * discriminator ) const
197  {
198  for (unsigned i=0 ; i < size ; i++ )
199  {
200  XMLComponentAdapter componentAdapter(data[i],data[i].GetClassName(),true);
201  storage.Store(componentAdapter);
202  }
203  }
204  template <typename T>
205  void XmlRestoreConcreteData(Storage & storage, T * data, unsigned size, void * discriminator ) const
206  {
207  XMLArrayAdapter<DataType> dataAdapter(data, size);
208  storage.Load(dataAdapter);
209  }
210  template <typename T>
211  void XmlRestoreConcreteData(Storage & storage, T * data, unsigned size, Component * discriminator ) const
212  {
213  for (unsigned i=0 ; i < size ; i++ )
214  {
215  XMLComponentAdapter componentAdapter(data[i],data[i].GetClassName(),true);
216  storage.Load(componentAdapter);
217  }
218  }
219  protected:
220  virtual const std::type_info & TypeInfo() const
221  {
222  return typeid(DataType);
223  }
224  };
225 
226 }
227 
228 
229 
230 #endif// _DescriptionAttributes_hxx_
231