XMLIterableAdapter.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00023 // Class XMLIterableAdapter
00024 // 
00025 
00026 #ifndef _XMLIterableAdapter_h
00027 #define _XMLIterableAdapter_h
00028 
00029 #include "BasicXMLable.hxx"
00030 #include "XMLAdapter.hxx"
00031 #include "XMLComponentAdapter.hxx"
00032 #include "TypeInfo.hxx"
00033 #include <sstream>
00034 #include <iostream>
00035 
00036 
00037 namespace CLAM {
00038 
00066 template <class T> class XMLIterableAdapter : public BasicXMLable , public Component {
00067 // Internal Types
00068 public:
00069         typedef BasicXMLable super;
00070         typedef T t_adaptee;
00071         typedef typename t_adaptee::value_type t_adapteeValues;
00072         typedef typename t_adaptee::iterator t_adapteeIterator;
00073         typedef typename TypeInfo<t_adapteeValues>::StorableAsLeaf BasicIsStorableAsLeaf;
00074 // Attributes
00075 private:
00076         t_adaptee & mAdaptee;
00077         const char * mElementsName;
00078 // Construction/Destruction
00079 public:
00098         XMLIterableAdapter (T & anAdaptee, const char * elementName, const char * name=NULL, 
00099                         bool isXMLElement=false)
00100                 : BasicXMLable(name, isXMLElement), mAdaptee(anAdaptee)
00101         {
00102                 mElementsName = elementName;
00103         }
00104         XMLIterableAdapter (const T & anAdaptee, const char * elementName, const char * name=NULL, 
00105                         bool isXMLElement=false)
00106                 : BasicXMLable(name, isXMLElement), mAdaptee(const_cast<T&>(anAdaptee))
00107         {
00108                 mElementsName = elementName;
00109         }
00110         virtual ~XMLIterableAdapter() {};
00111         const char * GetClassName() const {
00112                 CLAM_ASSERT(false, "You should never call XMLIterableAdapter::GetClassName");
00113                 return 0;
00114         }
00115 
00116 // Accessors
00117 public:
00118         //* @return A string with the extracted XML content
00119         std::string XMLContent() const
00120         {
00121                 return ContentLeaveOrComponent((BasicIsStorableAsLeaf*)NULL);
00122         }
00123 
00124         //* Extracts the content from the stream.
00125         bool XMLContent(std::istream & str) 
00126         {
00127                 return ContentLeaveOrComponent((BasicIsStorableAsLeaf*)NULL, str);
00128         }
00129 
00130 // Operators (for Component interface)
00131 public:
00137         virtual void StoreOn (Storage & store) const
00138         {
00139                 StoreLeaveOrComponent (store, (BasicIsStorableAsLeaf*)NULL);
00140         };
00147         virtual void LoadFrom (Storage & store) {
00148                 mAdaptee.clear();
00149                 while (true) {
00150                         t_adapteeValues elem;
00151                         if (!LoadLeaveOrComponent(store, elem,
00152                                                 (BasicIsStorableAsLeaf *)NULL)
00153                                         )
00154                                 break;
00155                         mAdaptee.push_back(elem);
00156                 }
00157         };
00158 // Implementation:
00159 private:
00160         void StoreLeaveOrComponent (Storage& store, StaticTrue* isLeave) const 
00161         {
00162                 t_adapteeIterator it=mAdaptee.begin();
00163                 t_adapteeIterator end=mAdaptee.end();
00164                 const char * separator = "";
00165                 std::stringstream stream;
00166                 for (; it!=end; it++) {
00167                         stream << separator << *it;
00168                         separator = " ";
00169                 }
00170                 std::string content=stream.str();
00171                 XMLAdapter<std::string> adapter(content);
00172                 store.Store(adapter);
00173         }
00174         void StoreLeaveOrComponent (Storage& store, StaticFalse* isLeave) const
00175         {
00176                 t_adapteeIterator it=mAdaptee.begin();
00177                 t_adapteeIterator end=mAdaptee.end();
00178                 for (; it!=end; it++) {
00179                         XMLComponentAdapter adapter(*it,mElementsName,true);
00180                         store.Store(adapter);
00181                 }
00182         }
00183         bool LoadLeaveOrComponent (Storage& store, t_adapteeValues & value, StaticTrue* isLeave) 
00184         {
00185                 XMLAdapter<t_adapteeValues> adapter(value);
00186                 return store.Load(adapter);
00187         }
00188         bool LoadLeaveOrComponent (Storage& store, t_adapteeValues & value, StaticFalse* isLeave)
00189         {
00190                 XMLComponentAdapter adapter(value,mElementsName,true);
00191                 return store.Load(adapter);
00192         }
00193         //* @return A string with the extracted XML content */
00194         std::string ContentLeaveOrComponent(StaticFalse* /*isLeave*/) const
00195         {
00196                 return "";
00197         }
00199         std::string ContentLeaveOrComponent(StaticTrue* /*isLeave*/) const
00200         {
00201                 if (!IsXMLAttribute()) return "";
00202                 std::stringstream stream;
00203                 t_adapteeIterator it=mAdaptee.begin();
00204                 t_adapteeIterator end=mAdaptee.end();
00205                 bool first = true;
00206                 for (; it!=end; it++) {
00207                         if (first) first=false;
00208                         else stream << " ";
00209                         stream << *it;
00210                 }
00211                 return stream.str();
00212         }
00216         bool ContentLeaveOrComponent(StaticFalse* isLeave, std::istream &is) 
00217         {
00218                 return true;
00219         }
00223         bool ContentLeaveOrComponent(StaticTrue* isLeave, std::istream &str) 
00224         {
00225                 if (!IsXMLAttribute()) return true;
00226                 mAdaptee.clear();
00227                 while (str) {
00228                         t_adapteeValues contained;
00229                         str >> contained;
00230                         if (str) mAdaptee.push_back(contained);
00231                 }
00232                 return true;
00233         }
00234 // Testing
00235 public:
00237         bool FulfilsInvariant();
00238 };
00239 
00240 
00241 // Check the internal status for a class instance is valid
00242 template <class T>
00243 bool XMLIterableAdapter<T>::FulfilsInvariant() 
00244 {
00245         return super::FulfilsInvariant();
00246 };
00247 
00248 }
00249 
00250 #endif//_XMLIterableAdapter_h
00251 
Generated by  doxygen 1.6.3