ximol/xml/reader.hpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002  *                                                                           *
00003  * library XiMoL                                                             *
00004  * Copyright (C) 2002, 2003, 2004 Florent Tournois                           *
00005  *                                                                           *
00006  * This library is free software; you can redistribute it and/or             *
00007  * modify it under the terms of the GNU Lesser General Public                *
00008  * License as published by the Free Software Foundation; either              *
00009  * version 2.1 of the License, or (at your option) any later version.        *
00010  *                                                                           *
00011  * This library 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 GNU         *
00014  * Lesser General Public License for more details.                           *
00015  *                                                                           *
00016  * You should have received a copy of the GNU Lesser General Public          *
00017  * License along with this library; if not, write to the Free Software       *
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   *
00019  *                                                                           *
00020 \*****************************************************************************/
00021 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00022 /** \file 
00023         \brief Define XiMoL Interface.
00024 
00025         This is the most important file in the project. Here we define
00026         the user interface of the library.
00027         
00028         \author Tournois Florent
00029         \version 1.0
00030 
00031     $Id: reader.hpp,v 1.13 2004/02/25 18:59:13 tournois Exp $
00032     $Log: reader.hpp,v $
00033     Revision 1.13  2004/02/25 18:59:13  tournois
00034     imporve the gcc compatibility.
00035 
00036     Revision 1.12  2004/02/22 10:27:34  tournois
00037     Add some doc.
00038 
00039     Revision 1.11  2004/02/22 09:54:21  tournois
00040     Change years on the copyright.
00041 
00042     Revision 1.10  2004/01/29 20:52:35  tournois
00043     doc and tutorial.
00044 
00045     Revision 1.9  2004/01/26 20:44:21  tournois
00046     no message
00047 
00048     Revision 1.8  2004/01/25 17:32:56  tournois
00049     no message
00050 
00051     Revision 1.7  2004/01/22 22:01:35  tournois
00052     no message
00053 
00054     Revision 1.6  2004/01/19 20:40:56  tournois
00055     Add min, max and digits facet.
00056     Create the control flow file.
00057 
00058     Revision 1.5  2003/11/19 20:52:54  tournois
00059     Add new manipulator for stag and etag.
00060     Correct bugs and add tests.
00061 
00062     Revision 1.4  2003/11/18 18:54:52  tournois
00063     Add str_cast and drop the transformation.hpp file.
00064 
00065     Revision 1.3  2003/11/14 11:45:05  tournois
00066     First try for the stag.
00067 
00068     Revision 1.2  2003/11/02 19:23:01  tournois
00069     Go to the boost coding standard.
00070     Change all name to lower case.
00071 
00072     Revision 1.1  2003/10/26 14:49:32  hfp
00073     reader separated
00074 
00075     Revision 1.4  2003/10/25 13:53:40  hfp
00076     review and separation
00077   */
00078 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00079 #ifndef XIMOL_XML_READER_HPP_
00080 #define XIMOL_XML_READER_HPP_
00081 
00082 #include <ximol/stop_warnings.hpp>
00083 #include <ximol/export_defs.hpp>
00084 #include <ximol/typedefs.hpp>
00085 #include <ximol/parser/utils.hpp>
00086 #include <ximol/control_flow.hpp>
00087 
00088 #include <map>
00089 
00090 
00091 // forwarded declarations
00092 XIMOL_BEGIN_NAMESPACE
00093         class xostream;
00094         class xistream;
00095 XIMOL_END_NAMESPACE
00096 
00097 XIMOL_XML_BEGIN_NAMESPACE
00098 
00099 namespace helper {
00100 
00101     /// Small struct to Grap the reference to read.
00102     struct XIMOL_EXPORT abstract_copy_holder {
00103         abstract_copy_holder();
00104         abstract_copy_holder(const abstract_copy_holder & x);
00105                 virtual ~abstract_copy_holder();
00106         abstract_copy_holder& operator=(const abstract_copy_holder & x );
00107 
00108                 virtual abstract_copy_holder* clone() = 0;
00109                 virtual xistream& read(xistream&) = 0;
00110         
00111     };
00112 
00113     /// Small struct to Grap the reference to read.
00114     template < typename T >
00115     struct copy_holder : public abstract_copy_holder {
00116         copy_holder(const T& x):x_(x){};
00117         copy_holder(const copy_holder<T>& x):x_(x.x_){};
00118         ~copy_holder(){};
00119         abstract_copy_holder* clone(){ return new copy_holder<T>(*this);}
00120         xistream& read(xistream & xis){ return xis >> x_; };
00121         T x_;
00122     };
00123 
00124 }; // end of namespace helper
00125 
00126 /// namespace for the reader policy
00127 namespace reader_policy {
00128     template < typename qname_type = ::std::pair<xstring,xstring>, typename abs_reader_type = helper::abstract_copy_holder >
00129     struct by_default
00130     {
00131         typedef ::std::map<qname_type, abs_reader_type * > map_type;
00132         static xistream & read(const map_type & map, xistream & xis)
00133         {
00134             attributes att;
00135             qname_type qname(L"",L"");
00136             typename map_type::const_iterator i_end=map.end();
00137             typename map_type::const_iterator i;
00138 
00139             XIMOL_PARSER_USING_NAMESPACE;
00140 
00141             while (drop_content(xis) && is_stag(xis))
00142             {
00143                 read_open_stag(xis,qname.second,att,qname.first);
00144                 i=map.find(qname);
00145                 if (i!=i_end)           
00146                     ((*i).second)->read(xis);
00147                 else {
00148                     read_stag(xis,qname.second,qname.first);
00149                     drop_element_until_etag(xis);
00150                     read_etag(xis,qname.second,qname.first);
00151                 }
00152             }
00153             return xis;
00154         };
00155     };
00156 }; // end of reader_policy
00157 
00158 //=============================================================================
00159 /// Class to read some shuffled stuff in XML.
00160 /** You must set all tags and launch the reader on an istream.
00161         @ingroup xml
00162     \todo make copie contructor and assignment operator.
00163   */
00164 //=============================================================================
00165 template < typename reading_policy_type = reader_policy::by_default<> >
00166 class reader
00167 {
00168 public:
00169     typedef helper::abstract_copy_holder abs_reader_type;
00170         typedef ::std::pair<xstring,xstring> qname_type;
00171     typedef ::std::map<qname_type, abs_reader_type * > map_type;
00172 
00173 protected:
00174     typedef map_type::iterator iterator;
00175     typedef map_type::const_iterator const_iterator;
00176 
00177 public:
00178 
00179     reader()
00180     {};
00181 
00182     template < typename String1, typename String2, typename T >
00183         reader(const String1 & uri, const String2 tag, const T& x)
00184     {
00185         operator()(uri,tag,x); 
00186     };
00187 
00188     template < typename String1, typename T >
00189         reader(const String1 & tag, const T& x)
00190     {
00191         operator()(tag,x); 
00192     };
00193 
00194     /// delete all pointer
00195     ~reader()
00196     {
00197         const_iterator i_end=end();
00198         const_iterator i=begin();
00199         for(;i!=i_end;++i) delete (*i).second;
00200     };
00201 
00202     template < typename String1, typename String2, typename T >
00203         reader & operator()(const String1 & uri, const String2 tag, const T& x)
00204     {
00205         return add_reader(str<xstring>::cast(uri), str<xstring>::cast(tag), new helper::copy_holder<T>(x)); 
00206     };
00207 
00208     template < typename String1, typename T >
00209         reader & operator()(const String1 & tag, const T& x)
00210     {
00211         return add_reader(str<xstring>::cast(""), str<xstring>::cast(tag), new helper::copy_holder<T>(x)); 
00212     };
00213 
00214     xistream& read(xistream& xis)
00215     {   
00216         return reading_policy_type::read(map_,xis);
00217     };
00218 
00219 protected:
00220     iterator       begin()       { return map_.begin(); };
00221     iterator       end  ()       { return map_.end(); };
00222     const_iterator begin() const { return map_.begin(); };
00223     const_iterator end  () const { return map_.end(); };
00224 
00225 private:
00226 
00227     reader& add_reader(const xstring& uri, const xstring& tag_name, abs_reader_type * p)
00228     {
00229             qname_type qname(uri,tag_name);
00230             const_iterator i_end=end();
00231             const_iterator i=map_.find(qname);
00232             if (i!=i_end) delete (*i).second;
00233             map_[qname]=p;
00234             return *this;
00235     };
00236 
00237 private:
00238     /// Map(tag, reference to read).
00239     map_type map_;
00240 }; // end of class reader
00241 
00242 //-----------------------------------------------------------------------------
00243 /// GetFrom operator for the reader
00244 //-----------------------------------------------------------------------------
00245 template < typename T >
00246 xistream& operator>>(xistream& xis, reader<T>& t)
00247 {
00248     return t.read(xis);
00249 };
00250 
00251 XIMOL_XML_END_NAMESPACE
00252 
00253 XIMOL_BEGIN_NAMESPACE
00254 
00255 template < typename T >
00256 struct ref_holder
00257 {
00258     ref_holder(T & t):x(t){};
00259     ref_holder(const ref_holder<T> & r):x(r.x){};
00260     ~ref_holder(){};
00261     T& get_ref(){return x; };
00262 private:
00263     ref_holder& operator=(const ref_holder<T> & r);
00264     T & x;
00265 };
00266 
00267 template < typename T > 
00268 xistream& operator>>(xistream& xis, ref_holder<T> & r)
00269 { 
00270     return xis >> r.get_ref();
00271 };
00272 
00273 template < typename T > 
00274 ref_holder<T> by_ref(T & x)
00275 { 
00276     return ref_holder<T>(x); 
00277 };
00278 
00279 template < typename T, typename callback_type>
00280 struct read_and_callback_type
00281 {
00282     read_and_callback_type(const callback_type & fun):f(fun){};
00283     callback_type f;
00284 };
00285 
00286 template < typename T, typename callback_type> 
00287 xistream& operator>>(xistream& xis, read_and_callback_type<T,callback_type> & r)
00288 { 
00289     T t;
00290     xis >> t;
00291     r.f(t);
00292     return xis;
00293 };
00294 
00295 template < typename T, typename callback_type >
00296 read_and_callback_type<T,callback_type> read_and_callback(T*, const callback_type & f)
00297 {
00298     return read_and_callback_type<T,callback_type>(f);
00299 };
00300 
00301 XIMOL_END_NAMESPACE
00302 
00303 #endif // #ifndef XIMOL_XML_READER_HPP_


Donate to the XiMoL project SourceForge.net Logo If you have any questions about XiMoL, you could write to tournois@users.sourceforge.net.