00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
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
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
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
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 };
00125
00126
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 };
00157
00158
00159
00160
00161
00162
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
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
00239 map_type map_;
00240 };
00241
00242
00243
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_