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 00018 #include "zypp/sat/detail/PoolImpl.h" 00019 00020 #include "zypp/sat/Pool.h" 00021 #include "zypp/sat/LookupAttr.h" 00022 #include "zypp/sat/AttrMatcher.h" 00023 00024 #include "zypp/CheckSum.h" 00025 00026 using std::endl; 00027 00029 namespace zypp 00030 { 00031 00032 namespace sat 00033 { 00034 00035 using detail::noSolvableId; 00036 00038 // 00039 // CLASS NAME : LookupAttr::Impl 00040 // 00042 00055 class LookupAttr::Impl 00056 { 00057 public: 00058 Impl() 00059 : _parent( SolvAttr::noAttr ) 00060 {} 00061 Impl( SolvAttr attr_r, Location loc_r ) 00062 : _attr( attr_r ), _parent( attr_r.parent() ), _solv( loc_r == REPO_ATTR ? SOLVID_META : noSolvableId ) 00063 {} 00064 Impl( SolvAttr attr_r, Repository repo_r, Location loc_r ) 00065 : _attr( attr_r ), _parent( attr_r.parent() ), _repo( repo_r ), _solv( loc_r == REPO_ATTR ? SOLVID_META : noSolvableId ) 00066 {} 00067 Impl( SolvAttr attr_r, Solvable solv_r ) 00068 : _attr( attr_r ), _parent( attr_r.parent() ), _solv( solv_r ) 00069 {} 00070 00071 public: 00072 SolvAttr attr() const 00073 { return _attr; } 00074 00075 void setAttr( SolvAttr attr_r ) 00076 { 00077 _attr = attr_r; 00078 SolvAttr p( _attr.parent() ); 00079 if ( p != SolvAttr::noAttr ) 00080 _parent = p; 00081 } 00082 00083 const AttrMatcher & attrMatcher() const 00084 { return _attrMatcher; } 00085 00086 void setAttrMatcher( const AttrMatcher & matcher_r ) 00087 { 00088 matcher_r.compile(); 00089 _attrMatcher = matcher_r; 00090 } 00091 00092 public: 00093 bool pool() const 00094 { return ! (_repo || _solv); } 00095 00096 void setPool( Location loc_r ) 00097 { 00098 _repo = Repository::noRepository; 00099 _solv = Solvable( loc_r == REPO_ATTR ? SOLVID_META : noSolvableId ); 00100 } 00101 00102 Repository repo() const 00103 { return _repo; } 00104 00105 void setRepo( Repository repo_r, Location loc_r ) 00106 { 00107 _repo = repo_r; 00108 _solv = Solvable( loc_r == REPO_ATTR ? SOLVID_META : noSolvableId ); 00109 } 00110 00111 Solvable solvable() const 00112 { return _solv; } 00113 00114 void setSolvable( Solvable solv_r ) 00115 { 00116 _repo = Repository::noRepository; 00117 _solv = solv_r; 00118 } 00119 00120 SolvAttr parent() const 00121 { return _parent; } 00122 00123 void setParent( SolvAttr attr_r ) 00124 { _parent = attr_r; } 00125 00126 public: 00127 LookupAttr::iterator begin() const 00128 { 00129 if ( _attr == SolvAttr::noAttr || sat::Pool::instance().reposEmpty() ) 00130 return end(); 00131 00132 detail::RepoIdType whichRepo = detail::noRepoId; // all repos 00133 if ( _solv ) 00134 whichRepo = _solv.repository().id(); 00135 else if ( _repo ) 00136 whichRepo = _repo.id(); 00137 00138 detail::DIWrap dip( whichRepo, _solv.id(), _attr.id(), _attrMatcher.searchstring(), _attrMatcher.flags().get() ); 00139 if ( _parent != SolvAttr::noAttr ) 00140 ::dataiterator_prepend_keyname( dip.get(), _parent.id() ); 00141 00142 return iterator( dip ); // iterator takes over ownership! 00143 } 00144 00145 LookupAttr::iterator end() const 00146 { return iterator(); } 00147 00148 private: 00149 SolvAttr _attr; 00150 SolvAttr _parent; 00151 Repository _repo; 00152 Solvable _solv; 00153 AttrMatcher _attrMatcher; 00154 00155 private: 00156 friend Impl * rwcowClone<Impl>( const Impl * rhs ); 00158 Impl * clone() const 00159 { return new Impl( *this ); } 00160 }; 00161 00163 // 00164 // CLASS NAME : LookupAttr 00165 // 00167 00168 LookupAttr::LookupAttr() 00169 : _pimpl( new Impl ) 00170 {} 00171 00172 LookupAttr::LookupAttr( SolvAttr attr_r, Location loc_r ) 00173 : _pimpl( new Impl( attr_r, loc_r ) ) 00174 {} 00175 LookupAttr::LookupAttr( SolvAttr attr_r, SolvAttr parent_r, Location loc_r ) 00176 : _pimpl( new Impl( attr_r, loc_r ) ) 00177 { _pimpl->setParent( parent_r ); } 00178 00179 LookupAttr::LookupAttr( SolvAttr attr_r, Repository repo_r, Location loc_r ) 00180 : _pimpl( new Impl( attr_r, repo_r, loc_r ) ) 00181 {} 00182 LookupAttr::LookupAttr( SolvAttr attr_r, SolvAttr parent_r, Repository repo_r, Location loc_r ) 00183 : _pimpl( new Impl( attr_r, repo_r, loc_r ) ) 00184 { _pimpl->setParent( parent_r ); } 00185 00186 LookupAttr::LookupAttr( SolvAttr attr_r, Solvable solv_r ) 00187 : _pimpl( new Impl( attr_r, solv_r ) ) 00188 {} 00189 LookupAttr::LookupAttr( SolvAttr attr_r, SolvAttr parent_r, Solvable solv_r ) 00190 : _pimpl( new Impl( attr_r, solv_r ) ) 00191 { _pimpl->setParent( parent_r ); } 00192 00193 00195 00196 SolvAttr LookupAttr::attr() const 00197 { return _pimpl->attr(); } 00198 00199 void LookupAttr::setAttr( SolvAttr attr_r ) 00200 { _pimpl->setAttr( attr_r ); } 00201 00202 const AttrMatcher & LookupAttr::attrMatcher() const 00203 { return _pimpl->attrMatcher(); } 00204 00205 void LookupAttr::setAttrMatcher( const AttrMatcher & matcher_r ) 00206 { _pimpl->setAttrMatcher( matcher_r ); } 00207 00209 00210 bool LookupAttr::pool() const 00211 { return _pimpl->pool(); } 00212 00213 void LookupAttr::setPool( Location loc_r ) 00214 { _pimpl->setPool( loc_r ); } 00215 00216 Repository LookupAttr::repo() const 00217 { return _pimpl->repo(); } 00218 00219 void LookupAttr::setRepo( Repository repo_r, Location loc_r ) 00220 { _pimpl->setRepo( repo_r, loc_r ); } 00221 00222 Solvable LookupAttr::solvable() const 00223 { return _pimpl->solvable(); } 00224 00225 void LookupAttr::setSolvable( Solvable solv_r ) 00226 { _pimpl->setSolvable( solv_r ); } 00227 00228 SolvAttr LookupAttr::parent() const 00229 { return _pimpl->parent(); } 00230 00231 void LookupAttr::setParent( SolvAttr attr_r ) 00232 { _pimpl->setParent( attr_r ); } 00233 00235 00236 LookupAttr::iterator LookupAttr::begin() const 00237 { return _pimpl->begin(); } 00238 00239 LookupAttr::iterator LookupAttr::end() const 00240 { return _pimpl->end(); } 00241 00242 bool LookupAttr::empty() const 00243 { return begin() == end(); } 00244 00245 LookupAttr::size_type LookupAttr::size() const 00246 { 00247 size_type c = 0; 00248 for_( it, begin(), end() ) 00249 ++c; 00250 return c; 00251 } 00252 00254 00255 std::ostream & operator<<( std::ostream & str, const LookupAttr & obj ) 00256 { 00257 if ( obj.attr() == SolvAttr::noAttr ) 00258 return str << "search nothing"; 00259 00260 if ( obj.attr() ) 00261 str << "seach " << obj.attr() << " in "; 00262 else 00263 str << "seach ALL in "; 00264 00265 if ( obj.solvable() ) 00266 return str << obj.solvable(); 00267 if ( obj.repo() ) 00268 return str << obj.repo(); 00269 return str << "pool"; 00270 } 00271 00272 std::ostream & dumpOn( std::ostream & str, const LookupAttr & obj ) 00273 { 00274 return dumpRange( str << obj, obj.begin(), obj.end() ); 00275 } 00276 00278 // 00279 // CLASS NAME : LookupRepoAttr 00280 // 00282 00283 LookupRepoAttr::LookupRepoAttr( SolvAttr attr_r, Repository repo_r ) 00284 : LookupAttr( attr_r, repo_r, REPO_ATTR ) 00285 {} 00286 00287 void LookupRepoAttr::setRepo( Repository repo_r ) 00288 { LookupAttr::setRepo( repo_r, REPO_ATTR ); } 00289 00291 // 00292 // CLASS NAME : detail::DIWrap 00293 // 00295 00296 namespace detail 00297 { 00298 DIWrap::DIWrap( RepoIdType repoId_r, SolvableIdType solvId_r, IdType attrId_r, 00299 const std::string & mstring_r, int flags_r ) 00300 : _dip( new ::Dataiterator ) 00301 , _mstring( mstring_r ) 00302 { 00303 ::dataiterator_init( _dip, sat::Pool::instance().get(), repoId_r, solvId_r, attrId_r, 00304 _mstring.empty() ? 0 : _mstring.c_str(), flags_r ); 00305 } 00306 00307 DIWrap::DIWrap( RepoIdType repoId_r, SolvableIdType solvId_r, IdType attrId_r, 00308 const char * mstring_r, int flags_r ) 00309 : _dip( new ::Dataiterator ) 00310 , _mstring( mstring_r ? mstring_r : "" ) 00311 { 00312 ::dataiterator_init( _dip, sat::Pool::instance().get(), repoId_r, solvId_r, attrId_r, 00313 _mstring.empty() ? 0 : _mstring.c_str(), flags_r ); 00314 } 00315 00316 DIWrap::DIWrap( const DIWrap & rhs ) 00317 : _dip( 0 ) 00318 , _mstring( rhs._mstring ) 00319 { 00320 if ( rhs._dip ) 00321 { 00322 _dip = new ::Dataiterator; 00323 ::dataiterator_init_clone( _dip, rhs._dip ); 00324 } 00325 } 00326 00327 DIWrap::~DIWrap() 00328 { 00329 if ( _dip ) 00330 { 00331 ::dataiterator_free( _dip ); 00332 delete _dip; 00333 } 00334 } 00335 00336 std::ostream & operator<<( std::ostream & str, const DIWrap & obj ) 00337 { return str << obj.get(); } 00338 } 00339 00341 // 00342 // CLASS NAME : LookupAttr::iterator 00343 // 00345 00347 // position and moving 00349 00350 Repository LookupAttr::iterator::inRepo() const 00351 { return _dip ? Repository( _dip->repo ) : Repository::noRepository; } 00352 00353 Solvable LookupAttr::iterator::inSolvable() const 00354 { return _dip ? Solvable( _dip->solvid ) : Solvable::noSolvable; } 00355 00356 SolvAttr LookupAttr::iterator::inSolvAttr() const 00357 { return _dip ? SolvAttr( _dip->key->name ) : SolvAttr::noAttr; } 00358 00359 void LookupAttr::iterator::nextSkipSolvAttr() 00360 { if ( _dip ) ::dataiterator_skip_attribute( _dip.get() ); } 00361 00362 void LookupAttr::iterator::nextSkipSolvable() 00363 { if ( _dip ) ::dataiterator_skip_solvable( _dip.get() ); } 00364 00365 void LookupAttr::iterator::nextSkipRepo() 00366 { if ( _dip ) ::dataiterator_skip_repo( _dip.get() ); } 00367 00368 void LookupAttr::iterator::stayInThisSolvable() 00369 { if ( _dip ) { _dip.get()->repoid = -1; _dip.get()->flags |= SEARCH_THISSOLVID; } } 00370 00371 void LookupAttr::iterator::stayInThisRepo() 00372 { if ( _dip ) { _dip.get()->repoid = -1; } } 00373 00375 // attr value type test 00377 00378 detail::IdType LookupAttr::iterator::solvAttrType() const 00379 { return _dip ? _dip->key->type : detail::noId; } 00380 00381 bool LookupAttr::iterator::solvAttrNumeric() const 00382 { 00383 switch ( solvAttrType() ) 00384 { 00385 case REPOKEY_TYPE_U32: 00386 case REPOKEY_TYPE_NUM: 00387 case REPOKEY_TYPE_CONSTANT: 00388 return true; 00389 break; 00390 } 00391 return false; 00392 } 00393 00394 bool LookupAttr::iterator::solvAttrString() const 00395 { 00396 switch ( solvAttrType() ) 00397 { 00398 case REPOKEY_TYPE_ID: 00399 case REPOKEY_TYPE_IDARRAY: 00400 case REPOKEY_TYPE_CONSTANTID: 00401 case REPOKEY_TYPE_STR: 00402 case REPOKEY_TYPE_DIRSTRARRAY: 00403 return true; 00404 break; 00405 } 00406 return false; 00407 } 00408 00409 bool LookupAttr::iterator::solvAttrIdString() const 00410 { 00411 switch ( solvAttrType() ) 00412 { 00413 case REPOKEY_TYPE_ID: 00414 case REPOKEY_TYPE_IDARRAY: 00415 case REPOKEY_TYPE_CONSTANTID: 00416 return true; 00417 break; 00418 } 00419 return false; 00420 } 00421 00422 bool LookupAttr::iterator::solvAttrCheckSum() const 00423 { 00424 switch ( solvAttrType() ) 00425 { 00426 case REPOKEY_TYPE_MD5: 00427 case REPOKEY_TYPE_SHA1: 00428 case REPOKEY_TYPE_SHA256: 00429 return true; 00430 break; 00431 } 00432 return false; 00433 } 00434 00436 namespace 00437 { 00438 enum SubType { ST_NONE, // no sub-structure 00439 ST_FLEX, // flexarray 00440 ST_SUB }; // inside sub-structure 00441 SubType subType( const detail::DIWrap & dip ) 00442 { 00443 if ( ! dip ) 00444 return ST_NONE; 00445 if ( dip.get()->key->type == REPOKEY_TYPE_FLEXARRAY ) 00446 return ST_FLEX; 00447 return dip.get()->kv.parent ? ST_SUB : ST_NONE; 00448 } 00449 } 00451 00452 bool LookupAttr::iterator::solvAttrSubEntry() const 00453 { return subType( _dip ) != ST_NONE; } 00454 00456 // Iterate sub-structures. 00458 00459 bool LookupAttr::iterator::subEmpty() const 00460 { return( subBegin() == subEnd() ); } 00461 00462 LookupAttr::size_type LookupAttr::iterator::subSize() const 00463 { 00464 size_type c = 0; 00465 for_( it, subBegin(), subEnd() ) 00466 ++c; 00467 return c; 00468 } 00469 00470 LookupAttr::iterator LookupAttr::iterator::subBegin() const 00471 { 00472 SubType subtype( subType( _dip ) ); 00473 if ( subtype == ST_NONE ) 00474 return subEnd(); 00475 // setup the new sub iterator with the remembered position 00476 detail::DIWrap dip( 0, 0, 0 ); 00477 ::dataiterator_clonepos( dip.get(), _dip.get() ); 00478 switch ( subtype ) 00479 { 00480 case ST_NONE: // not reached 00481 break; 00482 case ST_FLEX: 00483 ::dataiterator_seek( dip.get(), DI_SEEK_CHILD|DI_SEEK_STAY ); 00484 break; 00485 case ST_SUB: 00486 ::dataiterator_seek( dip.get(), DI_SEEK_REWIND|DI_SEEK_STAY ); 00487 break; 00488 } 00489 return iterator( dip ); // iterator takes over ownership! 00490 } 00491 00492 LookupAttr::iterator LookupAttr::iterator::subEnd() const 00493 { 00494 return iterator(); 00495 } 00496 00497 LookupAttr::iterator LookupAttr::iterator::subFind( SolvAttr attr_r ) const 00498 { 00499 iterator it = subBegin(); 00500 if ( attr_r != sat::SolvAttr::allAttr ) 00501 { 00502 while ( it != subEnd() && it.inSolvAttr() != attr_r ) 00503 ++it; 00504 } 00505 return it; 00506 } 00507 00508 LookupAttr::iterator LookupAttr::iterator::subFind( const C_Str & attrname_r ) const 00509 { 00510 if ( attrname_r.empty() ) 00511 return subBegin(); 00512 00513 SubType subtype( subType( _dip ) ); 00514 if ( subtype == ST_NONE ) 00515 return subBegin(); 00516 00517 std::string subattr( inSolvAttr().asString() ); 00518 if ( subtype == ST_FLEX ) 00519 { 00520 // append ":attrname" 00521 subattr += ":"; 00522 subattr += attrname_r; 00523 } 00524 else 00525 { 00526 // replace "oldname" after ':' with "attrname" 00527 std::string::size_type pos( subattr.rfind( ':' ) ); 00528 if ( pos != std::string::npos ) 00529 { 00530 subattr.erase( pos+1 ); 00531 subattr += attrname_r; 00532 } 00533 else 00534 subattr = attrname_r; // no ':' so replace all. 00535 } 00536 return subFind( SolvAttr( subattr ) ); 00537 } 00538 00540 // attr value retrieval 00542 00543 int LookupAttr::iterator::asInt() const 00544 { 00545 if ( _dip ) 00546 { 00547 switch ( solvAttrType() ) 00548 { 00549 case REPOKEY_TYPE_U32: 00550 case REPOKEY_TYPE_NUM: 00551 case REPOKEY_TYPE_CONSTANT: 00552 return _dip->kv.num; 00553 break; 00554 } 00555 } 00556 return 0; 00557 } 00558 00559 unsigned LookupAttr::iterator::asUnsigned() const 00560 { return asInt(); } 00561 00562 bool LookupAttr::iterator::asBool() const 00563 { return asInt(); } 00564 00565 00566 const char * LookupAttr::iterator::c_str() const 00567 { 00568 if ( _dip ) 00569 { 00570 switch ( solvAttrType() ) 00571 { 00572 case REPOKEY_TYPE_ID: 00573 case REPOKEY_TYPE_IDARRAY: 00574 case REPOKEY_TYPE_CONSTANTID: 00575 if ( _dip->data && _dip->data->localpool ) 00576 return ::stringpool_id2str( &_dip->data->spool, _dip->kv.id ); // in local pool 00577 else 00578 return IdString( _dip->kv.id ).c_str(); // in global pool 00579 break; 00580 00581 case REPOKEY_TYPE_STR: 00582 return _dip->kv.str; 00583 break; 00584 00585 case REPOKEY_TYPE_DIRSTRARRAY: 00586 return ::repodata_dir2str( _dip->data, _dip->kv.id, _dip->kv.str ); 00587 break; 00588 } 00589 } 00590 return 0; 00591 } 00592 00593 std::string LookupAttr::iterator::asString() const 00594 { 00595 if ( _dip ) 00596 { 00597 switch ( solvAttrType() ) 00598 { 00599 case REPOKEY_TYPE_ID: 00600 case REPOKEY_TYPE_IDARRAY: 00601 case REPOKEY_TYPE_CONSTANTID: 00602 { 00603 detail::IdType id = ::repodata_globalize_id( _dip->data, _dip->kv.id, 1 ); 00604 return ISRELDEP(id) ? Capability( id ).asString() 00605 : IdString( id ).asString(); 00606 } 00607 break; 00608 00609 case REPOKEY_TYPE_STR: 00610 case REPOKEY_TYPE_DIRSTRARRAY: 00611 { 00612 const char * ret( c_str() ); 00613 return ret ? ret : ""; 00614 } 00615 break; 00616 00617 case REPOKEY_TYPE_U32: 00618 case REPOKEY_TYPE_NUM: 00619 case REPOKEY_TYPE_CONSTANT: 00620 return str::numstring( asInt() ); 00621 break; 00622 00623 case REPOKEY_TYPE_MD5: 00624 case REPOKEY_TYPE_SHA1: 00625 case REPOKEY_TYPE_SHA256: 00626 { 00627 return asCheckSum().asString(); 00628 } 00629 break; 00630 00631 case REPOKEY_TYPE_FLEXARRAY: 00632 { 00633 std::ostringstream str; 00634 str << "{" << endl; 00635 for_( it, subBegin(), subEnd() ) 00636 { 00637 str << " " << it.inSolvAttr() << " = " << it.asString() << endl; 00638 } 00639 str << "}"; 00640 return str.str(); 00641 } 00642 break; 00643 } 00644 } 00645 return std::string(); 00646 } 00647 00648 IdString LookupAttr::iterator::idStr() const 00649 { 00650 if ( _dip ) 00651 { 00652 switch ( solvAttrType() ) 00653 { 00654 case REPOKEY_TYPE_ID: 00655 case REPOKEY_TYPE_IDARRAY: 00656 case REPOKEY_TYPE_CONSTANTID: 00657 return IdString( ::repodata_globalize_id( _dip->data, _dip->kv.id, 1 ) ); 00658 break; 00659 } 00660 } 00661 return IdString(); 00662 } 00663 00664 CheckSum LookupAttr::iterator::asCheckSum() const 00665 { 00666 if ( _dip ) 00667 { 00668 switch ( solvAttrType() ) 00669 { 00670 case REPOKEY_TYPE_MD5: 00671 return CheckSum::md5( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) ); 00672 break; 00673 00674 case REPOKEY_TYPE_SHA1: 00675 return CheckSum::sha1( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) ); 00676 break; 00677 00678 case REPOKEY_TYPE_SHA256: 00679 return CheckSum::sha256( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) ); 00680 break; 00681 } 00682 } 00683 return CheckSum(); 00684 } 00685 00687 // internal stuff below 00689 00690 LookupAttr::iterator::iterator() 00691 : iterator_adaptor_( 0 ) 00692 {} 00693 00694 LookupAttr::iterator::iterator( const iterator & rhs ) 00695 : iterator_adaptor_( 0 ) 00696 , _dip( rhs._dip ) 00697 { 00698 base_reference() = _dip.get(); 00699 } 00700 00701 LookupAttr::iterator::iterator( detail::DIWrap & dip_r ) 00702 : iterator_adaptor_( 0 ) 00703 { 00704 _dip.swap( dip_r ); // take ownership! 00705 base_reference() = _dip.get(); 00706 increment(); 00707 } 00708 00709 LookupAttr::iterator::~iterator() 00710 {} 00711 00712 LookupAttr::iterator & LookupAttr::iterator::operator=( const iterator & rhs ) 00713 { 00714 if ( &rhs != this ) 00715 { 00716 _dip = rhs._dip; 00717 base_reference() = _dip.get(); 00718 } 00719 return *this; 00720 } 00721 00723 00724 bool LookupAttr::iterator::dip_equal( const ::_Dataiterator & lhs, const ::_Dataiterator & rhs ) const 00725 { 00726 // Iterator equal is same position in same container. 00727 // Here: same attribute in same solvable. 00728 return( lhs.solvid == rhs.solvid && lhs.key->name == rhs.key->name ); 00729 } 00730 00731 detail::IdType LookupAttr::iterator::dereference() const 00732 { 00733 return _dip ? ::repodata_globalize_id( _dip->data, _dip->kv.id, 1 ) 00734 : detail::noId; 00735 } 00736 00737 void LookupAttr::iterator::increment() 00738 { 00739 if ( _dip && ! ::dataiterator_step( _dip.get() ) ) 00740 { 00741 _dip.reset(); 00742 base_reference() = 0; 00743 } 00744 } 00745 00746 std::ostream & operator<<( std::ostream & str, const LookupAttr::iterator & obj ) 00747 { 00748 const ::_Dataiterator * dip = obj.get(); 00749 if ( ! dip ) 00750 return str << "EndOfQuery"; 00751 00752 if ( obj.inSolvable() ) 00753 str << obj.inSolvable(); 00754 else if ( obj.inRepo() ) 00755 str << obj.inRepo(); 00756 00757 str << '<' << obj.inSolvAttr() << (obj.solvAttrSubEntry() ? ">(*" : ">(") 00758 << IdString(obj.solvAttrType()) << ") = " << obj.asString(); 00759 return str; 00760 } 00761 00762 template<> CheckSum LookupAttr::iterator::asType<CheckSum>() const 00763 { return asCheckSum(); } 00764 00766 } // namespace sat 00769 } // namespace zypp 00771 00772 std::ostream & operator<<( std::ostream & str, const ::_Dataiterator * obj ) 00773 { 00774 str << "::_Dataiterator("; 00775 if ( ! obj ) 00776 { 00777 str << "NULL"; 00778 } 00779 else 00780 { 00781 str << "|" << zypp::Repository(obj->repo); 00782 str << "|" << zypp::sat::Solvable(obj->solvid); 00783 str << "|" << zypp::IdString(obj->key->name); 00784 str << "|" << zypp::IdString(obj->key->type); 00785 str << "|" << obj->repodataid; 00786 str << "|" << obj->repoid; 00787 } 00788 return str << ")"; 00789 } 00790