4c3c75c2690657dbc79a343dfc99a603a2aa41c0
[platform/upstream/libzypp.git] / zypp / sat / WhatProvides.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/WhatProvides.cc
10  *
11 */
12 #include <iostream>
13
14 #include "zypp/base/LogTools.h"
15 #include "zypp/sat/WhatProvides.h"
16 #include "zypp/sat/detail/PoolImpl.h"
17
18 using std::endl;
19
20 ///////////////////////////////////////////////////////////////////
21 namespace zypp
22 { /////////////////////////////////////////////////////////////////
23   ///////////////////////////////////////////////////////////////////
24   namespace sat
25   { /////////////////////////////////////////////////////////////////
26
27     ///////////////////////////////////////////////////////////////////
28     //
29     //  CLASS NAME : WhatProvides::Impl
30     //
31     /** WhatProvides implementation date.
32      * Stores the offset into a O terminated Id array. Per default
33      * the satsolvers whatprovidesdata, otherwise private data.
34      *
35      * As the satsolvers whatprovidesdata might be realocated
36      * while iterating a result, the iterator takes an
37      * <tt>const IdType *const*</tt>. Thats why we explicitly
38      * provide _private and pass its adress to the iterator,
39      * even if private data are not reallocated.
40      */
41     class WhatProvides::Impl : protected detail::PoolMember
42     {
43       public:
44         Impl()
45         : _offset( 0 ), _private( 0 )
46         {}
47
48         Impl( unsigned offset_r )
49         : _offset( offset_r ), _private( 0 )
50         {}
51
52         Impl( const std::tr1::unordered_set<detail::IdType> & ids_r )
53         : _offset( 0 ), _private( 0 )
54         {
55            // use private data to store the result (incl. trailing NULL)
56           _pdata.reserve( ids_r.size()+1 );
57           _pdata.insert( _pdata.begin(), ids_r.begin(), ids_r.end() );
58           _pdata.push_back( detail::noId );
59
60           _private = &_pdata.front(); // ptr to 1st element
61         }
62
63       public:
64         unsigned                         _offset;
65         const detail::IdType *           _private;
66
67       private:
68         std::vector<sat::detail::IdType> _pdata;
69     };
70     ///////////////////////////////////////////////////////////////////
71
72     ///////////////////////////////////////////////////////////////////
73     namespace
74     { /////////////////////////////////////////////////////////////////
75
76       /** WhatProvides ctor helper collecting providers from Capabilies. */
77       template <class Iterator>
78       void collectProviders( Iterator begin_r, Iterator end_r, std::tr1::unordered_set<detail::IdType> & collect_r )
79       {
80         for_( it, begin_r, end_r )
81         {
82           WhatProvides providers( *it );
83           for_( prv, providers.begin(), providers.end() )
84           {
85             collect_r.insert( prv->id() );
86           }
87         }
88       }
89
90       /////////////////////////////////////////////////////////////////
91     } //namespace
92     ///////////////////////////////////////////////////////////////////
93
94     WhatProvides::WhatProvides()
95     {}
96
97     WhatProvides::WhatProvides( Capability cap_r )
98     {
99       unsigned res( myPool().whatProvides( cap_r ) );
100       if ( myPool().whatProvidesData( res ) )
101       {
102         _pimpl.reset( new Impl( res ) );
103       }
104       // else: no Impl for empty result.
105     }
106
107     WhatProvides::WhatProvides( Capabilities caps_r )
108     {
109       std::tr1::unordered_set<detail::IdType> ids;
110       collectProviders( caps_r.begin(), caps_r.end(), ids );
111       if ( ! ids.empty() )
112       {
113         _pimpl.reset( new Impl( ids ) );
114       }
115       // else: no Impl for empty result.
116    }
117
118     WhatProvides::WhatProvides( const CapabilitySet & caps_r )
119     {
120       std::tr1::unordered_set<detail::IdType> ids;
121       collectProviders( caps_r.begin(), caps_r.end(), ids );
122       if ( ! ids.empty() )
123       {
124         _pimpl.reset( new Impl( ids ) );
125       }
126       // else: no Impl for empty result.
127    }
128
129     bool WhatProvides::empty() const
130     {
131       return !_pimpl; // Ctor asserts no Impl for empty result.
132     }
133
134     WhatProvides::size_type WhatProvides::size() const
135     {
136       if ( !_pimpl )
137         return 0;
138
139       size_type count = 0;
140       for_( it, begin(), end() )
141         ++count;
142       return count;
143     }
144
145     WhatProvides::const_iterator WhatProvides::begin() const
146     {
147       if ( !_pimpl )
148         return const_iterator();
149
150       if ( _pimpl->_private )
151         return const_iterator( _pimpl->_private );
152
153       // for satsolvers index use one more indirection, as it might get relocated.
154       return const_iterator( &myPool().getPool()->whatprovidesdata, _pimpl->_offset );
155     }
156
157     /******************************************************************
158     **
159     **  FUNCTION NAME : operator<<
160     **  FUNCTION TYPE : std::ostream &
161     */
162     std::ostream & operator<<( std::ostream & str, const WhatProvides & obj )
163     {
164       return dumpRange( str << "(" << obj.size() << ")", obj.begin(), obj.end() );
165     }
166
167     ///////////////////////////////////////////////////////////////////
168     namespace detail
169     { /////////////////////////////////////////////////////////////////
170
171       std::ostream & operator<<( std::ostream & str, const WhatProvidesIterator & obj )
172       {
173         str << str::form( "[%5u]", obj._offset );
174         str << str::form( "<%p(%p)>", obj.base_reference(), &obj.base_reference() );
175         str << str::form( "<%p(%p)>", obj._baseRef, (obj._baseRef ? *obj._baseRef : 0) );
176         return str;
177       }
178
179       /////////////////////////////////////////////////////////////////
180     } //namespace detail
181     ///////////////////////////////////////////////////////////////////
182
183     /////////////////////////////////////////////////////////////////
184   } // namespace sat
185   ///////////////////////////////////////////////////////////////////
186   /////////////////////////////////////////////////////////////////
187 } // namespace zypp
188 ///////////////////////////////////////////////////////////////////