1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/sat/LookupAttr.cc
15 #include "zypp/base/LogTools.h"
16 #include "zypp/base/String.h"
18 #include "zypp/sat/detail/PoolImpl.h"
20 #include "zypp/sat/LookupAttr.h"
21 #include "zypp/CheckSum.h"
25 ///////////////////////////////////////////////////////////////////
27 { /////////////////////////////////////////////////////////////////
28 ///////////////////////////////////////////////////////////////////
30 { /////////////////////////////////////////////////////////////////
32 LookupAttr::iterator LookupAttr::begin() const
34 if ( _attr == SolvAttr::noAttr )
37 #warning Need to call dataiterator_free, use Autodispose instead of scoped_ptr
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(), sat::Pool::instance().get(), _solv.repository().id(), _solv.id(), _attr.id(), 0, 0 );
48 ::dataiterator_init( dip.get(), sat::Pool::instance().get(), _repo.id(), 0, _attr.id(), 0, 0 );
50 else if ( ! sat::Pool::instance().reposEmpty() )
52 ::dataiterator_init( dip.get(), sat::Pool::instance().get(), 0, 0, _attr.id(), 0, 0 );
57 return iterator( dip ); // iterator takes over ownership!
60 LookupAttr::iterator LookupAttr::end() const
65 bool LookupAttr::empty() const
66 { return begin() == end(); }
68 LookupAttr::size_type LookupAttr::size() const
71 for_( it, begin(), end() )
76 std::ostream & operator<<( std::ostream & str, const LookupAttr & obj )
78 if ( obj.attr() == SolvAttr::noAttr )
79 return str << "search nothing";
82 str << "seach " << obj.attr() << " in ";
84 str << "seach ALL in ";
87 return str << obj.solvable();
89 return str << obj.repo();
93 std::ostream & dumpOn( std::ostream & str, const LookupAttr & obj )
95 return dumpRange( str << obj, obj.begin(), obj.end() );
98 ///////////////////////////////////////////////////////////////////
100 // CLASS NAME : LookupAttr::iterator
102 ///////////////////////////////////////////////////////////////////
104 ///////////////////////////////////////////////////////////////////
105 // position and moving
106 ///////////////////////////////////////////////////////////////////
108 Repository LookupAttr::iterator::inRepo() const
109 { return _dip ? Repository( _dip->repo ) : Repository::noRepository; }
111 Solvable LookupAttr::iterator::inSolvable() const
112 { return _dip ? Solvable( _dip->solvid ) : Solvable::noSolvable; }
114 SolvAttr LookupAttr::iterator::inSolvAttr() const
115 { return _dip ? SolvAttr( _dip->key->name ) : SolvAttr::noAttr; }
117 void LookupAttr::iterator::nextSkipSolvAttr()
118 { if ( _dip ) ::dataiterator_skip_attribute( _dip.get() ); }
120 void LookupAttr::iterator::nextSkipSolvable()
121 { if ( _dip ) ::dataiterator_skip_solvable( _dip.get() ); }
123 void LookupAttr::iterator::nextSkipRepo()
124 { if ( _dip ) ::dataiterator_skip_repo( _dip.get() ); }
126 ///////////////////////////////////////////////////////////////////
127 // attr value type test
128 ///////////////////////////////////////////////////////////////////
130 detail::IdType LookupAttr::iterator::solvAttrType() const
131 { return _dip ? _dip->key->type : detail::noId; }
133 bool LookupAttr::iterator::solvAttrNumeric() const
135 switch ( solvAttrType() )
137 case REPOKEY_TYPE_U32:
138 case REPOKEY_TYPE_NUM:
139 case REPOKEY_TYPE_CONSTANT:
146 bool LookupAttr::iterator::solvAttrString() const
148 switch ( solvAttrType() )
150 case REPOKEY_TYPE_ID:
151 case REPOKEY_TYPE_IDARRAY:
152 case REPOKEY_TYPE_CONSTANTID:
153 case REPOKEY_TYPE_STR:
154 case REPOKEY_TYPE_DIRSTRARRAY:
161 bool LookupAttr::iterator::solvAttrIdString() const
163 switch ( solvAttrType() )
165 case REPOKEY_TYPE_ID:
166 case REPOKEY_TYPE_IDARRAY:
167 case REPOKEY_TYPE_CONSTANTID:
174 bool LookupAttr::iterator::solvAttrCheckSum() const
176 switch ( solvAttrType() )
178 case REPOKEY_TYPE_MD5:
179 case REPOKEY_TYPE_SHA1:
180 case REPOKEY_TYPE_SHA256:
187 bool LookupAttr::iterator::solvAttrSubEntry() const
189 return solvAttrType() == REPOKEY_TYPE_FLEXARRAY;
192 ///////////////////////////////////////////////////////////////////
193 // Iterate sub-structures.
194 ///////////////////////////////////////////////////////////////////
196 bool LookupAttr::iterator::subEmpty() const
197 { return( subBegin() == subEnd() ); }
199 LookupAttr::size_type LookupAttr::iterator::subSize() const
202 for_( it, subBegin(), subEnd() )
207 LookupAttr::iterator LookupAttr::iterator::subBegin() const
209 if ( ! solvAttrSubEntry() )
212 // remember this position
213 ::dataiterator_setpos( _dip.get() );
215 // setup the new sub iterator
216 scoped_ptr< ::_Dataiterator> dip( new ::Dataiterator );
217 // needed while LookupAttr::iterator::dip_equal does ::memcmp:
218 ::memset( dip.get(), 0, sizeof(::_Dataiterator) );
220 ::dataiterator_init( dip.get(), sat::Pool::instance().get(), 0, SOLVID_POS, 0, 0, 0 );
222 return iterator( dip ); // iterator takes over ownership!
225 LookupAttr::iterator LookupAttr::iterator::subEnd() const
230 LookupAttr::iterator LookupAttr::iterator::subFind( SolvAttr attr_r ) const
232 iterator it = subBegin();
233 if ( attr_r != sat::SolvAttr::allAttr )
235 while ( it != subEnd() && it.inSolvAttr() != attr_r )
241 LookupAttr::iterator LookupAttr::iterator::subFind( const C_Str & attrname_r ) const
243 if ( attrname_r.empty() )
246 std::string subattr( inSolvAttr().asString() );
248 subattr += attrname_r;
249 return subFind( SolvAttr( subattr ) );
252 ///////////////////////////////////////////////////////////////////
253 // attr value retrieval
254 ///////////////////////////////////////////////////////////////////
256 int LookupAttr::iterator::asInt() const
260 switch ( solvAttrType() )
262 case REPOKEY_TYPE_U32:
263 case REPOKEY_TYPE_NUM:
264 case REPOKEY_TYPE_CONSTANT:
272 unsigned LookupAttr::iterator::asUnsigned() const
275 bool LookupAttr::iterator::asBool() const
279 const char * LookupAttr::iterator::c_str() const
283 switch ( solvAttrType() )
285 case REPOKEY_TYPE_ID:
286 case REPOKEY_TYPE_IDARRAY:
287 case REPOKEY_TYPE_CONSTANTID:
288 if ( _dip->data && _dip->data->localpool )
289 return ::stringpool_id2str( &_dip->data->spool, _dip->kv.id ); // in local pool
291 return IdString( _dip->kv.id ).c_str(); // in global pool
294 case REPOKEY_TYPE_STR:
298 case REPOKEY_TYPE_DIRSTRARRAY:
299 return ::repodata_dir2str( _dip->data, _dip->kv.id, _dip->kv.str );
306 std::string LookupAttr::iterator::asString() const
310 switch ( solvAttrType() )
312 case REPOKEY_TYPE_ID:
313 case REPOKEY_TYPE_IDARRAY:
314 case REPOKEY_TYPE_CONSTANTID:
315 case REPOKEY_TYPE_STR:
316 case REPOKEY_TYPE_DIRSTRARRAY:
318 const char * ret( c_str() );
319 return ret ? ret : "";
323 case REPOKEY_TYPE_U32:
324 case REPOKEY_TYPE_NUM:
325 case REPOKEY_TYPE_CONSTANT:
326 return str::numstring( asInt() );
329 case REPOKEY_TYPE_MD5:
330 case REPOKEY_TYPE_SHA1:
331 case REPOKEY_TYPE_SHA256:
333 return asCheckSum().asString();
337 case REPOKEY_TYPE_FLEXARRAY:
339 std::ostringstream str;
341 for_( it, subBegin(), subEnd() )
343 str << " " << it.inSolvAttr() << " = " << it.asString() << endl;
351 return std::string();
354 IdString LookupAttr::iterator::idStr() const
358 switch ( solvAttrType() )
360 case REPOKEY_TYPE_ID:
361 case REPOKEY_TYPE_IDARRAY:
362 case REPOKEY_TYPE_CONSTANTID:
363 return IdString( ::repodata_globalize_id( _dip->data, _dip->kv.id ) );
370 CheckSum LookupAttr::iterator::asCheckSum() const
374 switch ( solvAttrType() )
376 case REPOKEY_TYPE_MD5:
377 return CheckSum::md5( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
380 case REPOKEY_TYPE_SHA1:
381 return CheckSum::sha1( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
384 case REPOKEY_TYPE_SHA256:
385 return CheckSum::sha256( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
392 ///////////////////////////////////////////////////////////////////
393 // internal stuff below
394 ///////////////////////////////////////////////////////////////////
396 LookupAttr::iterator::~iterator()
399 LookupAttr::iterator::iterator()
400 : iterator_adaptor_( 0 )
403 LookupAttr::iterator::iterator( const iterator & rhs )
404 : iterator_adaptor_( cloneFrom( rhs.base() ) )
408 LookupAttr::iterator & LookupAttr::iterator::operator=( const iterator & rhs )
412 _dip.reset( cloneFrom( rhs.base() ) );
413 base_reference() = _dip.get();
418 LookupAttr::iterator::iterator( scoped_ptr< ::_Dataiterator> & dip_r )
419 : iterator_adaptor_( dip_r.get() )
421 _dip.swap( dip_r ); // take ownership!
425 ///////////////////////////////////////////////////////////////////
427 ::_Dataiterator * LookupAttr::iterator::cloneFrom( const ::_Dataiterator * rhs )
431 ::_Dataiterator * ret( new ::_Dataiterator );
436 bool LookupAttr::iterator::dip_equal( const ::_Dataiterator & lhs, const ::_Dataiterator & rhs ) const
438 // requires ::memset in LookupAttr::begin
439 return ::memcmp( &lhs, &rhs, sizeof(::_Dataiterator) ) == 0;
442 detail::IdType LookupAttr::iterator::dereference() const
444 return _dip ? ::repodata_globalize_id( _dip->data, _dip->kv.id )
448 void LookupAttr::iterator::increment()
450 if ( _dip && ! ::dataiterator_step( _dip.get() ) )
453 base_reference() = 0;
457 std::ostream & operator<<( std::ostream & str, const LookupAttr::iterator & obj )
459 const ::_Dataiterator * dip = obj.get();
461 return str << "EndOfQuery";
463 if ( obj.inSolvable() )
464 str << obj.inSolvable();
465 else if ( obj.inRepo() )
468 str << '<' << obj.inSolvAttr()
469 << ">(" << IdString(obj.solvAttrType()) << ") = " << obj.asString();
473 /////////////////////////////////////////////////////////////////
475 ///////////////////////////////////////////////////////////////////
476 /////////////////////////////////////////////////////////////////
478 ///////////////////////////////////////////////////////////////////
480 std::ostream & operator<<( std::ostream & str, const ::_Dataiterator * obj )
482 str << "::_Dataiterator(";
489 str << "|" << zypp::Repository(obj->repo);
490 str << "|" << zypp::sat::Solvable(obj->solvid);
491 str << "|" << zypp::IdString(obj->key->name);
492 str << "|" << zypp::IdString(obj->key->type);
493 str << "|" << obj->repodataid;
494 str << "|" << obj->repoid;
499 ///////////////////////////////////////////////////////////////////