CLAM-Development  1.4.0
DynamicType.hxx
Go to the documentation of this file.
1 /* DynamicType.hxx: interface for the DynamicType class.
2  * written by Pau Arumí - May 2001
3  * new version (that stores every type) : 21-July-2001
4  *
5  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
6  * UNIVERSITAT POMPEU FABRA
7  *
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  *
23  */
24 
25 #ifndef _DynamicType_
26 #define _DynamicType_
27 
28 #include "XMLAdapter.hxx"
29 #include "XMLIterableAdapter.hxx"
30 #include "XMLComponentAdapter.hxx"
31 
32 #include "DynamicTypeMacros.hxx" //this file is not included anywhere but here.
33 
34 #include "Component.hxx"
35 #include "DataTypes.hxx"
36 
37 #include <new>
38 
39 namespace CLAM {
40 
42 // Class DynamicType declaration :
43 //
45 
46 
70 class DynamicType : public Component
71 {
72 public:
80  DynamicType(const int nAttr);
81 
91  DynamicType(const DynamicType& prototype, const bool shareData, const bool deepCopy);
92  DynamicType(const DynamicType& prototype);
93  virtual ~DynamicType();
94 
95  virtual const char* GetClassName() const =0;
96 protected:
105  void DefaultInit() {
106 
107  };
108 
113  virtual void InformAll() {
114  // lets calculates the offsets of the "Pre allocated mode"
115  CLAM_DEBUG_ASSERT(typeDescTable,"static table don't exist. in DT::InformAll()");
116  int adder=0;
117  for (unsigned int i=0; i<numAttr; i++) {
118  typeDescTable[i].offset = adder;
119  adder += typeDescTable[i].size;
120  }
121  maxAttrSize = adder;
122 
123  };
124 
125 public:
133  void CopyInit(const DynamicType & dt) {
134  };
135 
145  bool UpdateData();
146 
147 private:
148  // Types of the constructors and destructors that all registerd type must have.
149  // A pointer to these functions is stored into the typeDescTable. (an array of TAttr)
150  // The definition of TAttr is following:
151  typedef void* (*t_new)(void* pos);
152  typedef void* (*t_new_copy)(void* pos,void* orig);
153  typedef void (*t_destructor)(void* pos);
154 
155  virtual void InformAttr_ (unsigned id, const char* name, unsigned size, const char* type, const bool isPtr,
156  const t_new, const t_new_copy, const t_destructor);
157 
158 protected:
159  inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
160  const t_new, const t_new_copy, const t_destructor, const Component* ptr);
161 
162  inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
163  const t_new, const t_new_copy, const t_destructor, const DynamicType* ptr);
164 
165  inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
166  const t_new, const t_new_copy, const t_destructor, const void* ptr);
167 
168  void AddAttr_ (const unsigned i, const unsigned size);
169  void RemoveAttr_ (const unsigned id);
170 
171 public:
172  unsigned GetNDynamicAttributes() const { return numAttr; }
173  const char * GetDynamicAttributeName(unsigned i) { return typeDescTable[i].id; }
174  virtual const std::type_info & GetTypeId(unsigned i) const=0;
175  bool AttributeIsComponent(unsigned i) const {return typeDescTable[i].isComponent; }
176  bool AttributeIsDynamictype(unsigned i) const {return typeDescTable[i].isDynamicType; }
177  bool IsAttributeInstantiated(unsigned i) const {return dynamicTable[i].offs!=-1; }
178  const void * GetAttributeAsVoidPtr(unsigned i) const {
179  return GetPtrToData_(i);
180  }
181  const Component * GetAttributeAsComponent(unsigned i) const {
182  if (!typeDescTable[i].isComponent) return 0;
183  return static_cast<const Component *> (GetPtrToData_(i));
184  }
186  if (! (typeDescTable[i].isComponent)) return 0;
187  return static_cast<Component *> (GetPtrToData_(i));
188  }
189  void FullfilsInvariant() const;
190 
191  virtual Component* DeepCopy() const;
192 public:
193  enum {idLength = 120, typeLength = 120}; //TODO: rise exception if the type is too long
194 
195 protected:
196  enum {shrinkThreshold = 80}; // Bytes. That constant means that when updating data, if the
197  // used data disminish an amount superior that this threshold,
198  // data will be reallocated (shrunk)
199  // item of the typeDescTable, that is static created only once in the concrete class constructor
200  struct TAttr
201  {
202  char id[idLength];
204  int size;
205  int offset;
206  t_new newObj;
207  t_new_copy newObjCopy;
208  t_destructor destructObj;
209 
210 // bool isInformed : 1; Deprecated!! Now the concrete constr. calls InformAll() chain.method.
211  bool isComponent : 1;
212  bool isStorable : 1;
213  bool isDynamicType : 1;
214  bool isPointer : 1;
215  };
216 
217  // item of the dynamicTable, that holds the dynamic information of the dynamic type
218  struct TDynInfo
219  {
220  int offs; // attribute offset of the data table. Has a -1 value when
221  // the attr is not instantiated (have no entry at the data table).
222  bool hasBeenAdded : 1;
223  bool hasBeenRemoved : 1;
224  };
225  virtual DynamicType& GetDynamicTypeCopy(const bool shareData = false, const bool deep = false) const =0;
226  virtual Component* ShallowCopy() const;
227  DynamicType& operator= (const DynamicType& source);
228 
229 
230  // Public Accesors to protected data. Necesary in the implementation of Branches (aggregates)
231  inline unsigned GetNumAttr() const { return numAttr; };
232  inline unsigned GetNumActiveAttr() const { return numActiveAttr; }
233  inline char* GetData() const { return data; }
234  inline void SetData(char* srcData) { data = srcData;}
235  inline TDynInfo* GetDynamicTable() const { return dynamicTable; }
236  inline TAttr* GetTypeDescTable() const { return typeDescTable; }
237  inline unsigned GetDataSize() const { return dataSize; }
238  inline bool IsInstanciate() const { return (data != 0); }
239  inline bool OwnsItsMemory() const { return bOwnsItsMemory; }
240  inline void SetOwnsItsMemory(const bool owns) { bOwnsItsMemory = owns; }
241  inline bool ExistAttr(unsigned id) const;
242  inline void SetPreAllocateAllAttributes() { bPreAllocateAllAttributes=true; }
243 
244 
245 public:
246  // Developing tools:
247  void Debug() const;
248 
249 protected:
250 
251  unsigned numActiveAttr;
252  char *data;
255  unsigned dataSize;
257  unsigned numAttr; // the total number of dyn. attrs.
258  unsigned maxAttrSize; // the total dyn. attrs. size
260 
261  inline int DynTableRefCounter();
262  inline void InitDynTableRefCounter();
263  inline int DecrementDynTableRefCounter();
264  inline int IncrementDynTableRefCounter();
265 
266 private:
267  inline bool AttrHasData(unsigned i) const { return (dynamicTable[i].offs > -1); };
268  inline void RemoveAllMem();
269  inline void* GetPtrToData_(const unsigned id) const;
270  inline void* GetDataAsPtr_(const unsigned id) const;
271  inline void SetDataAsPtr_(const unsigned id, void* p);
272 
274  void BeMemoryOwner();
280  void UpdateDataByShrinking();
281 
286  void UpdateDataByStandardMode();
287 
291  void UpdateDataGoingToPreAllocatedMode();
292 
296  void UpdateDataInPreAllocatedMode();
297 
298  void SelfCopyPrototype(const DynamicType &orig);
299  void SelfSharedCopy(const DynamicType &orig);
300  void SelfShallowCopy(const DynamicType &orig);
301  void SelfDeepCopy(const DynamicType &orig);
302  bool bPreAllocateAllAttributes;
303 
304 public:
305  virtual void StoreOn(CLAM::Storage & storage) const {
306  this->StoreDynAttributes(storage);
307  }
308  virtual void LoadFrom(CLAM::Storage & storage) {
309  this->LoadDynAttributes(storage);
310  }
311  template <unsigned int NAttrib>
313  public:
314  static const int value;
315  };
316 
317 protected:
318  virtual void StoreDynAttributes(CLAM::Storage & s) const=0;
319  virtual void LoadDynAttributes(CLAM::Storage & s)=0;
320  template <typename AttribType>
321  void StoreAttribute(StaticTrue* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) const
322  {
323  CLAM::XMLAdapter<AttribType> adapter(object, name, true);
324  s.Store (adapter);
325  }
326  template <typename AttribType>
327  void StoreAttribute(StaticFalse* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) const
328  {
329  CLAM::XMLComponentAdapter adapter(object, name, true);
330  s.Store (adapter);
331  }
332  template <typename AttribType>
333  void StoreIterableAttribute(CLAM::Storage &s ,AttribType & object, const char* name, const char* elemName) const
334  {
335  CLAM::XMLIterableAdapter<AttribType> adapter(object, elemName, name, true);
336  s.Store (adapter);
337  }
338 
339  template <typename AttribType>
340  bool LoadAttribute(StaticTrue* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) {
341  CLAM::XMLAdapter<AttribType> adapter(object, name, true);
342  return s.Load (adapter);
343  }
344  template <typename AttribType>
345  bool LoadAttribute(StaticFalse* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) {
346  CLAM::XMLComponentAdapter adapter(object, name, true);
347  return s.Load (adapter);
348  }
349  template <typename AttribType>
350  bool LoadIterableAttribute(CLAM::Storage &s ,AttribType & object, const char* name, const char* elemName) {
351  CLAM::XMLIterableAdapter<AttribType> adapter(object, elemName, name, true);
352  return s.Load (adapter);
353  }
354 };
355 
356 
358 // STATIC MEMBERS DEFINITION
359 
360 template <unsigned int NAttrib> const int DynamicType::AttributePositionBase<NAttrib>::value = NAttrib;
361 
363 // IMPLEMENTATION OF INLINE FUNCTIONS
364 
365 inline bool DynamicType::ExistAttr(unsigned id) const
366 {
367 
368  if (!data) return false;
369 
370  TDynInfo &inf = dynamicTable[id];
371  return (inf.offs != -1 && !inf.hasBeenAdded && !inf.hasBeenRemoved);
372 }
373 
374 inline void* DynamicType::GetDataAsPtr_(const unsigned id) const
375 {
376  return *(void**)&data[dynamicTable[id].offs];
377 }
378 
379 inline void* DynamicType::GetPtrToData_(const unsigned id) const
380 {
381  return (void*)&data[dynamicTable[id].offs];
382 }
383 
384 inline void DynamicType::SetDataAsPtr_(const unsigned id, void* p)
385 {
386  *(void**)&data[dynamicTable[id].offs] = p;
387 }
388 
389 
391 
392 
393 
394 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
395  const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const void* ptr)
396 {
397  InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
398  typeDescTable[val].isComponent = false;
399  typeDescTable[val].isDynamicType = false;
400  typeDescTable[val].isStorable = false;
401 }
402 
403 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
404  const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const Component* ptr)
405 {
406  InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
407  typeDescTable[val].isComponent = true;
408  typeDescTable[val].isDynamicType = false;
409  typeDescTable[val].isStorable = false;
410 }
411 
412 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
413  const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const DynamicType* ptr)
414 {
415  InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
416  typeDescTable[val].isComponent = true;
417  typeDescTable[val].isDynamicType = true;
418  typeDescTable[val].isStorable = false;
419 }
420 
421 
422 } //namespace CLAM
423 
424 #endif // !defined _DynamicType_
425