libzypp 9.41.1

ServiceFileReader.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include "zypp/base/Logger.h"
00014 #include "zypp/base/String.h"
00015 #include "zypp/base/Regex.h"
00016 #include "zypp/base/InputStream.h"
00017 #include "zypp/base/UserRequestException.h"
00018 
00019 #include "zypp/parser/IniDict.h"
00020 #include "zypp/parser/ServiceFileReader.h"
00021 #include "zypp/ServiceInfo.h"
00022 
00023 using std::endl;
00024 using zypp::parser::IniDict;
00025 
00027 namespace zypp
00028 { 
00029 
00030   namespace parser
00031   { 
00032 
00033     class ServiceFileReader::Impl
00034     {
00035     public:
00036       static void parseServices( const Pathname & file,
00037           const ServiceFileReader::ProcessService & callback );
00038     };
00039 
00040     void ServiceFileReader::Impl::parseServices( const Pathname & file,
00041                                   const ServiceFileReader::ProcessService & callback/*,
00042                                   const ProgressData::ReceiverFnc &progress*/ )
00043     {
00044       InputStream is(file);
00045       if( is.stream().fail() )
00046       {
00047         ZYPP_THROW(Exception("Failed to open service file"));
00048       }
00049 
00050       parser::IniDict dict(is);
00051       for ( parser::IniDict::section_const_iterator its = dict.sectionsBegin();
00052             its != dict.sectionsEnd();
00053             ++its )
00054       {
00055         MIL << (*its) << endl;
00056 
00057         ServiceInfo service(*its);
00058         typedef std::map<std::string,std::pair<std::string,ServiceInfo::RepoState> > RepoStatesMap;
00059         RepoStatesMap repoStates;       // <repo_NUM,< alias,RepoState >>
00060 
00061         for ( IniDict::entry_const_iterator it = dict.entriesBegin(*its);
00062               it != dict.entriesEnd(*its);
00063               ++it )
00064         {
00065           // MIL << (*it).first << endl;
00066           if ( it->first == "name" )
00067             service.setName( it->second );
00068           else if ( it->first == "url" && ! it->second.empty() )
00069             service.setUrl( Url (it->second) );
00070           else if ( it->first == "enabled" )
00071             service.setEnabled( str::strToTrue( it->second ) );
00072           else if ( it->first == "autorefresh" )
00073             service.setAutorefresh( str::strToTrue( it->second ) );
00074           else if ( it->first == "type" )
00075             service.setType( repo::ServiceType(it->second) );
00076           else if ( it->first == "repostoenable" )
00077           {
00078             std::vector<std::string> aliases;
00079             str::splitEscaped( it->second, std::back_inserter(aliases) );
00080             for_( ait, aliases.begin(), aliases.end() )
00081             {
00082               service.addRepoToEnable( *ait );
00083             }
00084           }
00085           else if ( it->first == "repostodisable" )
00086           {
00087             std::vector<std::string> aliases;
00088             str::splitEscaped( it->second, std::back_inserter(aliases) );
00089             for_( ait, aliases.begin(), aliases.end() )
00090             {
00091               service.addRepoToDisable( *ait );
00092             }
00093           }
00094           else if ( str::startsWith( it->first, "repo_" ) )
00095           {
00096             static str::regex rxexpr( "([0-9]+)(_(.*))?" );
00097             str::smatch what;
00098             if ( str::regex_match( it->first.c_str()+5/*repo_*/, what, rxexpr ) )
00099             {
00100               std::string tag( what[1] );
00101               if (  what.size() > 3 )
00102               {
00103                 // attribute
00104                 if ( what[3] == "enabled" )
00105                   repoStates[tag].second.enabled = str::strToBool( it->second, repoStates[tag].second.enabled );
00106                 else if ( what[3] == "autorefresh" )
00107                   repoStates[tag].second.autorefresh = str::strToBool( it->second, repoStates[tag].second.autorefresh );
00108                 else if ( what[3] == "priority" )
00109                   str::strtonum( it->second, repoStates[tag].second.priority );
00110                 else
00111                   ERR << "Unknown attribute " << it->first << " ignored" << endl;
00112               }
00113               else
00114               {
00115                 // alias
00116                 repoStates[tag].first = it->second;
00117               }
00118             }
00119             else
00120               ERR << "Unknown attribute " << it->first << " ignored" << endl;
00121           }
00122           else
00123             ERR << "Unknown attribute " << it->first << " ignored" << endl;
00124         }
00125 
00126         if ( ! repoStates.empty() )
00127         {
00128           ServiceInfo::RepoStates data;
00129           for_( it, repoStates.begin(), repoStates.end() )
00130           {
00131             const RepoStatesMap::value_type & el( *it );
00132 
00133             if ( el.second.first.empty() )
00134               ERR << "Missing alias for repo_" << el.first << "; ignore entry" << endl;
00135             else
00136               data[el.second.first] = el.second.second;
00137           }
00138           if ( ! data.empty() )
00139             service.setRepoStates( data );
00140         }
00141 
00142         MIL << "Linking ServiceInfo with file " << file << endl;
00143         service.setFilepath(file);
00144 
00145         // add it to the list.
00146         if ( !callback(service) )
00147           ZYPP_THROW(AbortRequestException());
00148       }
00149     }
00150 
00152     //
00153     //  CLASS NAME : RepoFileReader
00154     //
00156 
00157     ServiceFileReader::ServiceFileReader( const Pathname & repo_file,
00158                                     const ProcessService & callback/*,
00159                                     const ProgressData::ReceiverFnc &progress */)
00160     {
00161       Impl::parseServices(repo_file, callback/*, progress*/);
00162       //MIL << "Done" << endl;
00163     }
00164 
00165     ServiceFileReader::~ServiceFileReader()
00166     {}
00167 
00168     std::ostream & operator<<( std::ostream & str, const ServiceFileReader & obj )
00169     {
00170       return str;
00171     }
00172 
00174   } // namespace parser
00177 } // namespace zypp