2 #include <boost/call_traits.hpp>
8 #include <zypp/base/LogControl.h>
9 #include <zypp/base/LogTools.h>
11 #include "zypp/parser/xml/Reader.h"
16 #include "zypp/base/Exception.h"
17 #include "zypp/base/InputStream.h"
18 #include "zypp/base/DefaultIntegral.h"
19 #include <zypp/base/Function.h>
20 #include <zypp/base/Iterator.h>
21 #include <zypp/Pathname.h>
22 #include <zypp/ExplicitMap.h>
23 #include <zypp/Depository.h>
24 #include <zypp/Edition.h>
25 #include <zypp/CheckSum.h>
26 #include <zypp/Date.h>
28 ///////////////////////////////////////////////////////////////////
31 void ti( const _Cl & c )
33 SEC << __PRETTY_FUNCTION__ << endl;
36 ///////////////////////////////////////////////////////////////////
43 ///////////////////////////////////////////////////////////////////
45 ///////////////////////////////////////////////////////////////////
49 ///////////////////////////////////////////////////////////////////
51 bool nopNode( xml::Reader & reader_r )
56 bool accNode( xml::Reader & reader_r )
60 #define X(m) reader_r->m()
77 bool dumpNode( xml::Reader & reader_r )
79 switch ( reader_r->nodeType() )
81 case XML_READER_TYPE_ATTRIBUTE:
82 DBG << *reader_r << endl;
84 case XML_READER_TYPE_ELEMENT:
85 MIL << *reader_r << endl;
88 WAR << *reader_r << endl;
94 bool dumpNode2( xml::Reader & reader_r )
97 return reader_r.foreachNodeAttribute( dumpNode );
100 bool dumpEd( xml::Reader & reader_r )
103 if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT
104 && reader_r->name() == "version" )
106 MIL << *reader_r << endl;
107 DBG << reader_r->getAttribute( "rel" ) << endl;
108 ERR << *reader_r << endl;
109 DBG << reader_r->getAttribute( "ver" ) << endl;
110 ERR << *reader_r << endl;
111 DBG << reader_r->getAttribute( "epoch" ) << endl;
112 ERR << *reader_r << endl;
113 WAR << Edition( reader_r->getAttribute( "ver" ).asString(),
114 reader_r->getAttribute( "rel" ).asString(),
115 reader_r->getAttribute( "epoch" ).asString() ) << endl;
122 ///////////////////////////////////////////////////////////////////
132 Depository<std::string> _type;
133 Depository<CheckSum> _checksum;
134 Depository<Date> _timestamp;
135 Depository<CheckSum> _openChecksum;
138 Depository<Data> _data;
155 CheckSum _openChecksum;
158 std::map<std::string, Data> _data;
162 ///////////////////////////////////////////////////////////////////
167 std::ostream & operator<<( std::ostream & str, const Element & obj );
169 struct Element : private base::NonCopyable
171 Element( xml::Reader & reader_r )
172 : _reader( reader_r )
173 , _name( _reader->name().asString() )
174 , _depth( _reader->depth() )
176 MIL << *this << endl;
178 while( nextElement() )
180 Element el( _reader );
186 while( nextElement() )
188 DBG << *this << endl;
193 return ( _reader->depth() == _depth
194 && _reader->nodeType() == XML_READER_TYPE_ELEMENT
195 && _reader->name().c_str() == _name );
200 return ( _reader->depth() == _depth
201 && ( _reader->nodeType() == XML_READER_TYPE_END_ELEMENT
202 || ( _reader->nodeType() == XML_READER_TYPE_ELEMENT
203 && _reader->isEmptyElement() ) )
204 && _reader->name().c_str() == _name );
211 if ( ! _reader.nextNode() )
213 if ( _reader->nodeType() == XML_READER_TYPE_ELEMENT )
215 WAR << *_reader << endl;
221 xml::Reader & _reader;
226 std::ostream & operator<<( std::ostream & str, const Element & obj )
228 str << ( obj.atBegin() ? 'B' : '_' )
229 << ( obj.atEnd() ? 'E' : '_' )
230 << obj._depth << ":" << std::string( obj._depth, ' ') << obj._name
231 << " {" << *obj._reader << '}';
235 bool dumpEl( xml::Reader & reader_r )
237 Element el( reader_r );
241 void parse2( const InputStream & file_r )
243 Measure x( file_r.name() );
246 MIL << file_r << endl;
247 xml::Reader r( file_r );
252 catch ( const Exception & )
256 ///////////////////////////////////////////////////////////////////
260 typedef function<void( xml::Reader & )> Consumer;
261 typedef ExplicitMap<std::string,Consumer> ConsumerMap;
263 BasicParser( const InputStream & file_r )
269 xml::Reader & reader()
272 const xml::Reader & reader() const
278 const ConsumerMap & cmap() const
283 bool parse( xml::Reader & reader_r )
285 switch ( reader_r->nodeType() )
287 case XML_READER_TYPE_ELEMENT:
288 case XML_READER_TYPE_TEXT:
289 case XML_READER_TYPE_CDATA:
290 case XML_READER_TYPE_END_ELEMENT:
299 void consume( xml::Reader & reader_r, const std::string & key_r )
300 { _cmap[key_r]( reader_r ); }
302 void consume( xml::Reader & reader_r )
303 { consume( reader_r, reader_r->name().asString() ); }
306 { consume( _reader ); }
309 static void nop( xml::Reader & reader_r )
312 static void log( xml::Reader & reader_r )
313 { DBG << "NOP " << *reader_r << endl; }
321 ///////////////////////////////////////////////////////////////////
323 struct RepomdParser : private BasicParser
325 RepomdParser( const InputStream & file_r )
326 : BasicParser( file_r )
328 reader().foreachNode( ref(*this) );
331 bool operator()( xml::Reader & reader_r )
333 return parse( reader_r );
339 ///////////////////////////////////////////////////////////////////
346 //unused: Date _timestamp;
347 //unused: CheckSum _openChecksum;
350 typedef void (Consume::*Consumer)( xml::Reader & reader_r );
352 Consume( const InputStream & file_r )
354 , _consume( &Consume::nop )
357 _consume.set( "data", &Consume::data );
358 _reader.foreachNode( ref(*this) );
361 bool operator()( xml::Reader & reader_r )
363 switch ( reader_r->nodeType() )
365 case XML_READER_TYPE_ELEMENT:
366 (this->*_consume[reader_r->name().asString()])( reader_r );
370 WAR << *_reader << endl;
376 void nop( xml::Reader & reader_r )
379 void log( xml::Reader & reader_r )
380 { DBG << "NOP " << *_reader << endl; }
382 void data( xml::Reader & reader_r )
384 MIL << *_reader << endl;
385 _result[reader_r->name().asString()] = Entry();
391 ExplicitMap<std::string,Consumer> _consume;
392 std::map<std::string,Entry> _result;
396 std::ostream & operator<<( std::ostream & str, const Consume & obj )
401 std::ostream & operator<<( std::ostream & str, const Consume::Entry & obj )
403 return str << "Entry";
406 void parse( const InputStream & file_r )
408 Measure x( file_r.name() );
411 MIL << file_r << endl;
412 RepomdParser a( file_r );
413 //WAR << a._result << endl;
415 catch ( const Exception & )
431 void setb( const string & v )
447 std::ostream & operator<<( std::ostream & str, const Test & obj )
449 return str << "Test(" << obj.a << '|' << obj.b
450 << '|' << obj.c.a << '|' << obj.c.b << ')';
456 : outfile( "susedu.xml", std::ios_base::out )
459 static const bool indented = !false;
460 static const bool shorttags = !true;
461 std::fstream outfile;
463 bool operator()( xml::Reader & reader_r )
465 switch ( reader_r->nodeType() )
467 case XML_READER_TYPE_ELEMENT:
468 process( reader_r, true );
470 case XML_READER_TYPE_END_ELEMENT:
471 process( reader_r, false );
474 //WAR << *reader_r << endl;
485 bool operator<( const File & rhs ) const
486 { return( name < rhs.name ); }
497 std::set<File> files;
500 shared_ptr<Package> pkg;
502 void process( xml::Reader & reader_r, bool open_r )
504 if ( reader_r->name() == "file" )
509 else if ( reader_r->name() == "version" )
512 addVersion( reader_r );
514 else if ( reader_r->name() == "package" )
517 startPackage( reader_r );
521 else if ( reader_r->name() == "filelists" )
523 DBG << *reader_r << endl;
526 DBG << outfile << endl;
527 outfile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
528 outfile << "<susedu>" << endl;
532 outfile << "</susedu>" << endl;
542 void startPackage( xml::Reader & reader_r )
545 pkg.reset( new Package );
546 pkg->pkgid = reader_r->getAttribute( "pkgid" ).asString();
547 pkg->name = reader_r->getAttribute( "name" ).asString();
548 pkg->arch = reader_r->getAttribute( "arch" ).asString();
551 void addVersion( xml::Reader & reader_r )
553 pkg->epoch = reader_r->getAttribute( "epoch" ).asString();
554 pkg->ver = reader_r->getAttribute( "ver" ).asString();
555 pkg->rel = reader_r->getAttribute( "rel" ).asString();
558 void addFile( xml::Reader & reader_r )
561 f.type = reader_r->getAttribute( "type" ).asString();
562 for( reader_r.nextNode();
563 reader_r->nodeType() != XML_READER_TYPE_END_ELEMENT;
564 reader_r.nextNode() )
566 if ( reader_r->nodeType() == XML_READER_TYPE_TEXT )
568 f.name = reader_r->value().asString();
571 pkg->files.insert( f );
578 writePackage( outfile );
583 static std::ostream & putAttr( std::ostream & stream_r,
584 const std::string & tag_r,
585 const std::string & value_r )
587 if ( value_r.empty() || tag_r.empty() )
590 << str::form( " %s=\"%s\"", tag_r.c_str(), value_r.c_str() );
593 void writePackage( std::ostream & stream_r )
595 stream_r << " <package";
596 putAttr( stream_r, "pkgid", pkg->pkgid );
597 putAttr( stream_r, "name", pkg->name );
598 putAttr( stream_r, "arch", pkg->arch );
601 stream_r << " <version";
602 putAttr( stream_r, "epoch", pkg->epoch );
603 putAttr( stream_r, "ver", pkg->ver );
604 putAttr( stream_r, "rel", pkg->rel );
607 writePackageFiles2( stream_r );
609 stream_r << " </package>\n";
612 void writePackageFiles( std::ostream & stream_r )
614 for ( std::set<File>::const_iterator it = pkg->files.begin();
615 it != pkg->files.end(); ++it )
617 stream_r << " <file";
618 putAttr( stream_r, "type", it->type );
619 stream_r << ">" << it->name << "</file>\n";
625 Fnode( const std::string & name_r )
631 mutable const File * entry;
632 mutable std::set<Fnode> children;
634 const Fnode * add( const std::string & sub_r ) const
636 std::set<Fnode>::iterator i = children.find( sub_r );
637 if ( i != children.end() )
639 return &(*(children.insert( Fnode( sub_r ) ).first));
642 void dump( std::ostream & stream_r, const std::string & pname, unsigned level ) const
649 else if ( pname == "/" )
655 tname = pname+"/"+name;
658 if ( children.size() == 1 )
660 children.begin()->dump( stream_r, tname, (indented?level:0) );
665 stream_r << std::string( level, ' ' );
669 tag = (shorttags ? "f" : "file");
670 stream_r << "<" << tag;
671 putAttr( stream_r, (shorttags ? "t" : "type"), entry->type );
672 putAttr( stream_r, (shorttags ? "n" : "name"), tname );
676 tag = (shorttags ? "b" : "base");
677 stream_r << "<" << tag;
678 putAttr( stream_r, (shorttags ? "n" : "name"), tname );
681 if ( children.empty() )
683 stream_r << "/>" << (indented?"\n":"");
687 stream_r << ">" << (indented?"\n":"");
688 for ( std::set<Fnode>::const_iterator it = children.begin();
689 it != children.end(); ++it )
691 it->dump( stream_r, "", (indented?level+1:0) );
693 stream_r << std::string( level, ' ' ) << "</" << tag << ">" << (indented?"\n":"");
697 bool operator<( const Fnode & rhs ) const
698 { return( name < rhs.name ); }
701 void writePackageFiles2( std::ostream & stream_r )
704 for ( std::set<File>::const_iterator it = pkg->files.begin();
705 it != pkg->files.end(); ++it )
707 std::list<std::string> words;
708 str::split( it->name, std::back_inserter(words), "/" );
710 const Fnode * c = &root;
711 for ( std::list<std::string>::const_iterator w = words.begin();
712 w != words.end(); ++w )
718 root.dump( stream_r, "/", (indented?3:0) );
723 /******************************************************************
725 ** FUNCTION NAME : main
726 ** FUNCTION TYPE : int
728 int main( int argc, char * argv[] )
730 INT << "===[START]==========================================" << endl;
733 Pathname repodata( "/Local/PATCHES/repodata" );
734 //repodata = "/Local/FACTORY/repodata";
735 xml::Reader reader( repodata/"filelists.xml" );
737 reader.foreachNode( ref(t) );
739 INT << "===[END]============================================" << endl << endl;
743 Pathname repodata( "/Local/PATCHES/repodata" );
744 //repodata = "/Local/FACTORY/repodata";
745 InputStream x ( "/Local/PATCHES/repodata" );
746 parse2( repodata/"repomd.xml" );
747 //parse2( repodata/"primary.xml" );
749 INT << "===[END]============================================" << endl << endl;
753 for ( int i = 1; i; --i )
755 parse( repodata/"repomd.xml" );
756 parse( repodata/"primary.xml" );
757 parse( repodata/"filelists.xml" );
758 parse( repodata/"other.xml" );
761 ERR << "done..." << endl;
766 for ( int i = 20; i; --i )
768 parse( (repodata/"repomd.xml").asString() );
769 parse( repodata/"primary.xml" );
770 parse( repodata/"filelists.xml" );
771 parse( repodata/"other.xml" );
774 ERR << "done..." << endl;
777 INT << "===[END]============================================" << endl << endl;