dcfb0014c34a8e89b3b75b4e265645cfc9d7c9f8
[platform/upstream/libzypp.git] / zypp / sat / LookupAttr.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/LookupAttr.cc
10  *
11 */
12 #include <cstring>
13 #include <iostream>
14 #include "zypp/base/Logger.h"
15
16 #include "zypp/sat/detail/PoolImpl.h"
17
18 #include "zypp/sat/LookupAttr.h"
19
20 using std::endl;
21
22 ///////////////////////////////////////////////////////////////////
23 namespace zypp
24 { /////////////////////////////////////////////////////////////////
25   ///////////////////////////////////////////////////////////////////
26   namespace sat
27   { /////////////////////////////////////////////////////////////////
28
29     LookupAttr::iterator LookupAttr::begin() const
30     {
31       if ( _attr == SolvAttr::noAttr )
32         return iterator();
33
34       scoped_ptr< ::_Dataiterator> dip( new ::Dataiterator );
35       // needed while LookupAttr::iterator::dip_equal does ::memcmp:
36       ::memset( dip.get(), 0, sizeof(::_Dataiterator) );
37       bool chain = false;
38
39       if ( _solv )
40         ::dataiterator_init( dip.get(), _solv.repository().id(), _solv.id(), _attr.id(), 0, SEARCH_NO_STORAGE_SOLVABLE );
41       else if ( _repo )
42         ::dataiterator_init( dip.get(), _repo.id(), 0, _attr.id(), 0, SEARCH_NO_STORAGE_SOLVABLE );
43       else if ( ! sat::Pool::instance().reposEmpty() )
44       {
45         ::dataiterator_init( dip.get(), sat::Pool::instance().reposBegin()->id(), 0, _attr.id(), 0, SEARCH_NO_STORAGE_SOLVABLE );
46         chain = true;
47       }
48       else
49         return iterator();
50
51       return iterator( dip, chain ); // iterator takes over ownership!
52     }
53
54     LookupAttr::iterator LookupAttr::end() const
55     {
56       return iterator();
57     }
58
59     std::ostream & operator<<( std::ostream & str, const LookupAttr & obj )
60     {
61       if ( obj.attr() == SolvAttr::noAttr )
62         return str << "search nothing";
63
64       if ( obj.attr() )
65         str << "seach " << obj.attr() << " in ";
66       else
67         str << "seach ALL in ";
68
69       if ( obj.solvable() )
70         return str << obj.solvable();
71       if ( obj.repo() )
72         return str << obj.repo();
73       return str << "pool";
74     }
75
76     std::ostream & dumpOn( std::ostream & str, const LookupAttr & obj )
77     {
78       str << obj << endl;
79       for_( it, obj.begin(), obj.end() )
80       {
81         str << "  " << it << endl;
82       }
83       return str << "<EndOfSerach>";
84     }
85
86     ///////////////////////////////////////////////////////////////////
87     //
88     //  CLASS NAME : LookupAttr::iterator
89     //
90     ///////////////////////////////////////////////////////////////////
91
92     Repository LookupAttr::iterator::inRepo() const
93     { return Repository( _dip->repo ); }
94
95     Solvable LookupAttr::iterator::inSolvable() const
96     { return Solvable( _dip->solvid ); }
97
98     SolvAttr LookupAttr::iterator::inSolvAttr() const
99     { return SolvAttr( _dip->key->name ); }
100
101     detail::IdType LookupAttr::iterator::solvAttrType() const
102     { return _dip->key->type; }
103
104     void LookupAttr::iterator::nextSkipSolvAttr()
105     { ::dataiterator_skip_attribute( _dip.get() ); }
106
107     void LookupAttr::iterator::nextSkipSolvable()
108     { ::dataiterator_skip_solvable( _dip.get() ); }
109
110     void LookupAttr::iterator::nextSkipRepo()
111     { ::dataiterator_skip_repo( _dip.get() ); }
112
113     ///////////////////////////////////////////////////////////////////
114     // internal stuff below
115     ///////////////////////////////////////////////////////////////////
116
117     ::_Dataiterator * LookupAttr::iterator::cloneFrom( const ::_Dataiterator * rhs )
118     {
119       if ( ! rhs )
120         return 0;
121       ::_Dataiterator * ret( new ::_Dataiterator );
122       *ret = *rhs;
123       return ret;
124     }
125
126     bool LookupAttr::iterator::dip_equal( const ::_Dataiterator & lhs, const ::_Dataiterator & rhs ) const
127     {
128       // requires ::memset in LookupAttr::begin
129       return ::memcmp( &lhs, &rhs, sizeof(::_Dataiterator) ) == 0;
130     }
131
132     detail::IdType LookupAttr::iterator::dereference() const
133     {
134       return _dip ? ::repodata_globalize_id( _dip->data, _dip->kv.id )
135                   : detail::noId;
136     }
137
138     void LookupAttr::iterator::increment()
139     {
140       if ( _dip && ! ::dataiterator_step( _dip.get() ) )
141       {
142         bool haveNext = false;
143         if ( _chainRepos )
144         {
145           Repository nextRepo( inRepo().nextInPool() );
146           if ( nextRepo )
147           {
148             ::dataiterator_jump_to_repo( _dip.get(), nextRepo.get() );
149             haveNext = ::dataiterator_step( _dip.get() );
150           }
151         }
152         if ( ! haveNext )
153         {
154           _dip.reset();
155           base_reference() = 0;
156         }
157       }
158     }
159
160     std::ostream & operator<<( std::ostream & str, const LookupAttr::iterator & obj )
161     {
162       const ::_Dataiterator * dip = obj.get();
163       if ( ! dip )
164         return str << "EndOfQuery" << endl;
165
166       str << obj.inSolvable()
167           << '<' << obj.inSolvAttr()
168           << "> = " << obj.solvAttrType()
169           << "(" <<  dip->kv.id << ")" << (dip->data && dip->data->localpool ? "*" : "" );
170       return str;
171     }
172
173     /////////////////////////////////////////////////////////////////
174   } // namespace sat
175   ///////////////////////////////////////////////////////////////////
176   /////////////////////////////////////////////////////////////////
177 } // namespace zypp
178 ///////////////////////////////////////////////////////////////////