libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include <sstream> 00014 00015 #include "zypp/base/LogTools.h" 00016 #include "zypp/base/String.h" 00017 #include "zypp/base/IOStream.h" 00018 #include "zypp/base/UserRequestException.h" 00019 #include "zypp/parser/ParseException.h" 00020 00021 #include "zypp/parser/susetags/ContentFileReader.h" 00022 #include "zypp/parser/susetags/RepoIndex.h" 00023 00024 using std::endl; 00025 #undef ZYPP_BASE_LOGGER_LOGGROUP 00026 #define ZYPP_BASE_LOGGER_LOGGROUP "parser::susetags" 00027 00029 namespace zypp 00030 { 00031 00032 namespace parser 00033 { 00034 00035 namespace susetags 00036 { 00037 00039 // 00040 // CLASS NAME : ContentFileReader::Impl 00041 // 00043 struct ContentFileReader::Impl 00044 { 00045 public: 00046 Impl( const ContentFileReader & parent_r ) 00047 : _parent( parent_r ) 00048 {} 00049 00050 RepoIndex & repoindex() 00051 { 00052 if ( !_repoindex ) 00053 _repoindex = new RepoIndex; 00054 return *_repoindex; 00055 } 00056 00057 bool hasRepoIndex() const 00058 { return _repoindex; } 00059 00060 RepoIndex_Ptr handoutRepoIndex() 00061 { 00062 RepoIndex_Ptr ret; 00063 ret.swap( _repoindex ); 00064 _repoindex = 0; 00065 return ret; 00066 } 00067 00068 public: 00069 bool setFileCheckSum( std::map<std::string, CheckSum> & map_r, const std::string & value ) const 00070 { 00071 bool error = false; 00072 std::vector<std::string> words; 00073 if ( str::split( value, std::back_inserter( words ) ) == 3 ) 00074 { 00075 map_r[words[2]] = CheckSum( words[0], words[1] ); 00076 } 00077 else 00078 { 00079 error = true; 00080 } 00081 return error; 00082 } 00083 00084 public: 00085 std::string _inputname; 00086 00087 private: 00088 const ContentFileReader & _parent; 00089 RepoIndex_Ptr _repoindex; 00090 }; 00092 00094 // 00095 // CLASS NAME : ContentFileReader 00096 // 00098 00100 // 00101 // METHOD NAME : ContentFileReader::ContentFileReader 00102 // METHOD TYPE : Ctor 00103 // 00104 ContentFileReader::ContentFileReader() 00105 {} 00106 00108 // 00109 // METHOD NAME : ContentFileReader::~ContentFileReader 00110 // METHOD TYPE : Dtor 00111 // 00112 ContentFileReader::~ContentFileReader() 00113 {} 00114 00116 // 00117 // METHOD NAME : ContentFileReader::beginParse 00118 // METHOD TYPE : void 00119 // 00120 void ContentFileReader::beginParse() 00121 { 00122 _pimpl.reset( new Impl(*this) ); 00123 // actually mandatory, but in case they were forgotten... 00124 _pimpl->repoindex().descrdir = "suse/setup/descr"; 00125 _pimpl->repoindex().datadir = "suse"; 00126 } 00127 00129 // 00130 // METHOD NAME : ContentFileReader::endParse 00131 // METHOD TYPE : void 00132 // 00133 void ContentFileReader::endParse() 00134 { 00135 // consume oldData 00136 if ( _pimpl->hasRepoIndex() ) 00137 { 00138 if ( _repoIndexConsumer ) 00139 _repoIndexConsumer( _pimpl->handoutRepoIndex() ); 00140 } 00141 00142 MIL << "[Content]" << endl; 00143 _pimpl.reset(); 00144 } 00145 00147 // 00148 // METHOD NAME : ContentFileReader::userRequestedAbort 00149 // METHOD TYPE : void 00150 // 00151 void ContentFileReader::userRequestedAbort( unsigned lineNo_r ) 00152 { 00153 ZYPP_THROW( AbortRequestException( errPrefix( lineNo_r ) ) ); 00154 } 00155 00157 // 00158 // METHOD NAME : ContentFileReader::errPrefix 00159 // METHOD TYPE : std::string 00160 // 00161 std::string ContentFileReader::errPrefix( unsigned lineNo_r, 00162 const std::string & msg_r, 00163 const std::string & line_r ) const 00164 { 00165 return str::form( "%s:%u:%s | %s", 00166 _pimpl->_inputname.c_str(), 00167 lineNo_r, 00168 line_r.c_str(), 00169 msg_r.c_str() ); 00170 } 00171 00173 // 00174 // METHOD NAME : ContentFileReader::parse 00175 // METHOD TYPE : void 00176 // 00177 void ContentFileReader::parse( const InputStream & input_r, 00178 const ProgressData::ReceiverFnc & fnc_r ) 00179 { 00180 MIL << "Start parsing content repoindex" << input_r << endl; 00181 if ( ! input_r.stream() ) 00182 { 00183 std::ostringstream s; 00184 s << "Can't read bad stream: " << input_r; 00185 ZYPP_THROW( ParseException( s.str() ) ); 00186 } 00187 beginParse(); 00188 _pimpl->_inputname = input_r.name(); 00189 00190 ProgressData ticks( makeProgressData( input_r ) ); 00191 ticks.sendTo( fnc_r ); 00192 if ( ! ticks.toMin() ) 00193 userRequestedAbort( 0 ); 00194 00195 iostr::EachLine line( input_r ); 00196 for( ; line; line.next() ) 00197 { 00198 // strip 1st word from line to separate tag and value. 00199 std::string value( *line ); 00200 std::string key( str::stripFirstWord( value, /*ltrim_first*/true ) ); 00201 00202 if ( key.empty() || *key.c_str() == '#' ) // empty or comment line 00203 { 00204 continue; 00205 } 00206 00207 // strip modifier if exists 00208 std::string modifier; 00209 std::string::size_type pos = key.rfind( '.' ); 00210 if ( pos != std::string::npos ) 00211 { 00212 modifier = key.substr( pos+1 ); 00213 key.erase( pos ); 00214 } 00215 00216 // 00217 // ReppoIndex related data: 00218 // 00219 else if ( key == "DESCRDIR" ) 00220 { 00221 _pimpl->repoindex().descrdir = value; 00222 } 00223 else if ( key == "DATADIR" ) 00224 { 00225 _pimpl->repoindex().datadir = value; 00226 } 00227 else if ( key == "KEY" ) 00228 { 00229 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().signingKeys, value ) ) 00230 { 00231 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [KEY algorithm checksum filename]", *line ) ) ); 00232 } 00233 } 00234 else if ( key == "META" ) 00235 { 00236 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().metaFileChecksums, value ) ) 00237 { 00238 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) ); 00239 } 00240 } 00241 else if ( key == "HASH" ) 00242 { 00243 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().mediaFileChecksums, value ) ) 00244 { 00245 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) ); 00246 } 00247 } 00248 else 00249 { 00250 DBG << errPrefix( line.lineNo(), "ignored", *line ) << endl; 00251 } 00252 00253 00254 if ( ! ticks.set( input_r.stream().tellg() ) ) 00255 userRequestedAbort( line.lineNo() ); 00256 } 00257 00258 // 00259 // post processing 00260 // 00261 if ( ! ticks.toMax() ) 00262 userRequestedAbort( line.lineNo() ); 00263 00264 endParse(); 00265 MIL << "Done parsing " << input_r << endl; 00266 } 00267 00269 } // namespace susetags 00272 } // namespace parser 00275 } // namespace zypp