00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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