libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 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 // CLASS NAME : ParseDefConsume 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 // CLASS NAME : ParseDefConsumeRedirect 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 // CLASS NAME : ParseDefConsumeCallback 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 } // namespace parse_def_assign 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 } // namespace xml 00372 } // namespace zypp 00374 #endif // ZYPP_PARSER_XML_PARSEDEFCONSUME_H