libzypp  10.5.0
ParseDefConsume.h
Go to the documentation of this file.
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