libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include "zypp/base/Logger.h" 00014 00015 #include "zypp/SysContent.h" 00016 #include "zypp/parser/xml/Reader.h" 00017 #include "zypp/parser/xml/ParseDef.h" 00018 #include "zypp/parser/xml/ParseDefConsume.h" 00019 00020 using std::endl; 00021 00023 namespace zypp 00024 { 00025 00026 namespace syscontent 00027 { 00028 00030 namespace // Writer helpers 00031 { 00032 00037 inline std::string attrIf( const std::string & tag_r, 00038 const std::string & value_r ) 00039 { 00040 std::string ret; 00041 if ( ! value_r.empty() ) 00042 { 00043 ret += " "; 00044 ret += tag_r; 00045 ret += "=\""; 00046 ret += value_r; 00047 ret += "\""; 00048 } 00049 return ret; 00050 } 00051 00053 } // namespace 00055 00057 // 00058 // CLASS NAME : Writer::Impl 00059 // 00061 class Writer::Impl 00062 { 00063 public: 00064 std::ostream & writeXml( std::ostream & str ) const; 00065 00066 public: 00067 std::string _name; 00068 Edition _edition; 00069 std::string _description; 00070 StorageT _onsys; 00071 00072 public: 00074 static shared_ptr<Impl> nullimpl() 00075 { 00076 static shared_ptr<Impl> _nullimpl( new Impl ); 00077 return _nullimpl; 00078 } 00079 00080 private: 00081 friend Impl * rwcowClone<Impl>( const Impl * rhs ); 00083 Impl * clone() const 00084 { return new Impl( *this ); } 00085 }; 00087 00089 // 00090 // METHOD NAME : Writer::Impl::writeXml 00091 // METHOD TYPE : std::ostream & 00092 // 00093 std::ostream & Writer::Impl::writeXml( std::ostream & str ) const 00094 { 00095 // intro 00096 str << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 00097 str << "<syscontent>\n"; 00098 // ident data 00099 str << " <ident>\n"; 00100 str << " <name>" << _name << "</name>\n"; 00101 str << " <version" 00102 << attrIf( "epoch", str::numstring(_edition.epoch()) ) 00103 << attrIf( "ver", _edition.version() ) 00104 << attrIf( "rel", _edition.release() ) 00105 << "/>\n"; 00106 str << " <description>" << _description << "</description>\n"; 00107 str << " <created>" << Date::now().asSeconds() << "</created>\n"; 00108 str << " </ident>\n"; 00109 // ResObjects 00110 str << " <onsys>\n"; 00111 for ( iterator it = _onsys.begin(); it != _onsys.end(); ++it ) 00112 { 00113 str << " <entry" 00114 << attrIf( "kind", (*it)->kind().asString() ) 00115 << attrIf( "name", (*it)->name() ) 00116 << attrIf( "epoch", str::numstring((*it)->edition().epoch()) ) 00117 << attrIf( "ver", (*it)->edition().version() ) 00118 << attrIf( "rel", (*it)->edition().release() ) 00119 << attrIf( "arch", (*it)->arch().asString() ) 00120 << "/>\n"; 00121 } 00122 str << " </onsys>\n"; 00123 // extro 00124 str << "</syscontent>" << endl; 00125 return str; 00126 }; 00127 00129 // 00130 // CLASS NAME : Writer 00131 // 00133 00134 Writer::Writer() 00135 : _pimpl( Impl::nullimpl() ) 00136 {} 00137 00138 const std::string & Writer::name() const 00139 { return _pimpl->_name; } 00140 00141 Writer & Writer::name( const std::string & val_r ) 00142 { _pimpl->_name = val_r; return *this; } 00143 00144 const Edition & Writer::edition() const 00145 { return _pimpl->_edition; } 00146 00147 Writer & Writer::edition( const Edition & val_r ) 00148 { _pimpl->_edition = val_r; return *this; } 00149 00150 const std::string & Writer::description() const 00151 { return _pimpl->_description; } 00152 00153 Writer & Writer::description( const std::string & val_r ) 00154 { _pimpl->_description = val_r; return *this; } 00155 00156 void Writer::addInstalled( const PoolItem & obj_r ) 00157 { 00158 if ( obj_r.status().isInstalled() ) 00159 { 00160 _pimpl->_onsys.insert( obj_r.resolvable() ); 00161 } 00162 } 00163 00164 void Writer::addIf( const PoolItem & obj_r ) 00165 { 00166 if ( obj_r.status().isInstalled() != obj_r.status().transacts() 00167 && ! ( obj_r.status().transacts() && obj_r.status().isBySolver() ) ) 00168 { 00169 _pimpl->_onsys.insert( obj_r.resolvable() ); 00170 } 00171 } 00172 00173 void Writer::add( const ResObject::constPtr & obj_r ) 00174 { _pimpl->_onsys.insert( obj_r ); } 00175 00176 bool Writer::empty() const 00177 { return _pimpl->_onsys.empty(); } 00178 00179 Writer::size_type Writer::size() const 00180 { return _pimpl->_onsys.size(); } 00181 00182 Writer::const_iterator Writer::begin() const 00183 { return _pimpl->_onsys.begin(); } 00184 00185 Writer::const_iterator Writer::end() const 00186 { return _pimpl->_onsys.end(); } 00187 00188 std::ostream & Writer::writeXml( std::ostream & str ) const 00189 { return _pimpl->writeXml( str ); } 00190 00192 // 00193 // CLASS NAME : Reader::Entry::Impl 00194 // 00195 class Reader::Entry::Impl 00196 { 00197 public: 00198 std::string _kind; 00199 std::string _name; 00200 Edition _edition; 00201 Arch _arch; 00202 }; 00204 00206 // 00207 // CLASS NAME : Reader::Entry 00208 // 00210 00211 Reader::Entry::Entry() 00212 : _pimpl( new Impl ) 00213 {} 00214 00215 Reader::Entry::Entry( const shared_ptr<Impl> & pimpl_r ) 00216 : _pimpl( pimpl_r ) 00217 {} 00218 00219 const std::string & Reader::Entry::kind() const 00220 { return _pimpl->_kind; } 00221 00222 const std::string & Reader::Entry::name() const 00223 { return _pimpl->_name; } 00224 00225 const Edition & Reader::Entry::edition() const 00226 { return _pimpl->_edition; } 00227 00228 const Arch & Reader::Entry::arch() const 00229 { return _pimpl->_arch; } 00230 00232 // 00233 // CLASS NAME : Reader::Impl 00234 // 00236 class Reader::Impl 00237 { 00238 public: 00239 Impl() 00240 {} 00241 00242 Impl( std::istream & input_r ); 00243 00244 public: 00245 std::string _name; 00246 Edition _edition; 00247 std::string _description; 00248 Date _created; 00249 00250 std::list<Entry> _content; 00251 00252 public: 00254 static shared_ptr<Impl> nullimpl() 00255 { 00256 static shared_ptr<Impl> _nullimpl( new Impl ); 00257 return _nullimpl; 00258 } 00259 00260 private: 00261 friend Impl * rwcowClone<Impl>( const Impl * rhs ); 00263 Impl * clone() const 00264 { return new Impl( *this ); } 00265 }; 00267 00269 namespace // Reader helpers 00270 { 00271 00272 using namespace xml; 00273 00275 struct SycontentNode : public ParseDef 00276 { 00277 SycontentNode( Mode mode_r ) 00278 : ParseDef( "syscontent", mode_r ) 00279 { 00280 (*this)("ident", OPTIONAL) 00281 ("onsys", OPTIONAL) 00282 ; 00283 00284 (*this)["ident"] 00285 ("name", OPTIONAL) 00286 ("version", OPTIONAL) 00287 ("description", OPTIONAL) 00288 ("created", OPTIONAL) 00289 ; 00290 00291 (*this)["onsys"] 00292 ("entry", MULTIPLE_OPTIONAL) 00293 ; 00294 } 00295 }; 00296 00298 struct ConsumeEdition : public ParseDefConsume 00299 { 00300 ConsumeEdition( Edition & value_r ) 00301 : _value( & value_r ) 00302 {} 00303 00304 virtual void start( const Node & node_r ) 00305 { 00306 *_value = Edition( node_r.getAttribute("ver").asString(), 00307 node_r.getAttribute("rel").asString(), 00308 node_r.getAttribute("epoch").asString() ); 00309 } 00310 00311 Edition *_value; 00312 }; 00313 00315 struct ConsumeString : public ParseDefConsume 00316 { 00317 ConsumeString( std::string & value_r ) 00318 : _value( & value_r ) 00319 {} 00320 00321 virtual void text( const Node & node_r ) 00322 { 00323 *_value = node_r.value().asString(); 00324 } 00325 00326 std::string *_value; 00327 }; 00328 00330 struct ConsumeDate : public ParseDefConsume 00331 { 00332 ConsumeDate( Date & value_r ) 00333 : _value( & value_r ) 00334 {} 00335 00336 virtual void text( const Node & node_r ) 00337 { 00338 *_value = node_r.value().asString(); 00339 } 00340 00341 Date *_value; 00342 }; 00343 00345 struct ConsumeEntries : public ParseDefConsume 00346 { 00347 ConsumeEntries( std::list<Reader::Entry> & value_r ) 00348 : _value( & value_r ) 00349 {} 00350 00351 virtual void start( const Node & node_r ) 00352 { 00353 shared_ptr<Reader::Entry::Impl> centry( new Reader::Entry::Impl ); 00354 00355 centry->_kind = node_r.getAttribute("kind").asString(); 00356 centry->_name = node_r.getAttribute("name").asString(); 00357 centry->_edition = Edition( node_r.getAttribute("ver").asString(), 00358 node_r.getAttribute("rel").asString(), 00359 node_r.getAttribute("epoch").asString() ); 00360 centry->_arch = Arch( node_r.getAttribute("arch").asString() ); 00361 00362 _value->push_back( Reader::Entry( centry ) ); 00363 } 00364 00365 std::list<Reader::Entry> *_value; 00366 }; 00367 00369 } // namespace 00371 00373 // 00374 // METHOD NAME : Reader::Impl::Impl 00375 // METHOD TYPE : Constructor 00376 // 00377 Reader::Impl::Impl( std::istream & input_r ) 00378 { 00379 xml::Reader reader( input_r ); 00380 SycontentNode rootNode( xml::ParseDef::MANDTAORY ); 00381 00382 rootNode["ident"]["name"].setConsumer 00383 ( new ConsumeString( _name ) ); 00384 00385 rootNode["ident"]["version"].setConsumer 00386 ( new ConsumeEdition( _edition ) ); 00387 00388 rootNode["ident"]["description"].setConsumer 00389 ( new ConsumeString( _description ) ); 00390 00391 rootNode["ident"]["created"].setConsumer 00392 ( new ConsumeDate( _created ) ); 00393 00394 rootNode["onsys"]["entry"].setConsumer 00395 ( new ConsumeEntries( _content ) ); 00396 00397 // parse 00398 rootNode.take( reader ); 00399 } 00400 00402 // 00403 // CLASS NAME : Reader 00404 // 00406 00407 Reader::Reader() 00408 : _pimpl( Impl::nullimpl() ) 00409 {} 00410 00411 Reader::Reader( std::istream & input_r ) 00412 : _pimpl( new Impl( input_r ) ) 00413 {} 00414 00415 const std::string & Reader::name() const 00416 { return _pimpl->_name; } 00417 00418 const Edition & Reader::edition() const 00419 { return _pimpl->_edition; } 00420 00421 const std::string & Reader::description() const 00422 { return _pimpl->_description; } 00423 00424 const Date & Reader::ctime() const 00425 { return _pimpl->_created; } 00426 00427 bool Reader::empty() const 00428 { return _pimpl->_content.empty(); } 00429 00430 Reader::size_type Reader::size() const 00431 { return _pimpl->_content.size(); } 00432 00433 Reader::const_iterator Reader::begin() const 00434 { return _pimpl->_content.begin(); } 00435 00436 Reader::const_iterator Reader::end() const 00437 { return _pimpl->_content.end(); } 00438 00439 /****************************************************************** 00440 ** 00441 ** FUNCTION NAME : operator<< 00442 ** FUNCTION TYPE : inline std::ostream & 00443 */ 00444 std::ostream & operator<<( std::ostream & str, const Reader & obj ) 00445 { 00446 return str << "syscontent(" << obj.name() << "-" << obj.edition() 00447 << ", " << obj.size() << " entries" 00448 << ", created " << obj.ctime() 00449 << ")"; 00450 } 00451 00453 } // namespace syscontent 00456 } // namespace zypp