comment added
[platform/upstream/libzypp.git] / zypp / ResStatus.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ResStatus.h
10  *
11 */
12 #ifndef ZYPP_RESSTATUS_H
13 #define ZYPP_RESSTATUS_H
14
15 #include <iosfwd>
16
17 #include "zypp/Bit.h"
18
19 ///////////////////////////////////////////////////////////////////
20 namespace zypp
21 { /////////////////////////////////////////////////////////////////
22
23   ///////////////////////////////////////////////////////////////////
24   //
25   //    CLASS NAME : ResStatus
26   //
27   /** Status bitfield.
28    *
29    * \li \c StateField Whether the resolvable is currently installed
30    *        or uninstalled (available).
31    * \li \c EstablishField Established status computed by the solver as
32    *        unneeded (have freshens but none of them trigger)
33    *        satisfied (no freshen or at least one triggered freshen and
34    *        all requires fulfilled)
35    *        or incomplete (no freshen or at least one triggered freshen and
36    *        NOT all requires fulfilled)
37    * \li \c TransactField Wheter to transact this resolvable
38    *        (delete if installed install if uninstalled).
39    * \li \c TransactByField Who triggered the transaction. Transaction
40    *        bit may be reset by higer levels only.
41    * \li \c TransactDetailField Reason why the Resolvable transacts.
42    *        Splitted into \c InstallDetailValue and \c RemoveDetailValue
43    *        dependent on the kind of transaction.
44    *
45   */
46   class ResStatus
47   {
48     friend std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
49     friend bool operator==( const ResStatus & lhs, const ResStatus & rhs );
50
51   public:
52     /** \name BitField range definitions.
53      *
54      * \note Enlarge FieldType if more bit's needed. It's not yet
55      * checked by the compiler.
56      */
57     //@{
58     typedef short FieldType;
59     typedef bit::BitField<FieldType> BitFieldType;
60     // Bit Ranges within FieldType defined by 1st bit and size:
61     typedef bit::Range<FieldType,0,                    1> StateField;
62     typedef bit::Range<FieldType,StateField::end,      2> EstablishField;
63     typedef bit::Range<FieldType,EstablishField::end,  1> TransactField;
64     typedef bit::Range<FieldType,TransactField::end,   2> TransactByField;
65     typedef bit::Range<FieldType,TransactByField::end, 3> TransactDetailField;
66     typedef bit::Range<FieldType,TransactDetailField::end, 2> SolverStateField;
67     // enlarge FieldType if more bit's needed. It's not yet
68     // checked by the compiler.
69     //@}
70   public:
71
72     /** \name Status values.
73      *
74      * Each enum corresponds to a BitField range.
75      * \note Take care that enumerator values actually fit into
76      * the corresponding field. It's not yet checked by the compiler.
77      */
78     //@{
79     enum StateValue
80       {
81         UNINSTALLED = bit::RangeValue<StateField,0>::value,
82         INSTALLED   = bit::RangeValue<StateField,1>::value
83       };
84     enum EstablishValue
85       {
86         UNDETERMINED = bit::RangeValue<EstablishField,0>::value,
87         UNNEEDED     = bit::RangeValue<EstablishField,1>::value, // has freshens, none trigger
88         SATISFIED    = bit::RangeValue<EstablishField,2>::value, // has none or triggered freshens, all requirements fulfilled
89         INCOMPLETE   = bit::RangeValue<EstablishField,3>::value  // installed: has none or triggered freshens, requirements unfulfilled
90       };
91     enum TransactValue
92       {
93         KEEP_STATE = bit::RangeValue<TransactField,0>::value,
94         TRANSACT   = bit::RangeValue<TransactField,1>::value // change state installed <-> uninstalled
95       };
96     enum TransactByValue
97       {
98         SOLVER    = bit::RangeValue<TransactByField,0>::value,
99         APPL_LOW  = bit::RangeValue<TransactByField,1>::value,
100         APPL_HIGH = bit::RangeValue<TransactByField,2>::value,
101         USER      = bit::RangeValue<TransactByField,3>::value
102       };
103
104     enum InstallDetailValue
105       {
106         EXPLICIT_INSTALL = bit::RangeValue<TransactDetailField,0>::value,
107         SOFT_INSTALL     = bit::RangeValue<TransactDetailField,1>::value
108       };
109     enum RemoveDetailValue
110       {
111         EXPLICIT_REMOVE = bit::RangeValue<TransactDetailField,0>::value,
112         SOFT_REMOVE     = bit::RangeValue<TransactDetailField,1>::value,
113         DUE_TO_OBSOLETE = bit::RangeValue<TransactDetailField,2>::value,
114         DUE_TO_UNLINK   = bit::RangeValue<TransactDetailField,3>::value,
115         DUE_TO_UPGRADE  = bit::RangeValue<TransactDetailField,4>::value
116       };
117     enum SolverStateValue
118       {
119         NORMAL     = bit::RangeValue<SolverStateField,0>::value, // default, notthing special
120         SEEN       = bit::RangeValue<SolverStateField,1>::value, // already seen during ResolverUpgrade
121         IMPOSSIBLE = bit::RangeValue<SolverStateField,2>::value  // impossible to install
122       };
123     //@}
124
125   public:
126
127     /** Default ctor. */
128     ResStatus();
129
130     /** Ctor setting the initial . */
131     ResStatus( bool isInstalled_r );
132
133     /** Dtor. */
134     ~ResStatus();
135
136     /** Debug helper returning the bitfield.
137      * It's save to expose the bitfield, as it can't be used to
138      * recreate a ResStatus. So it is not possible to bypass
139      * transition rules.
140     */
141     BitFieldType bitfield() const
142     { return _bitfield; }
143
144   public:
145
146     bool isInstalled() const
147     { return fieldValueIs<StateField>( INSTALLED ); }
148
149     bool isUninstalled() const
150     { return fieldValueIs<StateField>( UNINSTALLED ); }
151
152   public:
153
154     bool staysInstalled() const
155     { return isInstalled() && !transacts(); }
156
157     bool wasInstalled() const { return staysInstalled(); }      //for old status
158
159     bool isToBeInstalled() const
160     { return isUninstalled() && transacts(); }
161
162     bool staysUninstalled() const
163     { return isUninstalled() && !transacts(); }
164
165     bool wasUninstalled() const { return staysUninstalled(); }  // for old status
166
167     bool isToBeUninstalled() const
168     { return isInstalled() && transacts(); }
169
170     bool isUndetermined() const
171     { return fieldValueIs<EstablishField>( UNDETERMINED ); }
172
173     bool isUnneeded() const
174     { return isUninstalled() && fieldValueIs<EstablishField>( UNNEEDED ); }
175
176     bool isSatisfied() const
177     { return isUninstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
178
179     bool isComplete () const
180     { return isInstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
181
182     bool isIncomplete() const
183     { return isInstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
184
185     bool isNeeded() const
186     { return isUninstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
187
188     bool transacts() const
189     { return fieldValueIs<TransactField>( TRANSACT ); }
190
191     bool isBySolver() const
192     { return fieldValueIs<TransactByField>( SOLVER ); }
193
194     bool isByApplLow() const
195     { return fieldValueIs<TransactByField>( APPL_LOW ); }
196
197     bool isByApplHigh() const
198     { return fieldValueIs<TransactByField>( APPL_HIGH ); }
199
200     bool isByUser() const
201     { return fieldValueIs<TransactByField>( USER ); }
202
203     bool isToBeUninstalledDueToObsolete () const
204     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
205
206     bool isToBeUninstalledDueToUnlink() const
207     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UNLINK ); }
208
209     bool isToBeUninstalledDueToUpgrade() const
210     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
211
212     bool isToBeInstalledSoft () const
213     { return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
214
215     bool isToBeUninstalledSoft () const
216     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
217
218   public:
219
220     //------------------------------------------------------------------------
221     // get/set functions, returnig \c true if requested status change
222     // was successfull (i.e. leading to the desired transaction).
223     // If a lower level (e.g.SOLVER) wants to transact, but it's
224     // already set by a higher level, \c true should be returned.
225     // Removing a higher levels transaction bit should fail.
226     //
227     // The may functions checks only, if the action would return true
228     // if it is called.
229
230     bool setTransact (bool val_r, TransactByValue causer)
231     {
232         if (!isGreaterThan<TransactByField>( causer )) {
233             fieldValueAssign<TransactField>( val_r ? TRANSACT : KEEP_STATE );
234             fieldValueAssign<TransactByField>( causer );                        // remember the causer
235             return true;
236         } else if (fieldValueIs<TransactField>(val_r ? TRANSACT : KEEP_STATE)) {
237             return true; // is already set
238         } else {
239             return false;
240         }
241     }
242
243     bool maySetTransact (bool val_r, TransactByValue causer)
244     {
245         bit::BitField<FieldType> savBitfield = _bitfield;
246         bool ret = setTransact (val_r, causer);
247         _bitfield = savBitfield;
248         return ret;
249     }
250
251     bool setToBeInstalled (TransactByValue causer)
252     {
253       if (isInstalled()) return false;
254       return setTransact (true, causer);
255     }
256
257     bool maySetToBeInstalled (TransactByValue causer)
258     {
259         bit::BitField<FieldType> savBitfield = _bitfield;
260         bool ret = setToBeInstalled (causer);
261         _bitfield = savBitfield;
262         return ret;
263     }
264
265     bool setToBeUninstalled (TransactByValue causer)
266     {
267       if (!isInstalled()) return false;
268       return setTransact (true, causer);
269     }
270
271     bool maySetToBeUninstalled (TransactByValue causer)
272     {
273         bit::BitField<FieldType> savBitfield = _bitfield;
274         bool ret = setToBeUninstalled (causer);
275         _bitfield = savBitfield;
276         return ret;
277     }
278
279     //------------------------------------------------------------------------
280     // *** These are only for the Resolver ***
281
282     bool setToBeUninstalledDueToUnlink ( )
283     {
284       if (!setToBeUninstalled (SOLVER)) return false;
285       fieldValueAssign<TransactDetailField>(DUE_TO_UNLINK);
286       return true;
287     }
288
289     bool setToBeUninstalledDueToObsolete ( )
290     {
291       if (!setToBeUninstalled (SOLVER)) return false;
292       fieldValueAssign<TransactDetailField>(DUE_TO_OBSOLETE);
293       return true;
294     }
295
296     bool setToBeUninstalledDueToUpgrade ( )
297     {
298       if (!setToBeUninstalled (SOLVER)) return false;
299       fieldValueAssign<TransactDetailField>(DUE_TO_UPGRADE);
300       return true;
301     }
302
303     bool setToBeInstalledSoft ( )
304     {
305       if (!setToBeInstalled(SOLVER)) return false;
306       fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
307       return true;
308     }
309
310     bool setToBeUninstalledSoft ( )
311     {
312       if (!setToBeUninstalled(SOLVER)) return false;
313       fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
314       return true;
315     }
316
317     bool isSoftInstall () {
318         return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
319     }
320
321     bool isSoftUninstall () {
322         return fieldValueIs<TransactDetailField> (SOFT_REMOVE);
323     }
324
325     bool setSoftInstall (bool flag) {
326         fieldValueAssign<TransactDetailField>(flag?SOFT_INSTALL:0);
327         return true;
328     }
329
330     bool setSoftUninstall (bool flag) {
331         fieldValueAssign<TransactDetailField>(flag?SOFT_REMOVE:0);
332         return true;
333     }
334
335     bool setUndetermined ()
336     {
337       fieldValueAssign<EstablishField>(UNDETERMINED);
338       return true;
339     }
340
341     bool setUnneeded ()
342     {
343       fieldValueAssign<EstablishField>(UNNEEDED);
344       return true;
345     }
346
347     bool setSatisfied ()
348     {
349       fieldValueAssign<EstablishField>(SATISFIED);
350       return true;
351     }
352
353     bool setIncomplete ()
354     {
355       fieldValueAssign<EstablishField>(INCOMPLETE);
356       return true;
357     }
358
359     bool isSeen () const
360     { return fieldValueIs<SolverStateField>( SEEN ); }
361
362     bool isImpossible () const
363     { return fieldValueIs<SolverStateField>( IMPOSSIBLE ); }
364
365     bool setSeen (bool value)
366     {
367       fieldValueAssign<SolverStateField>( value ? SEEN : NORMAL );
368       return true;
369     }
370
371     bool setImpossible (bool value)
372     {
373       fieldValueAssign<SolverStateField>( value ? IMPOSSIBLE : NORMAL );
374       return true;
375     }
376
377     bool setStatus (ResStatus status)
378     {
379         if ( ((isInstalled() && status.isInstalled())
380                || (isUninstalled() && status.isUninstalled()))
381              && _bitfield.value<TransactByField>() <=  status._bitfield.value<TransactByField>() // regarding priority
382              )
383         {
384             _bitfield = status._bitfield;
385             return true;
386         }
387         else
388         {
389             // The type is not correct ( system/source)
390             // or has not enough priority
391             return false;
392         }
393     }
394
395     /** \name Builtin ResStatus constants. */
396     //@{
397     static const ResStatus toBeInstalled;
398     static const ResStatus toBeInstalledSoft;
399     static const ResStatus toBeUninstalled;
400     static const ResStatus toBeUninstalledSoft;
401     static const ResStatus toBeUninstalledDueToUnlink;
402     static const ResStatus toBeUninstalledDueToObsolete;
403     static const ResStatus toBeUninstalledDueToUpgrade;
404     static const ResStatus installed;   // installed, status after successful target 'install' commit
405     static const ResStatus uninstalled; // uninstalled, status after successful target 'uninstall' commit
406     static const ResStatus satisfied;   // uninstalled, satisfied
407     static const ResStatus complete;    // installed, satisfied
408     static const ResStatus unneeded;    // uninstalled, unneeded
409     static const ResStatus needed;      // uninstalled, incomplete
410     static const ResStatus incomplete;  // installed, incomplete
411     static const ResStatus impossible;  // uninstallable
412     //@}
413
414   private:
415     /** Ctor for intialization of builtin constants. */
416     ResStatus( StateValue s,
417                EstablishValue e     = UNDETERMINED,
418                TransactValue t      = KEEP_STATE,
419                InstallDetailValue i = EXPLICIT_INSTALL,
420                RemoveDetailValue r  = EXPLICIT_REMOVE,
421                SolverStateValue ssv = NORMAL );
422
423     /** Return whether the corresponding Field has value \a val_r.
424     */
425     template<class _Field>
426       bool fieldValueIs( FieldType val_r ) const
427       { return _bitfield.isEqual<_Field>( val_r ); }
428
429     /** Set the corresponding Field to value \a val_r.
430     */
431     template<class _Field>
432       void fieldValueAssign( FieldType val_r )
433       { _bitfield.assign<_Field>( val_r ); }
434
435     /** compare two values.
436     */
437     template<class _Field>
438       bool isGreaterThan( FieldType val_r )
439           { return _bitfield.value<_Field>() > val_r; }
440
441   private:
442     BitFieldType _bitfield;
443   };
444   ///////////////////////////////////////////////////////////////////
445
446   /** \relates ResStatus Stream output */
447   std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
448
449   /** \relates ResStatus */
450   inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
451   { return lhs._bitfield == rhs._bitfield; }
452
453   /** \relates ResStatus */
454   inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
455   { return ! (lhs == rhs); }
456
457   /////////////////////////////////////////////////////////////////
458 } // namespace zypp
459 ///////////////////////////////////////////////////////////////////
460 #endif // ZYPP_RESSTATUS_H