CLAM-Development  1.4.0
XMLIterableAdapter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-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 
23 // Class XMLIterableAdapter
24 //
25 
26 #ifndef _XMLIterableAdapter_h
27 #define _XMLIterableAdapter_h
28 
29 #include "BasicXMLable.hxx"
30 #include "XMLAdapter.hxx"
31 #include "XMLComponentAdapter.hxx"
32 #include "TypeInfo.hxx"
33 #include <sstream>
34 #include <iostream>
35 
36 
37 namespace CLAM {
38 
66 template <class T> class XMLIterableAdapter : public BasicXMLable , public Component {
67 // Internal Types
68 public:
70  typedef T t_adaptee;
71  typedef typename t_adaptee::value_type t_adapteeValues;
72  typedef typename t_adaptee::iterator t_adapteeIterator;
74 // Attributes
75 private:
76  t_adaptee & mAdaptee;
77  const char * mElementsName;
78 // Construction/Destruction
79 public:
98  XMLIterableAdapter (T & anAdaptee, const char * elementName, const char * name=NULL,
99  bool isXMLElement=false)
100  : BasicXMLable(name, isXMLElement), mAdaptee(anAdaptee)
101  {
102  mElementsName = elementName;
103  }
104  XMLIterableAdapter (const T & anAdaptee, const char * elementName, const char * name=NULL,
105  bool isXMLElement=false)
106  : BasicXMLable(name, isXMLElement), mAdaptee(const_cast<T&>(anAdaptee))
107  {
108  mElementsName = elementName;
109  }
110  virtual ~XMLIterableAdapter() {};
111  const char * GetClassName() const {
112  CLAM_ASSERT(false, "You should never call XMLIterableAdapter::GetClassName");
113  return 0;
114  }
115 
116 // Accessors
117 public:
118  //* @return A string with the extracted XML content
119  std::string XMLContent() const
120  {
121  return ContentLeaveOrComponent((BasicIsStorableAsLeaf*)NULL);
122  }
123 
124  //* Extracts the content from the stream.
125  bool XMLContent(std::istream & str)
126  {
127  return ContentLeaveOrComponent((BasicIsStorableAsLeaf*)NULL, str);
128  }
129 
130 // Operators (for Component interface)
131 public:
137  virtual void StoreOn (Storage & store) const
138  {
139  StoreLeaveOrComponent (store, (BasicIsStorableAsLeaf*)NULL);
140  };
147  virtual void LoadFrom (Storage & store) {
148  mAdaptee.clear();
149  while (true) {
150  t_adapteeValues elem;
151  if (!LoadLeaveOrComponent(store, elem,
153  )
154  break;
155  mAdaptee.push_back(elem);
156  }
157  };
158 // Implementation:
159 private:
160  void StoreLeaveOrComponent (Storage& store, StaticTrue* isLeave) const
161  {
162  t_adapteeIterator it=mAdaptee.begin();
163  t_adapteeIterator end=mAdaptee.end();
164  const char * separator = "";
165  std::stringstream stream;
166  for (; it!=end; it++) {
167  stream << separator << *it;
168  separator = " ";
169  }
170  std::string content=stream.str();
171  XMLAdapter<std::string> adapter(content);
172  store.Store(adapter);
173  }
174  void StoreLeaveOrComponent (Storage& store, StaticFalse* isLeave) const
175  {
176  t_adapteeIterator it=mAdaptee.begin();
177  t_adapteeIterator end=mAdaptee.end();
178  for (; it!=end; it++) {
179  XMLComponentAdapter adapter(*it,mElementsName,true);
180  store.Store(adapter);
181  }
182  }
183  bool LoadLeaveOrComponent (Storage& store, t_adapteeValues & value, StaticTrue* isLeave)
184  {
185  XMLAdapter<t_adapteeValues> adapter(value);
186  return store.Load(adapter);
187  }
188  bool LoadLeaveOrComponent (Storage& store, t_adapteeValues & value, StaticFalse* isLeave)
189  {
190  XMLComponentAdapter adapter(value,mElementsName,true);
191  return store.Load(adapter);
192  }
193  //* @return A string with the extracted XML content */
194  std::string ContentLeaveOrComponent(StaticFalse* /*isLeave*/) const
195  {
196  return "";
197  }
199  std::string ContentLeaveOrComponent(StaticTrue* /*isLeave*/) const
200  {
201  if (!IsXMLAttribute()) return "";
202  std::stringstream stream;
203  t_adapteeIterator it=mAdaptee.begin();
204  t_adapteeIterator end=mAdaptee.end();
205  bool first = true;
206  for (; it!=end; it++) {
207  if (first) first=false;
208  else stream << " ";
209  stream << *it;
210  }
211  return stream.str();
212  }
216  bool ContentLeaveOrComponent(StaticFalse* isLeave, std::istream &is)
217  {
218  return true;
219  }
223  bool ContentLeaveOrComponent(StaticTrue* isLeave, std::istream &str)
224  {
225  if (!IsXMLAttribute()) return true;
226  mAdaptee.clear();
227  while (str) {
228  t_adapteeValues contained;
229  str >> contained;
230  if (str) mAdaptee.push_back(contained);
231  }
232  return true;
233  }
234 // Testing
235 public:
237  bool FulfilsInvariant();
238 };
239 
240 
241 // Check the internal status for a class instance is valid
242 template <class T>
244 {
245  return super::FulfilsInvariant();
246 };
247 
248 }
249 
250 #endif//_XMLIterableAdapter_h
251