PackagesDuFileReader.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <cstdlib>
00014 #include "zypp/base/Easy.h"
00015 #include "zypp/base/Regex.h"
00016 #include "zypp/base/Logger.h"
00017 #include "zypp/base/String.h"
00018 #include "zypp/ZYppFactory.h"
00019 
00020 #include "zypp/parser/susetags/PackagesDuFileReader.h"
00021 #include "zypp/parser/susetags/FileReaderBaseImpl.h"
00022 
00023 using std::endl;
00024 #undef  ZYPP_BASE_LOGGER_LOGGROUP
00025 #define ZYPP_BASE_LOGGER_LOGGROUP "parser::susetags"
00026 
00028 namespace zypp
00029 { 
00030 
00031   namespace parser
00032   { 
00033 
00034     namespace susetags
00035     { 
00036 
00038       //
00039       //        CLASS NAME : PackagesDuFileReader::Impl
00040       //
00042       class PackagesDuFileReader::Impl : public BaseImpl
00043       {
00044         public:
00045           Impl( const PackagesDuFileReader & parent_r )
00046           : BaseImpl( parent_r )
00047           {
00048             _mounts = getZYpp()->getPartitions();
00049 
00050             for ( DiskUsageCounter::MountPointSet::const_iterator it = _mounts.begin();
00051                   it != _mounts.end();
00052                   ++ it )
00053             {
00054               MIL << "Partition " << *it << endl;
00055             }
00056 
00057           }
00058 
00059           virtual ~Impl()
00060           {}
00061 
00062           bool hasPackage() const
00063           { return _pkgData; }
00064 
00065           bool hasSourcepackage() const
00066           { return _srcpkgData; }
00067 
00068           data::Package_Ptr handoutPackage()
00069           {
00070             data::Package_Ptr ret;
00071             ret.swap( _pkgData );
00072             _srcpkgData = 0;
00073             _data       = 0;
00074             return ret;
00075           }
00076 
00077           data::SrcPackage_Ptr handoutSourcepackage()
00078           {
00079             data::SrcPackage_Ptr ret;
00080             ret.swap( _srcpkgData );
00081             _pkgData = 0;
00082             _data    = 0;
00083             return ret;
00084           }
00085 
00086         public: // single tags
00088           void consumeVer( const SingleTagPtr & tag_r )
00089           { /* NOP */; }
00090 
00092           void consumePkg( const SingleTagPtr & tag_r )
00093           {
00094             std::vector<std::string> words;
00095             if ( str::split( tag_r->value, std::back_inserter(words) ) != 4 )
00096             {
00097               ZYPP_THROW( error( tag_r, "Expected [name version release arch]") );
00098             }
00099 
00100             if ( words[3] == "src" || words[3] == "nosrc")
00101             {
00102               ++_c_srcpkg;
00103               _data = _srcpkgData = new data::SrcPackage;
00104               _pkgData = 0;
00105               // _data->arch is arch_noarch per default
00106             }
00107             else
00108             {
00109               ++_c_pkg;
00110               _data = _pkgData = new data::Package;
00111               _srcpkgData = 0;
00112               _data->arch = Arch( words[3] );
00113             }
00114             _data->name    = words[0];
00115             _data->edition = Edition( words[1],words[2] );
00116           }
00117 
00118 
00119         public: // multi tags
00121           void consumeDir( const MultiTagPtr & tag_r )
00122           {
00123             static str::regex  sizeEntryRX( "^(.*/)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]*$" );
00124             static str::smatch what;
00125 
00126             _data->diskusage;
00127 
00128             for_( it, tag_r->value.begin(), tag_r->value.end() )
00129             {
00130               if ( str::regex_match( *it, what, sizeEntryRX ) )
00131               {
00132                 bool skip = true;
00133                 DiskUsage::Entry entry( what[1],
00134                                         str::strtonum<unsigned>(what[2]) + str::strtonum<unsigned>(what[3]),
00135                                         str::strtonum<unsigned>(what[4]) + str::strtonum<unsigned>(what[5]) );
00136 
00137                 // the partitioning is not known or we are running in instsys (see #308659)
00138                 if ( _mounts.empty() || (getenv("YAST_IS_RUNNING") && (std::string(getenv("YAST_IS_RUNNING")) == "instsys" )))
00139                 {
00140                   // if no mount information, cut off deeper directory
00141                   // levels in DiskUsage::Entry to reduce data size.
00142                   unsigned level             = 3; // number of '/' incl. a trailing one
00143                   std::string::size_type pos = 0; // we store absolute pathnames
00144                   while ( --level && pos != std::string::npos )
00145                   {
00146                     pos = entry.path.find( "/", pos+1 );
00147                   }
00148                   if ( pos != std::string::npos )
00149                   {
00150                     // found 'level' number of '/'es.
00151                     skip = ( entry.path[pos+1] != '\0' );
00152                   }
00153                   else
00154                   {
00155                     // less than 'level' number of '/'es.
00156                     skip = false;
00157                   }
00158                 }
00159                 else
00160                 {
00161                   // Store entries, if they are equal to or parent of a mountpoint.
00162                   for ( DiskUsageCounter::MountPointSet::reverse_iterator mit = _mounts.rbegin();
00163                         mit != _mounts.rend();
00164                         ++ mit )
00165                   {
00166                     // Entry.path has leading and trailing '/' (asserted by DiskUsage::Entry).
00167                     // So we append a '/' to the mountpoint and test for prefix_r.
00168                     if ( str::hasPrefix( (mit->dir+"/"), entry.path ) )
00169                     {
00170                       skip = false;
00171                       break;
00172                     }
00173                   }
00174                 }
00175                 // try next entry
00176                 if ( skip )
00177                   continue;
00178 
00179                 _data->diskusage.add(entry);
00180               }
00181               else
00182               {
00183                 ZYPP_THROW( error( tag_r, "Expected du-entry [path num num num num]") );
00184               }
00185             }
00186           }
00187 
00188         public:
00189           DefaultIntegral<unsigned,0> _c_pkg;
00190           DefaultIntegral<unsigned,0> _c_srcpkg;
00191 
00192         private:
00193           data::Packagebase_Ptr   _data;
00194           data::Package_Ptr       _pkgData;
00195           data::SrcPackage_Ptr    _srcpkgData;
00196           DiskUsageCounter::MountPointSet _mounts;
00197       };
00199 
00201       //
00202       //        CLASS NAME : PackagesDuFileReader
00203       //
00205 
00207       //
00208       //        METHOD NAME : PackagesDuFileReader::PackagesDuFileReader
00209       //        METHOD TYPE : Ctor
00210       //
00211       PackagesDuFileReader::PackagesDuFileReader()
00212       {}
00213 
00215       //
00216       //        METHOD NAME : PackagesDuFileReader::~PackagesDuFileReader
00217       //        METHOD TYPE : Dtor
00218       //
00219       PackagesDuFileReader::~PackagesDuFileReader()
00220       {}
00221 
00223       //
00224       //        METHOD NAME : PackagesDuFileReader::beginParse
00225       //        METHOD TYPE : void
00226       //
00227       void PackagesDuFileReader::beginParse()
00228       {
00229         _pimpl.reset( new Impl(*this) );
00230       }
00231 
00233       //
00234       //        METHOD NAME : PackagesDuFileReader::consume
00235       //        METHOD TYPE : void
00236       //
00237       void PackagesDuFileReader::consume( const SingleTagPtr & tag_r )
00238       {
00239 #define TAGN(V)   tag_r->name == #V
00240 #define TAGFWD(V) ( TAGN(V) ) _pimpl->consume##V( tag_r )
00241 
00242         if ( TAGN( Pkg ) )
00243         {
00244           // consume old data
00245           if ( _pimpl->hasPackage() )
00246           {
00247             if ( _pkgConsumer )
00248               _pkgConsumer( _pimpl->handoutPackage() );
00249           }
00250           else if ( _pimpl->hasSourcepackage() )
00251           {
00252             if ( _srcPkgConsumer )
00253               _srcPkgConsumer( _pimpl->handoutSourcepackage() );
00254           }
00255           // start new data
00256           _pimpl->consumePkg( tag_r );
00257         }
00258         else if TAGFWD( Ver );
00259         else
00260         { WAR << errPrefix( tag_r, "Unknown tag" ) << endl; }
00261       }
00262 
00264       //
00265       //        METHOD NAME : PackagesDuFileReader::consume
00266       //        METHOD TYPE : void
00267       //
00268       void PackagesDuFileReader::consume( const MultiTagPtr & tag_r )
00269       {
00270         if TAGFWD( Dir );
00271         else
00272         { WAR << errPrefix( tag_r, "Unknown tag" ) << endl; }
00273       }
00274 
00276       //
00277       //        METHOD NAME : PackagesDuFileReader::lastData
00278       //        METHOD TYPE : void
00279       //
00280       void PackagesDuFileReader::endParse()
00281       {
00282         // consume oldData
00283         if ( _pimpl->hasPackage() )
00284         {
00285           if ( _pkgConsumer )
00286             _pkgConsumer( _pimpl->handoutPackage() );
00287         }
00288         else if ( _pimpl->hasSourcepackage() )
00289         {
00290           if ( _srcPkgConsumer )
00291             _srcPkgConsumer( _pimpl->handoutSourcepackage() );
00292         }
00293         MIL << "[PackagesDu]" << "(" << _pimpl->_c_pkg << "|" << _pimpl->_c_srcpkg << ")" << endl;
00294         _pimpl.reset();
00295       }
00296 
00298     } // namespace susetags
00301   } // namespace parser
00304 } // namespace zypp

Generated on Tue Sep 25 19:23:03 2007 for libzypp by  doxygen 1.5.3