1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/sat/LookupAttr.cc
16 #include "zypp/base/LogTools.h"
17 #include "zypp/base/String.h"
19 #include "zypp/sat/detail/PoolImpl.h"
21 #include "zypp/sat/LookupAttr.h"
22 #include "zypp/CheckSum.h"
26 ///////////////////////////////////////////////////////////////////
28 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
33 LookupAttr::iterator LookupAttr::begin() const
35 if ( _attr == SolvAttr::noAttr )
38 scoped_ptr< ::_Dataiterator> dip( new ::Dataiterator );
39 // needed while LookupAttr::iterator::dip_equal does ::memcmp:
40 ::memset( dip.get(), 0, sizeof(::_Dataiterator) );
44 ::dataiterator_init( dip.get(), _solv.repository().id(), _solv.id(), _attr.id(), 0, SEARCH_NO_STORAGE_SOLVABLE );
46 ::dataiterator_init( dip.get(), _repo.id(), 0, _attr.id(), 0, SEARCH_NO_STORAGE_SOLVABLE );
47 else if ( ! sat::Pool::instance().reposEmpty() )
49 ::dataiterator_init( dip.get(), sat::Pool::instance().reposBegin()->id(), 0, _attr.id(), 0, SEARCH_NO_STORAGE_SOLVABLE );
55 return iterator( dip, chain ); // iterator takes over ownership!
58 LookupAttr::iterator LookupAttr::end() const
63 bool LookupAttr::empty() const
64 { return begin() == end(); }
66 LookupAttr::size_type LookupAttr::size() const
69 for_( it, begin(), end() )
74 std::ostream & operator<<( std::ostream & str, const LookupAttr & obj )
76 if ( obj.attr() == SolvAttr::noAttr )
77 return str << "search nothing";
80 str << "seach " << obj.attr() << " in ";
82 str << "seach ALL in ";
85 return str << obj.solvable();
87 return str << obj.repo();
91 std::ostream & dumpOn( std::ostream & str, const LookupAttr & obj )
93 return dumpRange( str << obj, obj.begin(), obj.end() );
96 ///////////////////////////////////////////////////////////////////
98 // CLASS NAME : LookupAttr::iterator
100 ///////////////////////////////////////////////////////////////////
102 ///////////////////////////////////////////////////////////////////
103 // position and moving
104 ///////////////////////////////////////////////////////////////////
106 Repository LookupAttr::iterator::inRepo() const
107 { return _dip ? Repository( _dip->repo ) : Repository::noRepository; }
109 Solvable LookupAttr::iterator::inSolvable() const
110 { return _dip ? Solvable( _dip->solvid ) : Solvable::noSolvable; }
112 SolvAttr LookupAttr::iterator::inSolvAttr() const
113 { return _dip ? SolvAttr( _dip->key->name ) : SolvAttr::noAttr; }
115 void LookupAttr::iterator::nextSkipSolvAttr()
116 { if ( _dip ) ::dataiterator_skip_attribute( _dip.get() ); }
118 void LookupAttr::iterator::nextSkipSolvable()
119 { if ( _dip ) ::dataiterator_skip_solvable( _dip.get() ); }
121 void LookupAttr::iterator::nextSkipRepo()
122 { if ( _dip ) ::dataiterator_skip_repo( _dip.get() ); }
124 ///////////////////////////////////////////////////////////////////
125 // attr value type test
126 ///////////////////////////////////////////////////////////////////
128 detail::IdType LookupAttr::iterator::solvAttrType() const
129 { return _dip ? _dip->key->type : detail::noId; }
131 bool LookupAttr::iterator::solvAttrNumeric() const
133 switch ( solvAttrType() )
135 case REPOKEY_TYPE_U32:
136 case REPOKEY_TYPE_NUM:
137 case REPOKEY_TYPE_CONSTANT:
144 bool LookupAttr::iterator::solvAttrString() const
146 switch ( solvAttrType() )
148 case REPOKEY_TYPE_ID:
149 case REPOKEY_TYPE_IDARRAY:
150 case REPOKEY_TYPE_CONSTANTID:
151 case REPOKEY_TYPE_STR:
152 case REPOKEY_TYPE_DIRSTRARRAY:
159 bool LookupAttr::iterator::solvAttrIdString() const
161 switch ( solvAttrType() )
163 case REPOKEY_TYPE_ID:
164 case REPOKEY_TYPE_IDARRAY:
165 case REPOKEY_TYPE_CONSTANTID:
172 bool LookupAttr::iterator::solvAttrCheckSum() const
174 switch ( solvAttrType() )
176 case REPOKEY_TYPE_MD5:
177 case REPOKEY_TYPE_SHA1:
178 case REPOKEY_TYPE_SHA256:
185 ///////////////////////////////////////////////////////////////////
186 // attr value retrieval
187 ///////////////////////////////////////////////////////////////////
189 int LookupAttr::iterator::asInt() const
193 switch ( solvAttrType() )
195 case REPOKEY_TYPE_U32:
196 case REPOKEY_TYPE_NUM:
197 case REPOKEY_TYPE_CONSTANT:
205 unsigned LookupAttr::iterator::asUnsigned() const
208 bool LookupAttr::iterator::asBool() const
212 const char * LookupAttr::iterator::c_str() const
216 switch ( solvAttrType() )
218 case REPOKEY_TYPE_ID:
219 case REPOKEY_TYPE_IDARRAY:
220 case REPOKEY_TYPE_CONSTANTID:
221 if ( _dip->data && _dip->data->localpool )
222 return ::stringpool_id2str( &_dip->data->spool, _dip->kv.id ); // in local pool
224 return IdString( _dip->kv.id ).c_str(); // in global pool
227 case REPOKEY_TYPE_STR:
231 case REPOKEY_TYPE_DIRSTRARRAY:
232 return ::repodata_dir2str( _dip->data, _dip->kv.id, _dip->kv.str );
239 std::string LookupAttr::iterator::asString() const
243 switch ( solvAttrType() )
245 case REPOKEY_TYPE_ID:
246 case REPOKEY_TYPE_IDARRAY:
247 case REPOKEY_TYPE_CONSTANTID:
248 case REPOKEY_TYPE_STR:
249 case REPOKEY_TYPE_DIRSTRARRAY:
251 const char * ret( c_str() );
252 return ret ? ret : "";
256 case REPOKEY_TYPE_U32:
257 case REPOKEY_TYPE_NUM:
258 case REPOKEY_TYPE_CONSTANT:
259 return str::numstring( asInt() );
262 case REPOKEY_TYPE_MD5:
263 case REPOKEY_TYPE_SHA1:
264 case REPOKEY_TYPE_SHA256:
266 std::ostringstream str;
273 return std::string();
276 IdString LookupAttr::iterator::idStr() const
280 switch ( solvAttrType() )
282 case REPOKEY_TYPE_ID:
283 case REPOKEY_TYPE_IDARRAY:
284 case REPOKEY_TYPE_CONSTANTID:
285 return IdString( ::repodata_globalize_id( _dip->data, _dip->kv.id ) );
292 CheckSum LookupAttr::iterator::asCheckSum() const
296 switch ( solvAttrType() )
298 case REPOKEY_TYPE_MD5:
299 return CheckSum::md5( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
302 case REPOKEY_TYPE_SHA1:
303 return CheckSum::sha1( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
306 case REPOKEY_TYPE_SHA256:
307 return CheckSum::sha256( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
314 ///////////////////////////////////////////////////////////////////
315 // internal stuff below
316 ///////////////////////////////////////////////////////////////////
318 LookupAttr::iterator::~iterator()
321 LookupAttr::iterator::iterator()
322 : iterator_adaptor_( 0 )
325 LookupAttr::iterator::iterator( const iterator & rhs )
326 : iterator_adaptor_( cloneFrom( rhs.base() ) )
328 , _chainRepos(rhs._chainRepos)
331 LookupAttr::iterator & LookupAttr::iterator::operator=( const iterator & rhs )
335 _dip.reset( cloneFrom( rhs.base() ) );
336 base_reference() = _dip.get();
337 _chainRepos = rhs._chainRepos;
342 LookupAttr::iterator::iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r )
343 : iterator_adaptor_( dip_r.get() )
344 , _chainRepos( chain_r )
346 _dip.swap( dip_r ); // take ownership!
350 ///////////////////////////////////////////////////////////////////
352 ::_Dataiterator * LookupAttr::iterator::cloneFrom( const ::_Dataiterator * rhs )
356 ::_Dataiterator * ret( new ::_Dataiterator );
361 bool LookupAttr::iterator::dip_equal( const ::_Dataiterator & lhs, const ::_Dataiterator & rhs ) const
363 // requires ::memset in LookupAttr::begin
364 return ::memcmp( &lhs, &rhs, sizeof(::_Dataiterator) ) == 0;
367 detail::IdType LookupAttr::iterator::dereference() const
369 return _dip ? ::repodata_globalize_id( _dip->data, _dip->kv.id )
373 void LookupAttr::iterator::increment()
375 if ( _dip && ! ::dataiterator_step( _dip.get() ) )
377 bool haveNext = false;
380 Repository nextRepo( inRepo().nextInPool() );
383 ::dataiterator_jump_to_repo( _dip.get(), nextRepo.get() );
384 haveNext = ::dataiterator_step( _dip.get() );
390 base_reference() = 0;
395 std::ostream & operator<<( std::ostream & str, const LookupAttr::iterator & obj )
397 const ::_Dataiterator * dip = obj.get();
399 return str << "EndOfQuery" << endl;
401 if ( obj.inSolvable() )
402 str << obj.inSolvable();
403 else if ( obj.inRepo() )
406 str << '<' << obj.inSolvAttr()
407 << ">(" << obj.solvAttrType() << ") = " << obj.asString();
411 /////////////////////////////////////////////////////////////////
413 ///////////////////////////////////////////////////////////////////
414 /////////////////////////////////////////////////////////////////
416 ///////////////////////////////////////////////////////////////////