CLAM-Development  1.4.0
ScopePool.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 _ScopePool_hxx_
23 #define _ScopePool_hxx_
24 
25 #include "AttributePool.hxx"
26 #include "DescriptionScope.hxx"
27 
28 // TODO TO-TEST:
29 // Reading an non existent attribute
30 // Not reading an existent attribute
31 // Unordered attributes
32 // Twice present attributes
33 
34 namespace CLAM
35 {
41  class ScopePool : public Component
42  {
45  {
46  ScopePool & pool;
47  public:
49  : pool(scopePool)
50  {
51  }
52  const char* GetClassName() const { return "AttributeProxy"; }
53  void StoreOn(CLAM::Storage&) const {}
54  void LoadFrom(Storage & storage)
55  {
56  std::string name;
57  XMLAdapter<std::string> nameAdapter(name,"name",false);
58  storage.Load(nameAdapter);
59  unsigned attributeIndex = pool._spec.GetIndexSafe(name);
60  pool._attributePools[attributeIndex].Allocate(pool._size);
61  XMLComponentAdapter adapter(pool._attributePools[attributeIndex]);
62  storage.Load(adapter);
63  }
64  };
65  public:
66  typedef std::vector<AttributePool> AttributesData;
67  private:
68  unsigned _size;
69  const DescriptionScope & _spec;
70  AttributesData _attributePools;
71  public:
72  ScopePool(const DescriptionScope & spec, unsigned size=0)
73  : _size(size), _spec(spec), _attributePools(spec.GetNAttributes())
74  {
75  AttributesData::iterator it = _attributePools.begin();
76  AttributesData::iterator end = _attributePools.end();
77  for (unsigned i=0; it!=end; i++, it++)
78  {
79  it->SetDefinition(_spec.GetAttribute(i));
80  }
81  }
82  ~ScopePool();
83  const char * GetClassName() const { return "ScopePool"; }
84  void StoreOn(Storage & storage) const
85  {
86  XMLAdapter<std::string> nameAdapter(_spec.GetName(),"name",false);
87  storage.Store(nameAdapter);
88  XMLAdapter<unsigned> sizeAdapter(_size,"size",false);
89  storage.Store(sizeAdapter);
90  for (unsigned attribute=0; attribute<_attributePools.size(); attribute++)
91  {
92  if (!_attributePools[attribute].GetData()) continue;
93  XMLComponentAdapter adapter(_attributePools[attribute],"AttributePool",true);
94  storage.Store(adapter);
95  }
96  }
97  void LoadFrom(Storage & storage)
98  {
99  std::string name;
100  XMLAdapter<std::string> nameAdapter(name,"name",false);
101  storage.Load(nameAdapter);
102  CLAM_ASSERT(name==_spec.GetName(),
103  ("The schema expected a scope named '"+_spec.GetName()+
104  "', but the XML contains the scope '"+ name+"' instead").c_str());
105  unsigned newSize;
106  XMLAdapter<unsigned> sizeAdapter(newSize,"size",false);
107  storage.Load(sizeAdapter);
108  Reallocate(newSize);
109  for (unsigned attribute=0; attribute<_attributePools.size(); attribute++)
110  _attributePools[attribute].Deallocate();
111  AttributePoolStorageProxy proxy(*this);
112  XMLComponentAdapter adapter(proxy,"AttributePool",true);
113  while (storage.Load(adapter)) {} // do nothing
114  }
115  void Insert(unsigned pos)
116  {
117  AttributesData::iterator it = _attributePools.begin();
118  AttributesData::iterator end = _attributePools.end();
119  for (unsigned i=0; it!=end; i++, it++)
120  {
121  it->Insert(pos);
122  }
123  _size++;
124  }
125  void Remove(unsigned pos)
126  {
127  AttributesData::iterator it = _attributePools.begin();
128  AttributesData::iterator end = _attributePools.end();
129  for (unsigned i=0; it!=end; i++, it++)
130  {
131  it->Remove(pos);
132  }
133  _size--;
134  }
135  private:
136  void Reallocate(unsigned newSize)
137  {
138  _size = newSize;
139  AttributesData::iterator it = _attributePools.begin();
140  AttributesData::iterator end = _attributePools.end();
141  for (unsigned i=0; it!=end; i++, it++)
142  {
143  if (!it->GetData()) continue;
144  it->Deallocate();
145  it->Allocate(_size);
146  }
147  }
148  public:
149  unsigned GetNAttributes() const
150  {
151  return _spec.GetNAttributes();
152  }
153  unsigned GetSize() const
154  {
155  return _size;
156  }
157  void SetSize(unsigned newSize)
158  {
159  Reallocate(newSize);
160  }
161 
162  bool IsInstantiated(const std::string & attributeName) const
163  {
164  unsigned attribPos = _spec.GetIndex(attributeName);
165  const void * data = _attributePools[attribPos].GetData();
166  return data!=0;
167  }
168  template <typename AttributeType>
169  const AttributeType * GetReadPool(const std::string & name) const
170  {
171  unsigned attribPos = _spec.GetIndex(name);
172  _spec.CheckType(attribPos,(AttributeType*)0);
173  const void * data = _attributePools[attribPos].GetData();
174  CLAM_ASSERT(data,
175  (std::string()+"Getting data from a non instanciated attribute '"+_spec.GetName()+"':'"+name+"'").c_str());
176  return &(*(const std::vector<AttributeType>*) data )[0];
177  }
178 
179  template <typename AttributeType>
180  AttributeType * GetWritePool(const std::string & name)
181  {
182  unsigned attribPos = _spec.GetIndex(name);
183  _spec.CheckType(attribPos,(AttributeType*)0);
184  void * data = _attributePools[attribPos].GetData();
185  if (!data)
186  {
187  _attributePools[attribPos].Allocate(_size);
188  data = _attributePools[attribPos].GetData();
189  }
190 
191  return &(*(std::vector<AttributeType>*) data )[0];
192  }
193  };
194 
195 }
196 
197 
198 #endif// _ScopePool_hxx_
199