Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / parser / ServiceFileReader.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/parser/RepoFileReader.cc
10  *
11 */
12 #include <iostream>
13 #include "zypp/base/Logger.h"
14 #include "zypp/base/String.h"
15 #include "zypp/base/Regex.h"
16 #include "zypp/base/InputStream.h"
17 #include "zypp/base/UserRequestException.h"
18
19 #include "zypp/parser/IniDict.h"
20 #include "zypp/parser/ServiceFileReader.h"
21 #include "zypp/ServiceInfo.h"
22
23 using std::endl;
24 using zypp::parser::IniDict;
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////
29   ///////////////////////////////////////////////////////////////////
30   namespace parser
31   { /////////////////////////////////////////////////////////////////
32
33     class ServiceFileReader::Impl
34     {
35     public:
36       static void parseServices( const Pathname & file,
37           const ServiceFileReader::ProcessService & callback );
38     };
39
40     void ServiceFileReader::Impl::parseServices( const Pathname & file,
41                                   const ServiceFileReader::ProcessService & callback/*,
42                                   const ProgressData::ReceiverFnc &progress*/ )
43     {
44       InputStream is(file);
45       if( is.stream().fail() )
46       {
47         ZYPP_THROW(Exception("Failed to open service file"));
48       }
49
50       parser::IniDict dict(is);
51       for ( parser::IniDict::section_const_iterator its = dict.sectionsBegin();
52             its != dict.sectionsEnd();
53             ++its )
54       {
55         MIL << (*its) << endl;
56
57         ServiceInfo service(*its);
58         std::map<std::string,std::pair<std::string,ServiceInfo::RepoState>> repoStates; // <repo_NUM,< alias,RepoState >>
59
60         for ( IniDict::entry_const_iterator it = dict.entriesBegin(*its);
61               it != dict.entriesEnd(*its);
62               ++it )
63         {
64           // MIL << (*it).first << endl;
65           if ( it->first == "name" )
66             service.setName( it->second );
67           else if ( it->first == "url" && ! it->second.empty() )
68             service.setUrl( Url (it->second) );
69           else if ( it->first == "enabled" )
70             service.setEnabled( str::strToTrue( it->second ) );
71           else if ( it->first == "autorefresh" )
72             service.setAutorefresh( str::strToTrue( it->second ) );
73           else if ( it->first == "type" )
74             service.setType( repo::ServiceType(it->second) );
75           else if ( it->first == "repostoenable" )
76           {
77             std::vector<std::string> aliases;
78             str::splitEscaped( it->second, std::back_inserter(aliases) );
79             for_( ait, aliases.begin(), aliases.end() )
80             {
81               service.addRepoToEnable( *ait );
82             }
83           }
84           else if ( it->first == "repostodisable" )
85           {
86             std::vector<std::string> aliases;
87             str::splitEscaped( it->second, std::back_inserter(aliases) );
88             for_( ait, aliases.begin(), aliases.end() )
89             {
90               service.addRepoToDisable( *ait );
91             }
92           }
93           else if ( str::startsWith( it->first, "repo_" ) )
94           {
95             static str::regex rxexpr( "([0-9]+)(_(.*))?" );
96             str::smatch what;
97             if ( str::regex_match( it->first.c_str()+5/*repo_*/, what, rxexpr ) )
98             {
99               std::string tag( what[1] );
100               if (  what.size() > 3 )
101               {
102                 // attribute
103                 if ( what[3] == "enabled" )
104                   repoStates[tag].second.enabled = str::strToBool( it->second, repoStates[tag].second.enabled );
105                 else if ( what[3] == "autorefresh" )
106                   repoStates[tag].second.autorefresh = str::strToBool( it->second, repoStates[tag].second.autorefresh );
107                 else if ( what[3] == "priority" )
108                   str::strtonum( it->second, repoStates[tag].second.priority );
109                 else
110                   ERR << "Unknown attribute " << it->first << " ignored" << endl;
111               }
112               else
113               {
114                 // alias
115                 repoStates[tag].first = it->second;
116               }
117             }
118             else
119               ERR << "Unknown attribute " << it->first << " ignored" << endl;
120           }
121           else
122             ERR << "Unknown attribute " << it->first << " ignored" << endl;
123         }
124
125         if ( ! repoStates.empty() )
126         {
127           ServiceInfo::RepoStates data;
128           for ( const auto & el : repoStates )
129           {
130             if ( el.second.first.empty() )
131               ERR << "Missing alias for repo_" << el.first << "; ignore entry" << endl;
132             else
133               data[el.second.first] = el.second.second;
134           }
135           if ( ! data.empty() )
136             service.setRepoStates( std::move(data) );
137         }
138
139         MIL << "Linking ServiceInfo with file " << file << endl;
140         service.setFilepath(file);
141
142         // add it to the list.
143         if ( !callback(service) )
144           ZYPP_THROW(AbortRequestException());
145       }
146     }
147
148     ///////////////////////////////////////////////////////////////////
149     //
150     //  CLASS NAME : RepoFileReader
151     //
152     ///////////////////////////////////////////////////////////////////
153
154     ServiceFileReader::ServiceFileReader( const Pathname & repo_file,
155                                     const ProcessService & callback/*,
156                                     const ProgressData::ReceiverFnc &progress */)
157     {
158       Impl::parseServices(repo_file, callback/*, progress*/);
159       //MIL << "Done" << endl;
160     }
161
162     ServiceFileReader::~ServiceFileReader()
163     {}
164
165     std::ostream & operator<<( std::ostream & str, const ServiceFileReader & obj )
166     {
167       return str;
168     }
169
170     /////////////////////////////////////////////////////////////////
171   } // namespace parser
172   ///////////////////////////////////////////////////////////////////
173   /////////////////////////////////////////////////////////////////
174 } // namespace zypp
175 ///////////////////////////////////////////////////////////////////