Imported Upstream version 14.48.2
[platform/upstream/libzypp.git] / devel / devel.ma / FilelistTransform.cc
1 #include "Tools.h"
2 #include <boost/call_traits.hpp>
3
4 #include <iostream>
5 #include <fstream>
6 #include <map>
7
8 #include <zypp/base/LogControl.h>
9 #include <zypp/base/LogTools.h>
10
11 #include "zypp/parser/xml/Reader.h"
12
13 using namespace std;
14 using namespace zypp;
15
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>
27
28 ///////////////////////////////////////////////////////////////////
29
30 template<class _Cl>
31   void ti( const _Cl & c )
32   {
33     SEC << __PRETTY_FUNCTION__ << endl;
34   }
35
36 ///////////////////////////////////////////////////////////////////
37 namespace zypp
38 {
39   namespace parser
40   {
41     namespace yum
42     {
43       ///////////////////////////////////////////////////////////////////
44
45       ///////////////////////////////////////////////////////////////////
46     }
47   }
48 }
49 ///////////////////////////////////////////////////////////////////
50
51 bool nopNode( xml::Reader & reader_r )
52 {
53   return true;
54 }
55
56 bool accNode( xml::Reader & reader_r )
57 {
58   int i;
59   xml::XmlString s;
60 #define X(m) reader_r->m()
61       i=X(readState);
62       i=X(lineNumber);
63       i=X(columnNumber);
64       i=X(depth);
65       i=X(nodeType);
66       s=X(name);
67       s=X(prefix);
68       s=X(localName);
69       i=X(hasAttributes);
70       i=X(attributeCount);
71       i=X(hasValue);
72       s=X(value);
73 #undef X
74       return true;
75 }
76
77 bool dumpNode( xml::Reader & reader_r )
78 {
79   switch ( reader_r->nodeType() )
80     {
81     case XML_READER_TYPE_ATTRIBUTE:
82        DBG << *reader_r << endl;
83        break;
84     case XML_READER_TYPE_ELEMENT:
85        MIL << *reader_r << endl;
86        break;
87     default:
88        WAR << *reader_r << endl;
89        break;
90     }
91   return true;
92 }
93
94 bool dumpNode2( xml::Reader & reader_r )
95 {
96   dumpNode( reader_r );
97   return reader_r.foreachNodeAttribute( dumpNode );
98 }
99
100 bool dumpEd( xml::Reader & reader_r )
101 {
102   static int num = 5;
103   if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT
104        && reader_r->name() == "version" )
105     {
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;
116       --num;
117     }
118   return num;
119 }
120
121
122 ///////////////////////////////////////////////////////////////////
123
124 namespace parser
125 {
126   namespace consume
127   {
128     struct Repomd
129     {
130       struct Data
131       {
132         Depository<std::string> _type;
133         Depository<CheckSum>    _checksum;
134         Depository<Date>        _timestamp;
135         Depository<CheckSum>    _openChecksum;
136       };
137
138       Depository<Data> _data;
139     };
140   }
141
142
143
144 }
145
146 namespace data
147 {
148   struct Repomd
149   {
150     struct Data
151     {
152       std::string _type;
153       CheckSum    _checksum;
154       Date        _timestamp;
155       CheckSum    _openChecksum;
156     };
157
158     std::map<std::string, Data> _data;
159   };
160 }
161
162 ///////////////////////////////////////////////////////////////////
163
164
165
166 struct Element;
167 std::ostream & operator<<( std::ostream & str, const Element & obj );
168
169 struct Element : private base::NonCopyable
170 {
171   Element( xml::Reader & reader_r )
172   : _reader( reader_r )
173   , _name( _reader->name().asString() )
174   , _depth( _reader->depth() )
175   {
176     MIL << *this << endl;
177     //return;
178     while( nextElement() )
179       {
180         Element el( _reader );
181       }
182   }
183
184   ~Element()
185   {
186     while( nextElement() )
187       { ; }
188     DBG << *this << endl;
189   }
190
191   bool atBegin() const
192   {
193     return ( _reader->depth() == _depth
194              && _reader->nodeType() == XML_READER_TYPE_ELEMENT
195              && _reader->name().c_str() == _name );
196   }
197
198   bool atEnd() const
199   {
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 );
205   }
206
207   bool nextElement()
208   {
209     while ( ! atEnd() )
210       {
211         if ( ! _reader.nextNode() )
212           return false;
213         if ( _reader->nodeType() == XML_READER_TYPE_ELEMENT )
214           return true;
215         WAR << *_reader << endl;
216       }
217     return false;
218   }
219
220
221   xml::Reader & _reader;
222   std::string   _name;
223   int           _depth;
224 };
225
226 std::ostream & operator<<( std::ostream & str, const Element & obj )
227 {
228   str << ( obj.atBegin() ? 'B' : '_' )
229       << ( obj.atEnd() ? 'E' : '_' )
230       << obj._depth << ":" <<  std::string( obj._depth, ' ') << obj._name
231       << " {" << *obj._reader << '}';
232   return str;
233 }
234
235 bool dumpEl( xml::Reader & reader_r )
236 {
237   Element el( reader_r );
238   return true;
239 }
240
241 void parse2( const InputStream & file_r )
242 {
243   Measure x( file_r.name() );
244   try
245     {
246       MIL << file_r << endl;
247       xml::Reader r( file_r );
248       MIL << *r << endl;
249       Element el( r );
250       MIL << *r << endl;
251     }
252   catch ( const Exception & )
253     {
254     }
255 }
256 ///////////////////////////////////////////////////////////////////
257 class BasicParser
258 {
259   public:
260     typedef function<void( xml::Reader & )>   Consumer;
261     typedef ExplicitMap<std::string,Consumer> ConsumerMap;
262
263     BasicParser( const InputStream & file_r )
264     : _reader( file_r )
265     , _cmap( nop )
266     {}
267
268   public:
269     xml::Reader & reader()
270     { return _reader; }
271
272     const xml::Reader & reader() const
273     { return _reader; }
274
275     ConsumerMap & cmap()
276     { return _cmap; }
277
278     const ConsumerMap & cmap() const
279     { return _cmap; }
280
281   public:
282
283     bool parse( xml::Reader & reader_r )
284     {
285       switch ( reader_r->nodeType() )
286         {
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:
291           consume( reader_r );
292         default:
293           ;
294         }
295       return true;
296     }
297
298   public:
299     void consume( xml::Reader & reader_r, const std::string & key_r )
300     { _cmap[key_r]( reader_r ); }
301
302     void consume( xml::Reader & reader_r )
303     { consume( reader_r, reader_r->name().asString() ); }
304
305     void consume()
306     { consume( _reader ); }
307
308   public:
309     static void nop( xml::Reader & reader_r )
310     { ; }
311
312     static void log( xml::Reader & reader_r )
313     { DBG << "NOP " << *reader_r << endl; }
314
315
316   protected:
317     xml::Reader _reader;
318     ConsumerMap _cmap;
319 };
320
321 ///////////////////////////////////////////////////////////////////
322
323 struct RepomdParser : private BasicParser
324 {
325   RepomdParser( const InputStream & file_r )
326   : BasicParser( file_r )
327   {
328     reader().foreachNode( ref(*this) );
329   }
330
331   bool operator()( xml::Reader & reader_r )
332   {
333     return parse( reader_r );
334   }
335
336   // READER goes here!
337 };
338
339 ///////////////////////////////////////////////////////////////////
340 struct Consume
341 {
342   struct Entry
343   {
344     Pathname _location;
345     CheckSum _checksum;
346     //unused: Date     _timestamp;
347     //unused: CheckSum _openChecksum;
348   };
349
350   typedef void (Consume::*Consumer)( xml::Reader & reader_r );
351
352   Consume( const InputStream & file_r )
353   : _reader( file_r )
354   , _consume( &Consume::nop )
355   , _centry( NULL )
356   {
357     _consume.set( "data", &Consume::data );
358     _reader.foreachNode( ref(*this) );
359   }
360
361   bool operator()( xml::Reader & reader_r )
362   {
363     switch ( reader_r->nodeType() )
364       {
365       case XML_READER_TYPE_ELEMENT:
366         (this->*_consume[reader_r->name().asString()])( reader_r );
367         //data( reader_r );
368         break;
369       default:
370         WAR << *_reader << endl;
371         break;
372       }
373     return true;
374   }
375
376   void nop( xml::Reader & reader_r )
377   { ; }
378
379   void log( xml::Reader & reader_r )
380   { DBG << "NOP " << *_reader << endl; }
381
382   void data( xml::Reader & reader_r )
383   {
384     MIL << *_reader << endl;
385     _result[reader_r->name().asString()] = Entry();
386   }
387
388
389
390   xml::Reader _reader;
391   ExplicitMap<std::string,Consumer> _consume;
392   std::map<std::string,Entry> _result;
393   Entry * _centry;
394 };
395
396 std::ostream & operator<<( std::ostream & str, const Consume & obj )
397 {
398   return str;
399 }
400
401 std::ostream & operator<<( std::ostream & str, const Consume::Entry & obj )
402 {
403   return str << "Entry";
404 }
405
406 void parse( const InputStream & file_r )
407 {
408   Measure x( file_r.name() );
409   try
410     {
411       MIL << file_r << endl;
412       RepomdParser a( file_r );
413       //WAR << a._result << endl;
414     }
415   catch ( const Exception & )
416     {
417     }
418 }
419
420 struct Test
421 {
422   struct Mix
423   {
424     Mix()
425     : a( 0 )
426     {}
427
428     void seta( int v )
429     { a = v; }
430
431     void setb( const string & v )
432     { b = v; }
433
434     int    a;
435     string b;
436    };
437
438   Test()
439   : a( 0 )
440   {}
441
442   int    a;
443   string b;
444   Mix    c;
445 };
446
447 std::ostream & operator<<( std::ostream & str, const Test & obj )
448 {
449   return str << "Test(" << obj.a << '|' << obj.b
450              << '|' << obj.c.a << '|' << obj.c.b << ')';
451 }
452
453 struct Transform
454 {
455   Transform()
456   : outfile( "susedu.xml", std::ios_base::out )
457   {}
458
459   static const bool indented = !false;
460   static const bool shorttags = !true;
461   std::fstream outfile;
462
463   bool operator()( xml::Reader & reader_r )
464   {
465     switch ( reader_r->nodeType() )
466       {
467       case XML_READER_TYPE_ELEMENT:
468         process( reader_r, true );
469         break;
470       case XML_READER_TYPE_END_ELEMENT:
471         process( reader_r, false );
472         break;
473       default:
474         //WAR << *reader_r << endl;
475         break;
476       }
477     return true;
478   }
479
480   struct File
481   {
482     std::string name;
483     std::string type;
484
485     bool operator<( const File & rhs ) const
486     { return( name < rhs.name ); }
487   };
488
489   struct Package
490   {
491     std::string    pkgid;
492     std::string    name;
493     std::string    epoch;
494     std::string    ver;
495     std::string    rel;
496     std::string    arch;
497     std::set<File> files;
498   };
499
500   shared_ptr<Package> pkg;
501
502   void process( xml::Reader & reader_r, bool open_r )
503   {
504     if ( reader_r->name() == "file" )
505       {
506         if ( open_r )
507           addFile( reader_r );
508       }
509     else if ( reader_r->name() == "version" )
510       {
511         if ( open_r )
512           addVersion( reader_r );
513       }
514     else if ( reader_r->name() == "package" )
515       {
516         if ( open_r )
517           startPackage( reader_r );
518         else
519           endPackage();
520       }
521     else if ( reader_r->name() == "filelists" )
522       {
523         DBG << *reader_r << endl;
524         if ( open_r )
525           {
526             DBG << outfile << endl;
527             outfile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
528             outfile << "<susedu>" << endl;
529           }
530         else
531           {
532             outfile << "</susedu>" << endl;
533             outfile.close();
534           }
535       }
536     else
537       {
538         throw;
539       }
540   }
541
542   void startPackage( xml::Reader & reader_r )
543   {
544     endPackage();
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();
549   }
550
551   void addVersion( xml::Reader & reader_r )
552   {
553     pkg->epoch = reader_r->getAttribute( "epoch" ).asString();
554     pkg->ver = reader_r->getAttribute( "ver" ).asString();
555     pkg->rel = reader_r->getAttribute( "rel" ).asString();
556   }
557
558   void addFile( xml::Reader & reader_r )
559   {
560     File f;
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() )
565       {
566         if ( reader_r->nodeType() == XML_READER_TYPE_TEXT )
567           {
568             f.name = reader_r->value().asString();
569           }
570       }
571     pkg->files.insert( f );
572   }
573
574   void endPackage()
575   {
576     if ( pkg )
577       {
578         writePackage( outfile );
579         pkg.reset();
580       }
581   }
582
583   static std::ostream & putAttr( std::ostream & stream_r,
584                                  const std::string & tag_r,
585                                  const std::string & value_r )
586   {
587     if ( value_r.empty() || tag_r.empty() )
588       return stream_r;
589     return stream_r
590            << str::form( " %s=\"%s\"", tag_r.c_str(), value_r.c_str() );
591   }
592
593   void writePackage( std::ostream & stream_r )
594   {
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 );
599     stream_r << ">\n";
600
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 );
605     stream_r << "/>\n";
606
607     writePackageFiles2( stream_r );
608
609     stream_r << " </package>\n";
610   }
611
612   void writePackageFiles( std::ostream & stream_r )
613   {
614     for ( std::set<File>::const_iterator it = pkg->files.begin();
615           it != pkg->files.end(); ++it )
616       {
617         stream_r << "   <file";
618         putAttr( stream_r, "type", it->type );
619         stream_r << ">" << it->name << "</file>\n";
620       }
621   }
622
623   struct Fnode
624   {
625     Fnode( const std::string & name_r )
626     : name( name_r )
627     , entry( NULL )
628     {}
629
630     std::string             name;
631     mutable const File *    entry;
632     mutable std::set<Fnode> children;
633
634     const Fnode * add( const std::string & sub_r ) const
635     {
636       std::set<Fnode>::iterator i = children.find( sub_r );
637       if ( i != children.end() )
638         return &(*i);
639       return &(*(children.insert( Fnode( sub_r ) ).first));
640     }
641
642     void dump( std::ostream & stream_r, const std::string & pname, unsigned level ) const
643     {
644       std::string tname;
645       if ( pname.empty() )
646         {
647           tname = name;
648         }
649       else if ( pname == "/" )
650         {
651           tname = pname+name;
652         }
653       else
654         {
655           tname = pname+"/"+name;
656         }
657
658       if ( children.size() == 1 )
659         {
660           children.begin()->dump( stream_r, tname, (indented?level:0) );
661           return;
662         }
663
664       std::string tag;
665       stream_r << std::string( level, ' ' );
666
667       if ( entry )
668         {
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 );
673         }
674       else
675         {
676           tag = (shorttags ? "b" : "base");
677           stream_r << "<" << tag;
678           putAttr( stream_r, (shorttags ? "n" : "name"), tname );
679         }
680
681       if ( children.empty() )
682         {
683           stream_r << "/>" << (indented?"\n":"");
684         }
685       else
686         {
687           stream_r << ">" << (indented?"\n":"");
688           for ( std::set<Fnode>::const_iterator it = children.begin();
689                 it != children.end(); ++it )
690             {
691               it->dump( stream_r, "", (indented?level+1:0) );
692             }
693           stream_r << std::string( level, ' ' ) << "</" << tag << ">" << (indented?"\n":"");
694         }
695     }
696
697     bool operator<( const Fnode & rhs ) const
698     { return( name < rhs.name ); }
699   };
700
701   void writePackageFiles2( std::ostream & stream_r )
702   {
703     Fnode root( "" );
704     for ( std::set<File>::const_iterator it = pkg->files.begin();
705           it != pkg->files.end(); ++it )
706       {
707         std::list<std::string> words;
708         str::split( it->name, std::back_inserter(words), "/" );
709
710         const Fnode * c = &root;
711         for ( std::list<std::string>::const_iterator w = words.begin();
712               w != words.end(); ++w )
713           {
714             c = c->add( *w );
715           }
716         c->entry = &(*it);
717       }
718     root.dump( stream_r, "/", (indented?3:0) );
719   }
720
721 };
722
723 /******************************************************************
724 **
725 **      FUNCTION NAME : main
726 **      FUNCTION TYPE : int
727 */
728 int main( int argc, char * argv[] )
729 {
730   INT << "===[START]==========================================" << endl;
731   {
732     Measure x;
733     Pathname repodata( "/Local/PATCHES/repodata" );
734     //repodata = "/Local/FACTORY/repodata";
735     xml::Reader reader( repodata/"filelists.xml" );
736     Transform t;
737     reader.foreachNode( ref(t) );
738   }
739   INT << "===[END]============================================" << endl << endl;
740   return 0;
741   int s;
742
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" );
748
749   INT << "===[END]============================================" << endl << endl;
750   return 0;
751   {
752     Measure x;
753     for ( int i = 1; i; --i )
754       {
755         parse( repodata/"repomd.xml" );
756         parse( repodata/"primary.xml" );
757         parse( repodata/"filelists.xml" );
758         parse( repodata/"other.xml" );
759       }
760   }
761   ERR << "done..." << endl;
762   cin >> s;
763   return 0;
764   {
765     Measure x;
766     for ( int i = 20; i; --i )
767       {
768         parse( (repodata/"repomd.xml").asString() );
769         parse( repodata/"primary.xml" );
770         parse( repodata/"filelists.xml" );
771         parse( repodata/"other.xml" );
772       }
773   }
774   ERR << "done..." << endl;
775   cin >> s;
776
777   INT << "===[END]============================================" << endl << endl;
778   return 0;
779 }
780