ParseDefConsume.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #ifndef ZYPP_PARSER_XML_PARSEDEFCONSUME_H
00013 #define ZYPP_PARSER_XML_PARSEDEFCONSUME_H
00014
00015 #include "zypp/base/PtrTypes.h"
00016 #include "zypp/base/Function.h"
00017 #include "zypp/base/Tr1hash.h"
00018 #include "zypp/base/String.h"
00019 #include "zypp/base/DefaultIntegral.h"
00020
00021 #include "zypp/parser/xml/Node.h"
00022
00024 namespace zypp
00025 {
00026
00027 namespace xml
00028 {
00029
00030 class Node;
00031
00033
00034
00035
00038 struct ParseDefConsume
00039 {
00040 virtual ~ParseDefConsume();
00041
00042 virtual void start( const Node & _node );
00043 virtual void text ( const Node & _node );
00044 virtual void cdata( const Node & _node );
00045 virtual void done ( const Node & _node );
00046
00047 virtual void startSubnode( const Node & _node );
00048 virtual void doneSubnode ( const Node & _node );
00049 };
00051
00053
00054
00055
00060 class ParseDefConsumeRedirect : public ParseDefConsume
00061 {
00062 public:
00063 ParseDefConsumeRedirect();
00064 ParseDefConsumeRedirect( const shared_ptr<ParseDefConsume> & target_r );
00065 ParseDefConsumeRedirect( ParseDefConsume * allocatedTarget_r );
00066 ParseDefConsumeRedirect( ParseDefConsume & target_r );
00067
00068 virtual ~ParseDefConsumeRedirect();
00069
00070 public:
00071 void setRedirect( const shared_ptr<ParseDefConsume> & target_r );
00072 void setRedirect( ParseDefConsume * allocatedTarget_r );
00073 void setRedirect( ParseDefConsume & target_r );
00074 void cancelRedirect();
00075
00076 shared_ptr<ParseDefConsume> getRedirect() const;
00077
00078 public:
00079 virtual void start( const Node & _node );
00080 virtual void text ( const Node & _node );
00081 virtual void cdata( const Node & _node );
00082 virtual void done ( const Node & _node );
00083 virtual void startSubnode( const Node & _node );
00084 virtual void doneSubnode ( const Node & _node );
00085
00086 private:
00087 shared_ptr<ParseDefConsume> _target;
00088 };
00090
00092
00093
00094
00097 class ParseDefConsumeCallback : public ParseDefConsume
00098 {
00099 public:
00100 typedef function<void(const Node &)> Callback;
00101
00102 ParseDefConsumeCallback();
00103
00104 virtual ~ParseDefConsumeCallback();
00105
00106 public:
00107 virtual void start( const Node & node_r );
00108 virtual void text( const Node & node_r );
00109 virtual void cdata( const Node & node_r );
00110 virtual void done( const Node & node_r );
00111 virtual void startSubnode( const Node & node_r );
00112 virtual void doneSubnode( const Node & node_r );
00113
00114 public:
00115 Callback _start;
00116 Callback _text;
00117 Callback _cdata;
00118 Callback _done;
00119 Callback _startSubnode;
00120 Callback _doneSubnode;
00121 };
00123
00125
00126 namespace parse_def_assign
00127 {
00128 template <class _Type> struct Assigner;
00129
00130 typedef shared_ptr<Assigner<void> > AssignerRef;
00131
00133 template <>
00134 struct Assigner<void>
00135 {
00136 virtual ~Assigner()
00137 {}
00138 virtual void assign( const char * text_r )
00139 {}
00140 };
00141
00145 template <class _Type>
00146 struct Assigner : public Assigner<void>
00147 {
00148 Assigner(_Type & value_r )
00149 : _value( &value_r )
00150 {}
00151
00152 virtual void assign( const char * text_r )
00153 { *_value = _Type( text_r ); }
00154
00155 private:
00156 _Type * _value;
00157 };
00158
00163 template <>
00164 inline void Assigner<short>::assign( const char * text_r ) { str::strtonum( text_r, *_value ); }
00165 template <>
00166 inline void Assigner<int>::assign( const char * text_r ) { str::strtonum( text_r, *_value ); }
00167 template <>
00168 inline void Assigner<long>::assign( const char * text_r ) { str::strtonum( text_r, *_value ); }
00169 template <>
00170 inline void Assigner<long long>::assign( const char * text_r ) { str::strtonum( text_r, *_value ); }
00171 template <>
00172 inline void Assigner<unsigned short>::assign( const char * text_r ) { str::strtonum( text_r, *_value ); }
00173 template <>
00174 inline void Assigner<unsigned>::assign( const char * text_r ) { str::strtonum( text_r, *_value ); }
00175 template <>
00176 inline void Assigner<unsigned long>::assign( const char * text_r ) { str::strtonum( text_r, *_value ); }
00177 template <>
00178 inline void Assigner<unsigned long long>::assign( const char * text_r ) { str::strtonum( text_r, *_value ); }
00179
00180 template <>
00181 inline void Assigner<bool>::assign( const char * text_r ) { str::strToBoolNodefault( text_r, *_value ); }
00183
00186 template <class _Type>
00187 inline AssignerRef assigner( _Type & value_r )
00188 { return AssignerRef( new Assigner<_Type>( value_r ) ); }
00189
00190 template <class _Tp, _Tp _Initial>
00191 inline AssignerRef assigner( DefaultIntegral<_Tp,_Initial> & value_r )
00192 { return AssignerRef( new Assigner<_Tp>( value_r.get() ) ); }
00194
00195
00213 struct Consumer : public ParseDefConsume
00214 {
00216 void add( const AssignerRef & assigner_r )
00217 { _text.push_back( assigner_r ); }
00218
00220 void add( const std::string & attr_r, const AssignerRef & assigner_r )
00221 { _attr[attr_r].push_back( assigner_r ); }
00222
00224 void prenotify( function<void ( const Node & )> pre_r )
00225 { _pre = pre_r; }
00226
00228 void postnotify( function<void ( const Node & )> post_r )
00229 { _post = post_r; }
00230
00231 virtual void start( const xml::Node & node_r )
00232 {
00233 if ( _pre )
00234 _pre( node_r );
00235
00236 if ( ! _attr.empty() )
00237 for_( it, _attr.begin(), _attr.end() )
00238 assign( it->second, node_r.getAttribute( it->first.c_str() ).c_str() );
00239 }
00240
00241 virtual void text( const xml::Node & node_r )
00242 {
00243 if ( ! _text.empty() )
00244 assign( _text, node_r.value().c_str() );
00245 }
00246
00247 virtual void done( const xml::Node & node_r )
00248 {
00249 if ( _post )
00250 _post( node_r );
00251 }
00252
00253 private:
00254 void assign( const std::vector<AssignerRef> & vec_r, const char * value_r )
00255 {
00256 if ( value_r )
00257 for_( it, vec_r.begin(), vec_r.end() )
00258 (*it)->assign( value_r );
00259 }
00260
00261 private:
00262 std::tr1::unordered_map<std::string, std::vector<AssignerRef> > _attr;
00263 std::vector<AssignerRef> _text;
00264 function<void ( const Node & )> _pre;
00265 function<void ( const Node & )> _post;
00266 };
00267
00281 struct Builder
00282 {
00284 Builder()
00285 : _ptr( new Consumer )
00286 {}
00287
00289 template <class _Type>
00290 Builder( _Type & value_r )
00291 : _ptr( new Consumer )
00292 { operator()( value_r ); }
00293
00295 template <class _Type>
00296 Builder( const std::string & attr_r, _Type & value_r )
00297 : _ptr( new Consumer )
00298 { operator()( attr_r, value_r ); }
00299
00301 template <class _Type>
00302 Builder & operator()( _Type & value_r )
00303 { _ptr->add( assigner( value_r ) ); return *this; }
00304
00306 template <class _Type>
00307 Builder & operator()( const std::string & attr_r, _Type & value_r )
00308 { _ptr->add( attr_r, assigner( value_r ) ); return *this; }
00309
00311 Builder & operator<<( function<void ( const Node & )> done_r )
00312 { _ptr->prenotify( done_r ); return *this; }
00313
00315 Builder & operator>>( function<void ( const Node & )> done_r )
00316 { _ptr->postnotify( done_r ); return *this; }
00317
00319 operator shared_ptr<ParseDefConsume> () const
00320 { return _ptr; }
00321
00322 private:
00323 shared_ptr<Consumer> _ptr;
00324 };
00326 }
00328
00356 inline parse_def_assign::Builder parseDefAssign()
00357 { return parse_def_assign::Builder(); }
00358
00359 template <class _Type>
00360 inline parse_def_assign::Builder parseDefAssign( _Type & value_r )
00361 { return parse_def_assign::Builder( value_r ); }
00362
00363 template <class _Type>
00364 inline parse_def_assign::Builder parseDefAssign( const std::string & attr_r, _Type & value_r )
00365 { return parse_def_assign::Builder( attr_r, value_r ); }
00367
00369 }
00372 }
00374 #endif // ZYPP_PARSER_XML_PARSEDEFCONSUME_H