libzypp 8.13.6
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include "zypp/base/Logger.h" 00014 #include "zypp/base/Exception.h" 00015 #include "zypp/base/Functional.h" 00016 00017 #include "zypp/PathInfo.h" 00018 00019 #include "zypp/parser/ProductFileReader.h" 00020 #include "zypp/parser/xml/ParseDef.h" 00021 #include "zypp/parser/xml/ParseDefConsume.h" 00022 #include "zypp/parser/xml/Reader.h" 00023 00024 using std::endl; 00025 00027 namespace zypp 00028 { 00029 00030 namespace parser 00031 { 00032 00034 // 00035 // class ProductFileData::Upgrade 00036 // 00038 00039 struct ProductFileData::Upgrade::Impl 00040 { 00041 std::string _name; 00042 std::string _summary; 00043 std::string _repository; 00044 std::string _product; 00045 DefaultIntegral<bool,false> _notify; 00046 std::string _status; 00047 }; 00048 00049 ProductFileData::Upgrade::Upgrade( Impl * allocated_r ) 00050 : _pimpl( allocated_r ? allocated_r : new Impl ) 00051 {} 00052 00053 std::string ProductFileData::Upgrade::name() const { return _pimpl->_name; } 00054 std::string ProductFileData::Upgrade::summary() const { return _pimpl->_summary; } 00055 std::string ProductFileData::Upgrade::repository() const { return _pimpl->_repository; } 00056 std::string ProductFileData::Upgrade::product() const { return _pimpl->_product; } 00057 bool ProductFileData::Upgrade::notify() const { return _pimpl->_notify; } 00058 std::string ProductFileData::Upgrade::status() const { return _pimpl->_status; } 00059 00061 // 00062 // class ProductFileData 00063 // 00065 00066 struct ProductFileData::Impl 00067 { 00068 IdString _vendor; 00069 IdString _name; 00070 Edition _edition; 00071 Arch _arch; 00072 00073 std::string _shortName; 00074 std::string _summary; 00075 00076 std::string _productline; 00077 std::string _registerTarget; 00078 std::string _registerRelease; 00079 00080 std::string _updaterepokey; 00081 00082 Upgrades _upgrades; 00083 }; 00084 00085 ProductFileData::ProductFileData( Impl * allocated_r ) 00086 : _pimpl( allocated_r ? allocated_r : new Impl ) 00087 {} 00088 00089 IdString ProductFileData::vendor() const { return _pimpl->_vendor; } 00090 IdString ProductFileData::name() const { return _pimpl->_name; } 00091 Edition ProductFileData::edition() const { return _pimpl->_edition; } 00092 Arch ProductFileData::arch() const { return _pimpl->_arch; } 00093 00094 std::string ProductFileData::shortName() const { return _pimpl->_shortName; } 00095 std::string ProductFileData::summary() const { return _pimpl->_summary; } 00096 00097 std::string ProductFileData::productline() const { return _pimpl->_productline; } 00098 std::string ProductFileData::registerTarget() const { return _pimpl->_registerTarget; } 00099 std::string ProductFileData::registerRelease() const { return _pimpl->_registerRelease; } 00100 00101 std::string ProductFileData::updaterepokey() const { return _pimpl->_updaterepokey; } 00102 00103 const ProductFileData::Upgrades & ProductFileData::upgrades() const { return _pimpl->_upgrades; } 00104 00105 std::ostream & operator<<( std::ostream & str, const ProductFileData & obj ) 00106 { 00107 str << str::form( "|product|%s|%s|%s|%s|", 00108 obj.name().c_str(), 00109 obj.edition().c_str(), 00110 obj.arch().c_str(), 00111 obj.vendor().c_str() ); 00112 if ( ! obj.upgrades().empty() ) 00113 { 00114 for_( it, obj.upgrades().begin(), obj.upgrades().end() ) 00115 str << endl << " " << *it; 00116 } 00117 return str; 00118 } 00119 00120 std::ostream & operator<<( std::ostream & str, const ProductFileData::Upgrade & obj ) 00121 { 00122 str << str::form( "|upgrade|%s|%s|%s|%s|%s|", 00123 obj.name().c_str(), 00124 obj.repository().c_str(), 00125 obj.product().c_str(), 00126 obj.status().c_str(), 00127 (obj.notify() ? "notify" : "noNotify") ); 00128 return str; 00129 } 00131 // 00132 // class ProductFileReader 00133 // 00135 00136 struct ProductNode : public xml::ParseDef 00137 { 00138 ProductNode( ProductFileData::Impl & pdata_r ) 00139 : ParseDef( "product", MANDTAORY ) 00140 , _pdata( pdata_r ) 00141 { 00142 (*this) 00143 ("vendor", OPTIONAL, xml::parseDefAssign( _pdata._vendor ) ) 00144 ("name", MANDTAORY, xml::parseDefAssign( _pdata._name ) ) 00145 ("version", MANDTAORY, xml::parseDefAssign( _version ) ) 00146 ("release", MANDTAORY, xml::parseDefAssign( _release ) ) 00147 ("arch", MANDTAORY, xml::parseDefAssign( _pdata._arch ) ) 00148 ("shortsummary", OPTIONAL, xml::parseDefAssign( _pdata._shortName ) ) 00149 ("summary", MULTIPLE_OPTIONAL, xml::parseDefAssign( _ttext )( "lang", _tlocale ) 00150 >>bind( &ProductNode::doneLocalizedDefault, this, _1, ref(_pdata._summary) )) 00151 ("productline", OPTIONAL, xml::parseDefAssign( _pdata._productline ) ) 00152 ("register", OPTIONAL) 00153 ("updaterepokey", OPTIONAL, xml::parseDefAssign( _pdata._updaterepokey ) ) 00154 ("upgrades", OPTIONAL) 00155 ; 00156 00157 (*this)["register"] 00158 ("target", OPTIONAL, xml::parseDefAssign( _pdata._registerTarget ) ) 00159 ("release", OPTIONAL, xml::parseDefAssign( _pdata._registerRelease ) ) 00160 ; 00161 00162 (*this)["upgrades"] 00163 ("upgrade", MULTIPLE_OPTIONAL, xml::parseDefAssign() 00164 >> bind( &ProductNode::doneUpgrade, this, _1 )) 00165 ; 00166 00167 (*this)["upgrades"]["upgrade"] 00168 ("name", OPTIONAL, xml::parseDefAssign( _upgrade._name ) ) 00169 ("summary", OPTIONAL, xml::parseDefAssign( _upgrade._summary ) ) 00170 ("repository", OPTIONAL, xml::parseDefAssign( _upgrade._repository ) ) 00171 ("product", OPTIONAL, xml::parseDefAssign( _upgrade._product ) ) 00172 ("notify", OPTIONAL, xml::parseDefAssign( _upgrade._notify ) ) 00173 ("status", OPTIONAL, xml::parseDefAssign( _upgrade._status ) ) 00174 ; 00175 00176 // </product> callback to build edition. 00177 setConsumer( xml::parseDefAssign() >> bind( &ProductNode::done, this, _1 ) ); 00178 // xml::ParseDef::_debug = true; 00179 } 00180 00182 void doneUpgrade( const xml::Node & _node ) 00183 { 00184 ProductFileData::Upgrade cdata( new ProductFileData::Upgrade::Impl( _upgrade ) ); 00185 _pdata._upgrades.push_back( cdata ); 00186 _upgrade = ProductFileData::Upgrade::Impl(); 00187 } 00189 void doneLocalizedDefault( const xml::Node & _node, std::string & store_r ) 00190 { 00191 // take 1st or default 00192 if ( store_r.empty() || _tlocale.empty() ) 00193 store_r = _ttext; 00194 } 00195 00197 void done( const xml::Node & _node ) 00198 { 00199 _pdata._edition = Edition( _version, _release ); 00200 } 00201 00202 private: 00203 ProductFileData::Impl & _pdata; 00204 00205 std::string _version; 00206 std::string _release; 00207 00208 std::string _ttext; 00209 std::string _tlocale; 00210 00211 ProductFileData::Upgrade::Impl _upgrade; 00212 }; 00213 00214 bool ProductFileReader::parse( const InputStream & input_r ) const 00215 { 00216 MIL << "+++" << input_r << endl; 00217 bool ret = true; 00218 00219 ProductFileData::Impl * pdataImpl = 0; 00220 ProductFileData pdata( (pdataImpl = new ProductFileData::Impl) ); 00221 00222 try 00223 { 00224 xml::Reader reader( input_r ); 00225 ProductNode rootNode( *pdataImpl ); 00226 rootNode.take( reader ); 00227 00228 } 00229 catch ( const Exception & err ) 00230 { 00231 // parse error 00232 ERR << err << endl; 00233 ERR << "---" << ret << " - " << input_r << endl; 00234 return ret; 00235 } 00236 00237 if ( _consumer ) 00238 { 00239 ret = _consumer( pdata ); 00240 } 00241 00242 MIL << "---" << ret << " - " << input_r << endl; 00243 return ret; 00244 } 00245 00247 00248 bool ProductFileReader::scanDir( const Consumer & consumer_r, const Pathname & dir_r ) 00249 { 00250 std::list<Pathname> retlist; 00251 int res = filesystem::readdir( retlist, dir_r, /*dots*/false ); 00252 if ( res != 0 ) 00253 { 00254 WAR << "scanDir " << dir_r << " failed (" << res << ")" << endl; 00255 return true; 00256 } 00257 00258 ProductFileReader reader( consumer_r ); 00259 for_( it, retlist.begin(), retlist.end() ) 00260 { 00261 if ( PathInfo( *it, PathInfo::LSTAT ).isFile() && ! reader.parse( *it ) ) 00262 { 00263 return false; // consumer_r request to stop parsing. 00264 } 00265 } 00266 return true; 00267 } 00268 00269 ProductFileData ProductFileReader::scanFile( const Pathname & file_r ) 00270 { 00271 if ( ! PathInfo( file_r ).isFile() ) 00272 { 00273 WAR << "scanFile " << PathInfo( file_r ) << " is not a file." << endl; 00274 return ProductFileData(); 00275 } 00276 00277 ProductFileData ret; 00278 ProductFileReader reader( functor::getFirst( ret ), file_r ); 00279 return ret; 00280 } 00281 00283 } // namespace parser 00286 } // namespace zypp