1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/sat/LookupAttr.cc
16 #include "zypp/base/Logger.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 std::ostream & operator<<( std::ostream & str, const LookupAttr & obj )
68 if ( obj.attr() == SolvAttr::noAttr )
69 return str << "search nothing";
72 str << "seach " << obj.attr() << " in ";
74 str << "seach ALL in ";
77 return str << obj.solvable();
79 return str << obj.repo();
83 std::ostream & dumpOn( std::ostream & str, const LookupAttr & obj )
86 for_( it, obj.begin(), obj.end() )
88 str << " " << it << endl;
90 return str << "<EndOfSerach>";
93 ///////////////////////////////////////////////////////////////////
95 // CLASS NAME : LookupAttr::iterator
97 ///////////////////////////////////////////////////////////////////
99 ///////////////////////////////////////////////////////////////////
100 // position and moving
101 ///////////////////////////////////////////////////////////////////
103 Repository LookupAttr::iterator::inRepo() const
104 { return Repository( _dip->repo ); }
106 Solvable LookupAttr::iterator::inSolvable() const
107 { return Solvable( _dip->solvid ); }
109 SolvAttr LookupAttr::iterator::inSolvAttr() const
110 { return SolvAttr( _dip->key->name ); }
112 void LookupAttr::iterator::nextSkipSolvAttr()
113 { ::dataiterator_skip_attribute( _dip.get() ); }
115 void LookupAttr::iterator::nextSkipSolvable()
116 { ::dataiterator_skip_solvable( _dip.get() ); }
118 void LookupAttr::iterator::nextSkipRepo()
119 { ::dataiterator_skip_repo( _dip.get() ); }
121 ///////////////////////////////////////////////////////////////////
122 // attr value type test
123 ///////////////////////////////////////////////////////////////////
125 detail::IdType LookupAttr::iterator::solvAttrType() const
126 { return _dip->key->type; }
128 bool LookupAttr::iterator::solvAttrNumeric() const
130 switch ( solvAttrType() )
132 case REPOKEY_TYPE_U32:
133 case REPOKEY_TYPE_NUM:
134 case REPOKEY_TYPE_CONSTANT:
141 bool LookupAttr::iterator::solvAttrString() const
143 switch ( solvAttrType() )
145 case REPOKEY_TYPE_ID:
146 case REPOKEY_TYPE_IDARRAY:
147 case REPOKEY_TYPE_CONSTANTID:
148 case REPOKEY_TYPE_STR:
149 case REPOKEY_TYPE_DIRSTRARRAY:
156 bool LookupAttr::iterator::solvAttrIdString() const
158 switch ( solvAttrType() )
160 case REPOKEY_TYPE_ID:
161 case REPOKEY_TYPE_IDARRAY:
162 case REPOKEY_TYPE_CONSTANTID:
169 bool LookupAttr::iterator::solvAttrCheckSum() const
171 switch ( solvAttrType() )
173 case REPOKEY_TYPE_MD5:
174 case REPOKEY_TYPE_SHA1:
175 case REPOKEY_TYPE_SHA256:
182 ///////////////////////////////////////////////////////////////////
183 // attr value type test
184 ///////////////////////////////////////////////////////////////////
186 int LookupAttr::iterator::asInt() const
188 switch ( solvAttrType() )
190 case REPOKEY_TYPE_U32:
191 case REPOKEY_TYPE_NUM:
192 case REPOKEY_TYPE_CONSTANT:
199 unsigned LookupAttr::iterator::asUnsigned() const
202 bool LookupAttr::iterator::asBool() const
206 const char * LookupAttr::iterator::c_str() const
208 switch ( solvAttrType() )
210 case REPOKEY_TYPE_ID:
211 case REPOKEY_TYPE_IDARRAY:
212 case REPOKEY_TYPE_CONSTANTID:
213 if ( _dip->data && _dip->data->localpool )
214 return ::stringpool_id2str( &_dip->data->spool, _dip->kv.id ); // in local pool
216 return IdString( _dip->kv.id ).c_str(); // in global pool
219 case REPOKEY_TYPE_STR:
223 case REPOKEY_TYPE_DIRSTRARRAY:
224 return ::repodata_dir2str( _dip->data, _dip->kv.id, _dip->kv.str );
230 std::string LookupAttr::iterator::asString() const
232 switch ( solvAttrType() )
234 case REPOKEY_TYPE_ID:
235 case REPOKEY_TYPE_IDARRAY:
236 case REPOKEY_TYPE_CONSTANTID:
237 case REPOKEY_TYPE_STR:
238 case REPOKEY_TYPE_DIRSTRARRAY:
240 const char * ret( c_str() );
241 return ret ? ret : "";
245 case REPOKEY_TYPE_U32:
246 case REPOKEY_TYPE_NUM:
247 case REPOKEY_TYPE_CONSTANT:
248 return str::numstring( asInt() );
251 case REPOKEY_TYPE_MD5:
252 case REPOKEY_TYPE_SHA1:
253 case REPOKEY_TYPE_SHA256:
255 std::ostringstream str;
261 return std::string();
264 IdString LookupAttr::iterator::idStr() const
266 switch ( solvAttrType() )
268 case REPOKEY_TYPE_ID:
269 case REPOKEY_TYPE_IDARRAY:
270 case REPOKEY_TYPE_CONSTANTID:
271 return IdString( ::repodata_globalize_id( _dip->data, _dip->kv.id ) );
277 CheckSum LookupAttr::iterator::asCheckSum() const
279 switch ( solvAttrType() )
281 case REPOKEY_TYPE_MD5:
282 return CheckSum::md5( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
285 case REPOKEY_TYPE_SHA1:
286 return CheckSum::sha1( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
289 case REPOKEY_TYPE_SHA256:
290 return CheckSum::sha256( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
296 ///////////////////////////////////////////////////////////////////
297 // internal stuff below
298 ///////////////////////////////////////////////////////////////////
300 LookupAttr::iterator::~iterator()
303 LookupAttr::iterator::iterator()
304 : iterator_adaptor_( 0 )
307 LookupAttr::iterator::iterator( const iterator & rhs )
308 : iterator_adaptor_( cloneFrom( rhs.base() ) )
312 LookupAttr::iterator & LookupAttr::iterator::operator=( const iterator & rhs )
316 _dip.reset( cloneFrom( rhs.base() ) );
317 base_reference() = _dip.get();
322 LookupAttr::iterator::iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r )
323 : iterator_adaptor_( dip_r.get() )
324 , _chainRepos( chain_r )
326 _dip.swap( dip_r ); // take ownership!
330 ///////////////////////////////////////////////////////////////////
332 ::_Dataiterator * LookupAttr::iterator::cloneFrom( const ::_Dataiterator * rhs )
336 ::_Dataiterator * ret( new ::_Dataiterator );
341 bool LookupAttr::iterator::dip_equal( const ::_Dataiterator & lhs, const ::_Dataiterator & rhs ) const
343 // requires ::memset in LookupAttr::begin
344 return ::memcmp( &lhs, &rhs, sizeof(::_Dataiterator) ) == 0;
347 detail::IdType LookupAttr::iterator::dereference() const
349 return _dip ? ::repodata_globalize_id( _dip->data, _dip->kv.id )
353 void LookupAttr::iterator::increment()
355 if ( _dip && ! ::dataiterator_step( _dip.get() ) )
357 bool haveNext = false;
360 Repository nextRepo( inRepo().nextInPool() );
363 ::dataiterator_jump_to_repo( _dip.get(), nextRepo.get() );
364 haveNext = ::dataiterator_step( _dip.get() );
370 base_reference() = 0;
375 std::ostream & operator<<( std::ostream & str, const LookupAttr::iterator & obj )
377 const ::_Dataiterator * dip = obj.get();
379 return str << "EndOfQuery" << endl;
381 if ( obj.inSolvable() )
382 str << obj.inSolvable();
383 else if ( obj.inRepo() )
386 str << '<' << obj.inSolvAttr()
387 << ">(" << obj.solvAttrType() << ") = " << obj.asString();
391 /////////////////////////////////////////////////////////////////
393 ///////////////////////////////////////////////////////////////////
394 /////////////////////////////////////////////////////////////////
396 ///////////////////////////////////////////////////////////////////