1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ResStatus.h
12 #ifndef ZYPP_RESSTATUS_H
13 #define ZYPP_RESSTATUS_H
19 ///////////////////////////////////////////////////////////////////
21 { /////////////////////////////////////////////////////////////////
23 ///////////////////////////////////////////////////////////////////
25 // CLASS NAME : ResStatus
29 * \li \c StateField Whether the resolvable is or uninstalled (available).
30 * \li \c EstablishField Established status computed by the solver as
31 * unneeded (have freshens but none of them trigger)
32 * satisfied (no freshen or at least one triggered freshen and
33 * all requires fulfilled)
34 * or incomplete (no freshen or at least one triggered freshen and
35 * NOT all requires fulfilled)
36 * \li \c TransactField Wheter to transact this resolvable
37 * (delete if installed install if uninstalled).
38 * In case the resolvable is locked, only USER may modify the
40 * \li \c TransactByField Who triggered the transaction. Transaction
41 * bit may be reset by higer levels only.
42 * \li \c TransactDetailField Reason why the Resolvable transacts.
43 * Splitted into \c InstallDetailValue and \c RemoveDetailValue
44 * dependent on the kind of transaction.
49 friend std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
50 friend bool operator==( const ResStatus & lhs, const ResStatus & rhs );
53 /** \name BitField range definitions.
55 * \note Enlarge FieldType if more bit's needed. It's not yet
56 * checked by the compiler.
59 typedef uint16_t FieldType;
60 typedef bit::BitField<FieldType> BitFieldType;
61 // Bit Ranges within FieldType defined by 1st bit and size:
62 typedef bit::Range<FieldType,0, 1> StateField;
63 typedef bit::Range<FieldType,StateField::end, 2> EstablishField;
64 typedef bit::Range<FieldType,EstablishField::end, 2> TransactField;
65 typedef bit::Range<FieldType,TransactField::end, 2> TransactByField;
66 typedef bit::Range<FieldType,TransactByField::end, 3> TransactDetailField;
67 typedef bit::Range<FieldType,TransactDetailField::end, 2> SolverStateField;
68 typedef bit::Range<FieldType,SolverStateField::end, 1> LicenceConfirmedField;
69 // enlarge FieldType if more bit's needed. It's not yet
70 // checked by the compiler.
74 /** \name Status values.
76 * Each enum corresponds to a BitField range.
77 * \note Take care that enumerator values actually fit into
78 * the corresponding field. It's not yet checked by the compiler.
83 UNINSTALLED = bit::RangeValue<StateField,0>::value,
84 INSTALLED = bit::RangeValue<StateField,1>::value
88 UNDETERMINED = bit::RangeValue<EstablishField,0>::value,
89 UNNEEDED = bit::RangeValue<EstablishField,1>::value, // has freshens, none trigger
90 SATISFIED = bit::RangeValue<EstablishField,2>::value, // has none or triggered freshens, all requirements fulfilled
91 INCOMPLETE = bit::RangeValue<EstablishField,3>::value // installed: has none or triggered freshens, requirements unfulfilled
95 KEEP_STATE = bit::RangeValue<TransactField,0>::value,
96 LOCKED = bit::RangeValue<TransactField,1>::value, // locked, must not transact
97 TRANSACT = bit::RangeValue<TransactField,2>::value // transact according to state
101 SOLVER = bit::RangeValue<TransactByField,0>::value,
102 APPL_LOW = bit::RangeValue<TransactByField,1>::value,
103 APPL_HIGH = bit::RangeValue<TransactByField,2>::value,
104 USER = bit::RangeValue<TransactByField,3>::value
109 /** Detail for no transact, i.e. reset any Install/RemoveDetailValue. */
110 NO_DETAIL = bit::RangeValue<TransactDetailField,0>::value,
113 enum InstallDetailValue
115 EXPLICIT_INSTALL = bit::RangeValue<TransactDetailField,0>::value,
116 SOFT_INSTALL = bit::RangeValue<TransactDetailField,1>::value
118 enum RemoveDetailValue
120 EXPLICIT_REMOVE = bit::RangeValue<TransactDetailField,0>::value,
121 SOFT_REMOVE = bit::RangeValue<TransactDetailField,1>::value,
122 DUE_TO_OBSOLETE = bit::RangeValue<TransactDetailField,2>::value,
123 DUE_TO_UNLINK = bit::RangeValue<TransactDetailField,3>::value,
124 DUE_TO_UPGRADE = bit::RangeValue<TransactDetailField,4>::value
126 enum SolverStateValue
128 NORMAL = bit::RangeValue<SolverStateField,0>::value, // default, notthing special
129 SEEN = bit::RangeValue<SolverStateField,1>::value, // already seen during ResolverUpgrade
130 IMPOSSIBLE = bit::RangeValue<SolverStateField,2>::value // impossible to install
133 enum LicenceConfirmedValue
135 LICENCE_UNCONFIRMED = bit::RangeValue<LicenceConfirmedField,0>::value,
136 LICENCE_CONFIRMED = bit::RangeValue<LicenceConfirmedField,1>::value
145 /** Ctor setting the initial . */
146 ResStatus( bool isInstalled_r );
151 /** Debug helper returning the bitfield.
152 * It's save to expose the bitfield, as it can't be used to
153 * recreate a ResStatus. So it is not possible to bypass
156 BitFieldType bitfield() const
157 { return _bitfield; }
161 bool isLicenceConfirmed() const
162 { return fieldValueIs<LicenceConfirmedField>( LICENCE_CONFIRMED ); }
164 void setLicenceConfirmed( bool toVal_r = true )
165 { fieldValueAssign<LicenceConfirmedField>( toVal_r ? LICENCE_CONFIRMED : LICENCE_UNCONFIRMED ); }
168 // These two are IMMUTABLE!
170 bool isInstalled() const
171 { return fieldValueIs<StateField>( INSTALLED ); }
173 bool isUninstalled() const
174 { return fieldValueIs<StateField>( UNINSTALLED ); }
178 bool staysInstalled() const
179 { return isInstalled() && !transacts(); }
181 bool wasInstalled() const { return staysInstalled(); } //for old status
183 bool isToBeInstalled() const
184 { return isUninstalled() && transacts(); }
186 bool staysUninstalled() const
187 { return isUninstalled() && !transacts(); }
189 bool wasUninstalled() const { return staysUninstalled(); } // for old status
191 bool isToBeUninstalled() const
192 { return isInstalled() && transacts(); }
194 bool isUndetermined() const
195 { return fieldValueIs<EstablishField>( UNDETERMINED ); }
197 bool isEstablishedUneeded() const
198 { return fieldValueIs<EstablishField>( UNNEEDED ); }
200 bool isEstablishedSatisfied() const
201 { return fieldValueIs<EstablishField>( SATISFIED ); }
203 bool isEstablishedIncomplete() const
204 { return fieldValueIs<EstablishField>( INCOMPLETE ); }
206 bool isUnneeded() const
207 { return isUninstalled() && fieldValueIs<EstablishField>( UNNEEDED ); }
209 bool isSatisfied() const
210 { return isUninstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
212 bool isComplete () const
213 { return isInstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
215 bool isIncomplete() const
216 { return isInstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
218 bool isNeeded() const
219 { return isUninstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
221 bool isLocked() const
222 { return fieldValueIs<TransactField>( LOCKED ); }
225 { return fieldValueIs<TransactField>( KEEP_STATE ); }
227 bool transacts() const
228 { return fieldValueIs<TransactField>( TRANSACT ); }
230 TransactValue getTransactValue() const
231 { return (TransactValue)_bitfield.value<TransactField>(); }
233 bool isBySolver() const
234 { return fieldValueIs<TransactByField>( SOLVER ); }
236 bool isByApplLow() const
237 { return fieldValueIs<TransactByField>( APPL_LOW ); }
239 bool isByApplHigh() const
240 { return fieldValueIs<TransactByField>( APPL_HIGH ); }
242 bool isByUser() const
243 { return fieldValueIs<TransactByField>( USER ); }
245 TransactByValue getTransactByValue() const
246 { return (TransactByValue)_bitfield.value<TransactByField>(); }
248 bool isToBeUninstalledDueToObsolete () const
249 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
251 bool isToBeUninstalledDueToUnlink() const
252 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UNLINK ); }
254 bool isToBeUninstalledDueToUpgrade() const
255 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
257 bool isToBeInstalledSoft () const
258 { return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
260 bool isToBeInstalledNotSoft () const
261 { return isToBeInstalled() && !fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
264 bool isToBeUninstalledSoft () const
265 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
269 //------------------------------------------------------------------------
270 // get/set functions, returnig \c true if requested status change
271 // was successfull (i.e. leading to the desired transaction).
272 // If a lower level (e.g.SOLVER) wants to transact, but it's
273 // already set by a higher level, \c true should be returned.
274 // Removing a higher levels transaction bit should fail.
276 // The may functions checks only, if the action would return true
279 /** Set TransactValue.
280 * Convenience to set TransactValue from enum.
282 bool setTransactValue( TransactValue newVal_r, TransactByValue causer_r )
287 return setTransact( false, causer_r );
290 return setLock( true, causer_r );
293 return setTransact( true, causer_r );
299 bool maySetTransactValue( TransactValue newVal_r, TransactByValue causer_r )
301 bit::BitField<FieldType> savBitfield = _bitfield;
302 bool ret = setTransactValue( newVal_r, causer_r );
303 _bitfield = savBitfield;
307 /** Apply a lock (prevent transaction).
308 * Currently by USER only, but who knows... Set LOCKED
309 * from KEEP_STATE to be shure all transaction details
310 * were reset properly.
312 bool setLock( bool toLock_r, TransactByValue causer_r )
314 if ( toLock_r == isLocked() )
316 // we're already in the desired state, but in case of
317 // LOCKED, remember a superior causer.
318 if ( isLocked() && isLessThan<TransactByField>( causer_r ) )
319 fieldValueAssign<TransactByField>( causer_r );
322 // Here: Lock status is to be changed:
323 if ( causer_r != USER )
325 // Setting no transact removes an existing lock,
326 // or brings this into KEEP_STATE, and we apply the lock.
327 if ( ! setTransact( false, causer_r ) )
330 fieldValueAssign<TransactField>( LOCKED );
331 fieldValueAssign<TransactByField>( causer_r );
333 fieldValueAssign<TransactField>( KEEP_STATE );
334 fieldValueAssign<TransactByField>( SOLVER ); // reset to lowest causer
335 // in order to distinguish from keep_state_by_user
340 bool maySetLock( bool to_r, TransactByValue causer_r )
342 bit::BitField<FieldType> savBitfield = _bitfield;
343 bool ret = setLock( to_r, causer_r );
344 _bitfield = savBitfield;
348 /** Toggle between TRANSACT and KEEP_STATE.
349 * LOCKED state means KEEP_STATE. But in contrary to KEEP_STATE,
350 * LOCKED state is immutable for \a causer_r less than TransactByValue.
351 * KEEP_STATE may be canged by any \a causer_r.
353 bool setTransact( bool toTansact_r, TransactByValue causer_r )
355 if ( toTansact_r == transacts() )
357 // we're already in the desired state, but in case of
358 // TRANSACT, remember a superior causer.
359 if ( transacts() && isLessThan<TransactByField>( causer_r ) )
361 fieldValueAssign<TransactByField>( causer_r );
362 // ??? adapt TransactDetailField ?
366 // Here: transact status is to be changed:
367 if ( ! fieldValueIs<TransactField>( KEEP_STATE )
368 && isGreaterThan<TransactByField>( causer_r ) )
373 fieldValueAssign<TransactField>( TRANSACT );
374 // ??? adapt TransactDetailField ?
378 fieldValueAssign<TransactField>( KEEP_STATE );
379 fieldValueAssign<TransactDetailField>( NO_DETAIL );
381 fieldValueAssign<TransactByField>( causer_r );
385 bool maySetTransact( bool val_r, TransactByValue causer )
387 bit::BitField<FieldType> savBitfield = _bitfield;
388 bool ret = setTransact (val_r, causer);
389 _bitfield = savBitfield;
394 bool setSoftLock( TransactByValue causer_r )
396 if ( ! setTransact( false, causer_r ) )
398 if ( fieldValueIs<TransactField>( KEEP_STATE )
399 && isLessThan<TransactByField>( causer_r ) )
400 fieldValueAssign<TransactByField>( causer_r );
404 /** Not the same as setTransact( false ).
406 bool resetTransact( TransactByValue causer_r )
408 if ( ! setTransact( false, causer_r ) )
410 if ( fieldValueIs<TransactField>( KEEP_STATE ) )
411 fieldValueAssign<TransactByField>( SOLVER );
415 /** Soft toggle between TRANSACT and KEEP_STATE.
416 * Similar to setTransact, but leaving KEEP_STATE also requires
417 * a superior \a causerLimit_r. So this is a kind of soft lock.
419 * // SOLVER wants to set TRANSACT, iff KEEP_STATE is
420 * // not superior to APPL_LOW.
421 * setSoftTransact( true, SOLVER, APPL_LOW );
424 bool setSoftTransact( bool toTansact_r, TransactByValue causer_r,
425 TransactByValue causerLimit_r )
427 if ( fieldValueIs<TransactField>( KEEP_STATE )
428 && toTansact_r != transacts()
429 && isGreaterThan<TransactByField>( causerLimit_r ) )
431 // any transact status change requires a superior causer.
434 return setTransact( toTansact_r, causer_r );
437 bool setSoftTransact( bool toTansact_r, TransactByValue causer_r )
438 { return setSoftTransact( toTansact_r, causer_r, causer_r ); }
440 bool maySetSoftTransact( bool val_r, TransactByValue causer,
441 TransactByValue causerLimit_r )
443 bit::BitField<FieldType> savBitfield = _bitfield;
444 bool ret = setSoftTransact( val_r, causer, causerLimit_r );
445 _bitfield = savBitfield;
449 bool maySetSoftTransact( bool val_r, TransactByValue causer )
450 { return maySetSoftTransact( val_r, causer, causer ); }
452 bool setToBeInstalled (TransactByValue causer)
454 if (isInstalled()) return false;
455 return setTransact (true, causer);
458 bool maySetToBeInstalled (TransactByValue causer)
460 bit::BitField<FieldType> savBitfield = _bitfield;
461 bool ret = setToBeInstalled (causer);
462 _bitfield = savBitfield;
466 bool setToBeUninstalled (TransactByValue causer)
468 if (!isInstalled()) return false;
469 return setTransact (true, causer);
472 bool maySetToBeUninstalled (TransactByValue causer)
474 bit::BitField<FieldType> savBitfield = _bitfield;
475 bool ret = setToBeUninstalled (causer);
476 _bitfield = savBitfield;
480 //------------------------------------------------------------------------
481 // *** These are only for the Resolver ***
483 bool setToBeUninstalledDueToUnlink ( )
485 if (!setToBeUninstalled (SOLVER)) return false;
486 fieldValueAssign<TransactDetailField>(DUE_TO_UNLINK);
490 bool setToBeUninstalledDueToObsolete ( )
492 if (!setToBeUninstalled (SOLVER)) return false;
493 fieldValueAssign<TransactDetailField>(DUE_TO_OBSOLETE);
497 bool setToBeUninstalledDueToUpgrade ( TransactByValue causer )
499 if (!setToBeUninstalled (causer)) return false;
500 fieldValueAssign<TransactDetailField>(DUE_TO_UPGRADE);
504 bool setToBeInstalledSoft ( )
507 || !setSoftTransact (true, SOLVER))
510 fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
514 bool setToBeUninstalledSoft ( )
517 || !setSoftTransact (true, SOLVER))
520 fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
524 bool maySetToBeUninstalledSoft ()
526 bit::BitField<FieldType> savBitfield = _bitfield;
527 bool ret = setToBeUninstalledSoft ();
528 _bitfield = savBitfield;
532 bool isSoftInstall () {
533 return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
536 bool isSoftUninstall () {
537 return fieldValueIs<TransactDetailField> (SOFT_REMOVE);
540 bool setSoftInstall (bool flag) {
541 fieldValueAssign<TransactDetailField>(flag?SOFT_INSTALL:0);
545 bool setSoftUninstall (bool flag) {
546 fieldValueAssign<TransactDetailField>(flag?SOFT_REMOVE:0);
550 bool setUndetermined ()
552 fieldValueAssign<EstablishField>(UNDETERMINED);
558 fieldValueAssign<EstablishField>(UNNEEDED);
564 fieldValueAssign<EstablishField>(SATISFIED);
568 bool setIncomplete ()
570 fieldValueAssign<EstablishField>(INCOMPLETE);
575 { return fieldValueIs<SolverStateField>( SEEN ); }
577 bool isImpossible () const
578 { return fieldValueIs<SolverStateField>( IMPOSSIBLE ); }
580 bool setSeen (bool value)
582 fieldValueAssign<SolverStateField>( value ? SEEN : NORMAL );
586 bool setImpossible (bool value)
588 fieldValueAssign<SolverStateField>( value ? IMPOSSIBLE : NORMAL );
592 bool setStatus( ResStatus newStatus_r )
594 // State field is immutable!
595 if ( _bitfield.value<StateField>() != newStatus_r._bitfield.value<StateField>() )
597 // Transaction state change allowed?
598 if ( ! setTransactValue( newStatus_r.getTransactValue(), newStatus_r.getTransactByValue() ) )
601 // Ok, we take it all..
602 _bitfield = newStatus_r._bitfield;
606 /** \name Builtin ResStatus constants. */
608 static const ResStatus toBeInstalled;
609 static const ResStatus toBeInstalledSoft;
610 static const ResStatus toBeUninstalled;
611 static const ResStatus toBeUninstalledSoft;
612 static const ResStatus toBeUninstalledDueToUnlink;
613 static const ResStatus toBeUninstalledDueToObsolete;
614 static const ResStatus toBeUninstalledDueToUpgrade;
615 static const ResStatus installed; // installed, status after successful target 'install' commit
616 static const ResStatus uninstalled; // uninstalled, status after successful target 'uninstall' commit
617 static const ResStatus satisfied; // uninstalled, satisfied
618 static const ResStatus complete; // installed, satisfied
619 static const ResStatus unneeded; // uninstalled, unneeded
620 static const ResStatus needed; // uninstalled, incomplete
621 static const ResStatus incomplete; // installed, incomplete
622 static const ResStatus impossible; // uninstallable
626 /** Ctor for intialization of builtin constants. */
627 ResStatus( StateValue s,
628 EstablishValue e = UNDETERMINED,
629 TransactValue t = KEEP_STATE,
630 InstallDetailValue i = EXPLICIT_INSTALL,
631 RemoveDetailValue r = EXPLICIT_REMOVE,
632 SolverStateValue ssv = NORMAL );
634 /** Return whether the corresponding Field has value \a val_r.
636 template<class _Field>
637 bool fieldValueIs( FieldType val_r ) const
638 { return _bitfield.isEqual<_Field>( val_r ); }
640 /** Set the corresponding Field to value \a val_r.
642 template<class _Field>
643 void fieldValueAssign( FieldType val_r )
644 { _bitfield.assign<_Field>( val_r ); }
646 /** compare two values.
648 template<class _Field>
649 bool isGreaterThan( FieldType val_r )
650 { return _bitfield.value<_Field>() > val_r; }
652 template<class _Field>
653 bool isLessThan( FieldType val_r )
654 { return _bitfield.value<_Field>() < val_r; }
657 BitFieldType _bitfield;
659 ///////////////////////////////////////////////////////////////////
661 /** \relates ResStatus Stream output */
662 std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
664 /** \relates ResStatus */
665 inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
666 { return lhs._bitfield == rhs._bitfield; }
668 /** \relates ResStatus */
669 inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
670 { return ! (lhs == rhs); }
672 /////////////////////////////////////////////////////////////////
674 ///////////////////////////////////////////////////////////////////
675 #endif // ZYPP_RESSTATUS_H