CLAM-Development
1.1
|
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