Imported Upstream version 17.10.0
[platform/upstream/libzypp.git] / zypp / sat / SolvableSpec.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/SolvableSpec.cc
10  */
11 #include <iostream>
12
13 #include "zypp/base/LogTools.h"
14 #include "zypp/base/IOStream.h"
15
16 #include "zypp/sat/SolvableSpec.h"
17 #include "zypp/sat/WhatProvides.h"
18
19 using std::endl;
20
21 ///////////////////////////////////////////////////////////////////
22 namespace zypp
23 {
24   ///////////////////////////////////////////////////////////////////
25   namespace sat
26   {
27     ///////////////////////////////////////////////////////////////////
28     /// \class SolvableSpec::Impl
29     /// \brief SolvableSpec implementation.
30     ///////////////////////////////////////////////////////////////////
31     class SolvableSpec::Impl
32     {
33     public:
34       void addIdent( IdString ident_r )
35       {
36         if ( ! ident_r.empty() )
37           _idents.insert( ident_r );
38       }
39
40       void addProvides( Capability provides_r )
41       {
42         if ( ! provides_r.empty() && _provides.insert( provides_r ).second )
43           setDirty();
44       }
45
46
47       void parse( const C_Str & spec_r )
48       {
49         if ( str::hasPrefix( spec_r, "provides:" ) )
50           addProvides( Capability(spec_r.c_str()+9) );
51         else
52           addIdent( IdString(spec_r) );
53       }
54
55
56       bool needed() const
57       { return !_provides.empty(); }
58
59       bool dirty() const
60       { return needed() && !_cache; }
61
62       void setDirty() const
63       { _cache.reset(); }
64
65       const WhatProvides & cache() const
66       {
67         if ( !_cache )
68         {
69           _cache.reset( new WhatProvides( _provides ) );
70         }
71         return *_cache;
72       }
73
74       bool contains( const sat::Solvable & solv_r ) const
75       { return( _idents.count( solv_r.ident() ) || ( needed() && cache().contains( solv_r ) ) ); }
76
77
78       const IdStringSet & idents() const
79       { return _idents; }
80
81       const CapabilitySet & provides() const
82       { return _provides; }
83
84     private:
85       IdStringSet  _idents;
86       CapabilitySet _provides;
87
88       mutable shared_ptr<WhatProvides> _cache;
89
90     private:
91       friend Impl * rwcowClone<Impl>( const Impl * rhs );
92       /** clone for RWCOW_pointer */
93       Impl * clone() const
94       { return new Impl( *this ); }
95     };
96
97     /** \relates SolvableSpec::Impl Stream output */
98     inline std::ostream & operator<<( std::ostream & str, const SolvableSpec::Impl & obj )
99     {
100       str << "SolvableSpec {" << endl
101           << " Idents " << obj.idents() << endl
102           << " Provides " << obj.provides() << endl
103           << "}";
104       return str;
105     }
106
107     ///////////////////////////////////////////////////////////////////
108     //
109     //  CLASS NAME : SolvableSpec
110     //
111     ///////////////////////////////////////////////////////////////////
112
113     SolvableSpec::SolvableSpec()
114       : _pimpl( new Impl )
115     {}
116
117     SolvableSpec::~SolvableSpec()
118     {}
119
120     void SolvableSpec::addIdent( IdString ident_r )
121     { _pimpl->addIdent( ident_r ); }
122
123     void SolvableSpec::addProvides( Capability provides_r )
124     { _pimpl->addProvides( provides_r ); }
125
126     void SolvableSpec::parse( const C_Str & spec_r )
127     { _pimpl->parse( spec_r ); }
128
129     void SolvableSpec::parseFrom( const InputStream & istr_r )
130     {
131       iostr::simpleParseFile( istr_r,
132                               [this]( int num_r, const std::string & line_r )->bool
133                               {
134                                 this->parse( line_r );
135                                 return true;
136                               });
137     }
138
139     void SolvableSpec::splitParseFrom( const C_Str & multispec_r )
140     {
141       std::vector<std::string> v;
142       str::splitEscaped( multispec_r, std::back_inserter( v ), ", \t" );
143       parseFrom( v.begin(), v.end() );
144     }
145
146     bool SolvableSpec::contains( const sat::Solvable & solv_r ) const
147     { return _pimpl->contains( solv_r ) && !solv_r.isKind( ResKind::srcpackage ); }
148
149     bool SolvableSpec::dirty() const
150     { return _pimpl->dirty(); }
151
152     void SolvableSpec::setDirty() const
153     { _pimpl->setDirty(); }
154
155     bool SolvableSpec::containsIdent( const IdString & ident_r ) const
156     { return _pimpl->idents().count( ident_r ); }
157
158     bool SolvableSpec::containsProvides( const Capability & provides_r ) const
159     { return _pimpl->provides().count( provides_r ); }
160
161     std::ostream & operator<<( std::ostream & str, const SolvableSpec & obj )
162     { return str << *obj._pimpl; }
163
164   } // namespace sat
165   ///////////////////////////////////////////////////////////////////
166 } // namespace zypp
167 ///////////////////////////////////////////////////////////////////