1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ResStatus.h
12 #ifndef ZYPP_RESSTATUS_H
13 #define ZYPP_RESSTATUS_H
19 ///////////////////////////////////////////////////////////////////
21 { /////////////////////////////////////////////////////////////////
25 class UserLockQueryManip;
29 ///////////////////////////////////////////////////////////////////
31 // CLASS NAME : ResStatus
35 * \li \c StateField Whether the resolvable is or uninstalled (available).
36 * \li \c ValidateField Validate status computed by the solver as
37 * nonrelevant: it is unimportant for the user
38 * satisfied: it important nothing has to be done
39 * broken: it is incomplete. So e.g. an update is needed
40 * \li \c TransactField Wheter to transact this resolvable
41 * (delete if installed install if uninstalled).
42 * In case the resolvable is locked, only USER may modify the
44 * \li \c TransactByField Who triggered the transaction. Transaction
45 * bit may be reset by higer levels only.
46 * \li \c TransactDetailField Reason why the Resolvable transacts.
47 * Splitted into \c InstallDetailValue and \c RemoveDetailValue
48 * dependent on the kind of transaction.
49 * \li \c WeakField The solvable will be recommended/suggested by
50 * a to be installed/deleted solvable.
55 friend std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
56 friend bool operator==( const ResStatus & lhs, const ResStatus & rhs );
59 /** \name BitField range definitions.
61 * \note Enlarge FieldType if more bit's needed. It's not yet
62 * checked by the compiler.
65 typedef uint16_t FieldType;
66 typedef bit::BitField<FieldType> BitFieldType;
67 // Bit Ranges within FieldType defined by 1st bit and size:
68 typedef bit::Range<FieldType,0, 1> StateField;
69 typedef bit::Range<FieldType,StateField::end, 2> ValidateField;
70 typedef bit::Range<FieldType,ValidateField::end, 2> TransactField;
71 typedef bit::Range<FieldType,TransactField::end, 2> TransactByField;
72 typedef bit::Range<FieldType,TransactByField::end, 2> TransactDetailField;
73 typedef bit::Range<FieldType,TransactDetailField::end, 1> SolverStateField;
74 typedef bit::Range<FieldType,SolverStateField::end, 1> LicenceConfirmedField;
75 typedef bit::Range<FieldType,LicenceConfirmedField::end, 2> WeakField;
76 typedef bit::Range<FieldType,WeakField::end, 1> UserLockQueryField; // internal
77 // enlarge FieldType if more bit's needed. It's not yet
78 // checked by the compiler.
82 /** \name Status values.
84 * Each enum corresponds to a BitField range.
85 * \note Take care that enumerator values actually fit into
86 * the corresponding field. It's not yet checked by the compiler.
91 UNINSTALLED = bit::RangeValue<StateField,0>::value,
92 INSTALLED = bit::RangeValue<StateField,1>::value
96 UNDETERMINED = bit::RangeValue<ValidateField,0>::value,
97 BROKEN = bit::RangeValue<ValidateField,1>::value,
98 SATISFIED = bit::RangeValue<ValidateField,2>::value,
99 NONRELEVANT = bit::RangeValue<ValidateField,3>::value
103 KEEP_STATE = bit::RangeValue<TransactField,0>::value,
104 LOCKED = bit::RangeValue<TransactField,1>::value, // locked, must not transact
105 TRANSACT = bit::RangeValue<TransactField,2>::value // transact according to state
109 SOLVER = bit::RangeValue<TransactByField,0>::value,
110 APPL_LOW = bit::RangeValue<TransactByField,1>::value,
111 APPL_HIGH = bit::RangeValue<TransactByField,2>::value,
112 USER = bit::RangeValue<TransactByField,3>::value
117 /** Detail for no transact, i.e. reset any Install/RemoveDetailValue. */
118 NO_DETAIL = bit::RangeValue<TransactDetailField,0>::value,
121 enum InstallDetailValue
123 EXPLICIT_INSTALL = bit::RangeValue<TransactDetailField,0>::value,
124 SOFT_INSTALL = bit::RangeValue<TransactDetailField,1>::value
126 enum RemoveDetailValue
128 EXPLICIT_REMOVE = bit::RangeValue<TransactDetailField,0>::value,
129 SOFT_REMOVE = bit::RangeValue<TransactDetailField,1>::value,
130 DUE_TO_OBSOLETE = bit::RangeValue<TransactDetailField,2>::value,
131 DUE_TO_UPGRADE = bit::RangeValue<TransactDetailField,3>::value
133 enum SolverStateValue
135 NORMAL = bit::RangeValue<SolverStateField,0>::value, // default, notthing special
136 SEEN = bit::RangeValue<SolverStateField,1>::value, // already seen during ResolverUpgrade
139 enum LicenceConfirmedValue
141 LICENCE_UNCONFIRMED = bit::RangeValue<LicenceConfirmedField,0>::value,
142 LICENCE_CONFIRMED = bit::RangeValue<LicenceConfirmedField,1>::value
147 NO_WEAK = bit::RangeValue<WeakField,0>::value,
148 SUGGESTED = bit::RangeValue<WeakField,1>::value,
149 RECOMMENDED = bit::RangeValue<WeakField,2>::value,
150 SUGGESTED_AND_RECOMMENDED = bit::RangeValue<WeakField,3>::value
153 enum UserLockQuery // internal
155 USERLOCK_NOMATCH = bit::RangeValue<UserLockQueryField,0>::value,
156 USERLOCK_MATCH = bit::RangeValue<UserLockQueryField,1>::value
165 /** Ctor setting the initial . */
166 ResStatus( bool isInstalled_r );
171 /** Debug helper returning the bitfield.
172 * It's save to expose the bitfield, as it can't be used to
173 * recreate a ResStatus. So it is not possible to bypass
176 BitFieldType bitfield() const
177 { return _bitfield; }
181 bool isLicenceConfirmed() const
182 { return fieldValueIs<LicenceConfirmedField>( LICENCE_CONFIRMED ); }
184 void setLicenceConfirmed( bool toVal_r = true )
185 { fieldValueAssign<LicenceConfirmedField>( toVal_r ? LICENCE_CONFIRMED : LICENCE_UNCONFIRMED ); }
189 bool isRecommended() const
190 { return fieldValueIs<WeakField>( RECOMMENDED ); }
192 bool isSuggested() const
193 { return fieldValueIs<WeakField>( SUGGESTED ); }
195 bool resetWeak() const
196 { return fieldValueIs<WeakField>( NO_WEAK ); }
198 void setRecommended( bool toVal_r = true )
200 fieldValueAssign<WeakField>( toVal_r ? SUGGESTED_AND_RECOMMENDED : SUGGESTED );
202 fieldValueAssign<WeakField>( toVal_r ? RECOMMENDED : NO_WEAK );
205 void setSuggested( bool toVal_r = true )
206 { if (isRecommended())
207 fieldValueAssign<WeakField>( toVal_r ? SUGGESTED_AND_RECOMMENDED : RECOMMENDED );
209 fieldValueAssign<WeakField>( toVal_r ? SUGGESTED : NO_WEAK );
212 ValidateValue validate() const
213 { return (ValidateValue)_bitfield.value<ValidateField>(); }
215 bool isUndetermined() const
216 { return fieldValueIs<ValidateField>( UNDETERMINED ); }
218 bool isSatisfied() const
219 { return fieldValueIs<ValidateField>( SATISFIED ); }
221 bool isBroken() const
222 { return fieldValueIs<ValidateField>( BROKEN ); }
224 bool isNonRelevant() const
225 { return fieldValueIs<ValidateField>( NONRELEVANT ); }
228 // These two are IMMUTABLE!
230 bool isInstalled() const
231 { return fieldValueIs<StateField>( INSTALLED ); }
233 bool isUninstalled() const
234 { return fieldValueIs<StateField>( UNINSTALLED ); }
238 bool staysInstalled() const
239 { return isInstalled() && !transacts(); }
241 bool wasInstalled() const { return staysInstalled(); } //for old status
243 bool isToBeInstalled() const
244 { return isUninstalled() && transacts(); }
246 bool staysUninstalled() const
247 { return isUninstalled() && !transacts(); }
249 bool wasUninstalled() const { return staysUninstalled(); } // for old status
251 bool isToBeUninstalled() const
252 { return isInstalled() && transacts(); }
254 bool isLocked() const
255 { return fieldValueIs<TransactField>( LOCKED ); }
257 bool isUserLocked() const
258 { return isLocked() && isByUser(); }
260 bool isSoftLocked( TransactByValue causer_r = USER ) const
261 { return isKept() && fieldValueIs<TransactByField>( causer_r ); }
264 { return fieldValueIs<TransactField>( KEEP_STATE ); }
266 bool transacts() const
267 { return fieldValueIs<TransactField>( TRANSACT ); }
269 TransactValue getTransactValue() const
270 { return (TransactValue)_bitfield.value<TransactField>(); }
272 /** True if would be on system after commit. */
273 bool onSystem() const
274 { return( isInstalled() != transacts() ); }
276 /** True if would be off system after commit. */
277 bool offSystem() const
278 { return ! onSystem(); }
280 bool isBySolver() const
281 { return fieldValueIs<TransactByField>( SOLVER ); }
283 bool isByApplLow() const
284 { return fieldValueIs<TransactByField>( APPL_LOW ); }
286 bool isByApplHigh() const
287 { return fieldValueIs<TransactByField>( APPL_HIGH ); }
289 bool isByUser() const
290 { return fieldValueIs<TransactByField>( USER ); }
292 TransactByValue getTransactByValue() const
293 { return (TransactByValue)_bitfield.value<TransactByField>(); }
295 bool setTransactByValue(TransactByValue causer)
297 if ( isLessThan<TransactByField>( causer ) ) {
298 fieldValueAssign<TransactByField>( causer );
305 bool isToBeUninstalledDueToObsolete () const
306 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
308 bool isToBeUninstalledDueToUpgrade() const
309 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
311 bool isToBeInstalledSoft () const
312 { return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
314 bool isToBeInstalledNotSoft () const
315 { return isToBeInstalled() && !fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
317 bool isToBeUninstalledSoft () const
318 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
322 /** \name Internal hard lock maintainance */
324 friend class resstatus::UserLockQueryManip;
326 bool isUserLockQueryMatch() const
327 { return fieldValueIs<UserLockQueryField>( USERLOCK_MATCH ); }
329 void setUserLockQueryMatch( bool match_r )
330 { fieldValueAssign<UserLockQueryField>( match_r ? USERLOCK_MATCH : USERLOCK_NOMATCH ); }
335 //------------------------------------------------------------------------
336 // get/set functions, returnig \c true if requested status change
337 // was successfull (i.e. leading to the desired transaction).
338 // If a lower level (e.g.SOLVER) wants to transact, but it's
339 // already set by a higher level, \c true should be returned.
340 // Removing a higher levels transaction bit should fail.
342 // The may functions checks only, if the action would return true
345 /** Set TransactValue.
346 * Convenience to set TransactValue from enum.
348 bool setTransactValue( TransactValue newVal_r, TransactByValue causer_r )
353 return setTransact( false, causer_r );
356 return setLock( true, causer_r );
359 return setTransact( true, causer_r );
365 bool maySetTransactValue( TransactValue newVal_r, TransactByValue causer_r )
367 bit::BitField<FieldType> savBitfield = _bitfield;
368 bool ret = setTransactValue( newVal_r, causer_r );
369 _bitfield = savBitfield;
373 /** Apply a lock (prevent transaction).
374 * Currently by USER or APPL_HIGH only, but who knows...
375 * Set LOCKED from KEEP_STATE to be shure all transaction
376 * details were reset properly.
378 bool setLock( bool toLock_r, TransactByValue causer_r )
380 if ( toLock_r == isLocked() )
382 // we're already in the desired state, but in case of
383 // LOCKED, remember a superior causer.
384 if ( isLocked() && isLessThan<TransactByField>( causer_r ) )
385 fieldValueAssign<TransactByField>( causer_r );
388 // Here: Lock status is to be changed:
389 if ( causer_r != USER && causer_r != APPL_HIGH )
392 // We're in unlocked state, which includes TRANSACT.
393 // Causer must be allowed to reset this. But from
394 // KEEP_STATE every causer is allowed to set the lock.
395 if ( ! setTransact( false, causer_r ) )
397 fieldValueAssign<TransactField>( LOCKED );
398 fieldValueAssign<TransactByField>( causer_r );
400 // To leave Locked state it needs a superior causer.
401 if ( isGreaterThan<TransactByField>( causer_r ) )
403 fieldValueAssign<TransactField>( KEEP_STATE );
404 fieldValueAssign<TransactByField>( SOLVER ); // reset to lowest causer
405 // in order to distinguish from keep_state_by_user
410 bool maySetLock( bool to_r, TransactByValue causer_r )
412 bit::BitField<FieldType> savBitfield = _bitfield;
413 bool ret = setLock( to_r, causer_r );
414 _bitfield = savBitfield;
418 /** Toggle between TRANSACT and KEEP_STATE.
419 * LOCKED state means KEEP_STATE. But in contrary to KEEP_STATE,
420 * LOCKED state is immutable for \a causer_r less than TransactByValue.
421 * KEEP_STATE may be canged by any \a causer_r.
423 bool setTransact( bool toTansact_r, TransactByValue causer_r )
425 if ( toTansact_r == transacts() )
427 // we're already in the desired state, but in case of
428 // TRANSACT, remember a superior causer.
429 if ( transacts() && isLessThan<TransactByField>( causer_r ) )
430 fieldValueAssign<TransactByField>( causer_r );
432 fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
435 // Here: transact status is to be changed:
436 if ( ! fieldValueIs<TransactField>( KEEP_STATE )
437 && isGreaterThan<TransactByField>( causer_r ) ) {
443 fieldValueAssign<TransactField>( TRANSACT );
447 fieldValueAssign<TransactField>( KEEP_STATE );
449 fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
450 fieldValueAssign<TransactByField>( causer_r );
454 bool maySetTransact( bool val_r, TransactByValue causer )
456 bit::BitField<FieldType> savBitfield = _bitfield;
457 bool ret = setTransact (val_r, causer);
458 _bitfield = savBitfield;
463 bool setSoftLock( TransactByValue causer_r )
465 if ( ! setTransact( false, causer_r ) )
467 if ( fieldValueIs<TransactField>( KEEP_STATE )
468 && isLessThan<TransactByField>( causer_r ) )
469 fieldValueAssign<TransactByField>( causer_r );
473 /** Not the same as setTransact( false ).
475 bool resetTransact( TransactByValue causer_r )
477 if ( ! setTransact( false, causer_r ) )
479 if ( fieldValueIs<TransactField>( KEEP_STATE ) )
480 fieldValueAssign<TransactByField>( SOLVER );
484 /** Soft toggle between TRANSACT and KEEP_STATE.
485 * Similar to setTransact, but leaving KEEP_STATE also requires
486 * a superior \a causerLimit_r. So this is a kind of soft lock.
488 * // SOLVER wants to set TRANSACT, iff KEEP_STATE is
489 * // not superior to APPL_LOW.
490 * setSoftTransact( true, SOLVER, APPL_LOW );
493 bool setSoftTransact( bool toTansact_r, TransactByValue causer_r,
494 TransactByValue causerLimit_r )
496 if ( fieldValueIs<TransactField>( KEEP_STATE )
497 && toTansact_r != transacts()
498 && isGreaterThan<TransactByField>( causerLimit_r ) )
500 // any transact status change requires a superior causer.
503 return setTransact( toTansact_r, causer_r );
506 bool setSoftTransact( bool toTansact_r, TransactByValue causer_r )
507 { return setSoftTransact( toTansact_r, causer_r, causer_r ); }
509 bool maySetSoftTransact( bool val_r, TransactByValue causer,
510 TransactByValue causerLimit_r )
512 bit::BitField<FieldType> savBitfield = _bitfield;
513 bool ret = setSoftTransact( val_r, causer, causerLimit_r );
514 _bitfield = savBitfield;
518 bool maySetSoftTransact( bool val_r, TransactByValue causer )
519 { return maySetSoftTransact( val_r, causer, causer ); }
521 bool setToBeInstalled (TransactByValue causer)
523 if (isInstalled()) return false;
524 return setTransact (true, causer);
527 bool maySetToBeInstalled (TransactByValue causer)
529 bit::BitField<FieldType> savBitfield = _bitfield;
530 bool ret = setToBeInstalled (causer);
531 _bitfield = savBitfield;
535 bool setToBeUninstalled (TransactByValue causer)
537 if (!isInstalled()) return false;
538 return setTransact (true, causer);
541 bool maySetToBeUninstalled (TransactByValue causer)
543 bit::BitField<FieldType> savBitfield = _bitfield;
544 bool ret = setToBeUninstalled (causer);
545 _bitfield = savBitfield;
549 //------------------------------------------------------------------------
550 // *** These are only for the Resolver ***
552 bool setToBeUninstalledDueToObsolete ( )
554 if (!setToBeUninstalled (SOLVER)) return false;
555 fieldValueAssign<TransactDetailField>(DUE_TO_OBSOLETE);
559 bool setToBeUninstalledDueToUpgrade ( TransactByValue causer )
561 if (!setToBeUninstalled (causer)) return false;
562 fieldValueAssign<TransactDetailField>(DUE_TO_UPGRADE);
566 bool setToBeInstalledSoft ( )
569 || !setSoftTransact (true, SOLVER))
572 fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
576 bool setToBeUninstalledSoft ( )
579 || !setSoftTransact (true, SOLVER))
582 fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
586 bool maySetToBeUninstalledSoft ()
588 bit::BitField<FieldType> savBitfield = _bitfield;
589 bool ret = setToBeUninstalledSoft ();
590 _bitfield = savBitfield;
594 bool isSoftInstall () {
595 return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
598 bool isSoftUninstall () {
599 return fieldValueIs<TransactDetailField> (SOFT_REMOVE);
602 bool setSoftInstall (bool flag) {
603 fieldValueAssign<TransactDetailField>(flag?SOFT_INSTALL:0);
607 bool setSoftUninstall (bool flag) {
608 fieldValueAssign<TransactDetailField>(flag?SOFT_REMOVE:0);
612 bool setUndetermined ()
614 fieldValueAssign<ValidateField>(UNDETERMINED);
620 fieldValueAssign<ValidateField>(SATISFIED);
626 fieldValueAssign<ValidateField>(BROKEN);
630 bool setNonRelevant ()
632 fieldValueAssign<ValidateField>(NONRELEVANT);
637 { return fieldValueIs<SolverStateField>( SEEN ); }
639 bool setSeen (bool value)
641 fieldValueAssign<SolverStateField>( value ? SEEN : NORMAL );
645 bool setStatus( ResStatus newStatus_r )
647 // State field is immutable!
648 if ( _bitfield.value<StateField>() != newStatus_r._bitfield.value<StateField>() )
650 // Transaction state change allowed?
651 if ( ! setTransactValue( newStatus_r.getTransactValue(), newStatus_r.getTransactByValue() ) )
654 // Ok, we take it all..
655 _bitfield = newStatus_r._bitfield;
659 /** \name Builtin ResStatus constants. */
661 static const ResStatus toBeInstalled;
662 static const ResStatus toBeUninstalled;
663 static const ResStatus toBeUninstalledDueToUpgrade;
664 static const ResStatus toBeUninstalledDueToObsolete;
668 /** Ctor for intialization of builtin constants. */
669 ResStatus( StateValue s,
670 ValidateValue v = UNDETERMINED,
671 TransactValue t = KEEP_STATE,
672 InstallDetailValue i = EXPLICIT_INSTALL,
673 RemoveDetailValue r = EXPLICIT_REMOVE,
674 SolverStateValue ssv = NORMAL );
676 /** Return whether the corresponding Field has value \a val_r.
678 template<class _Field>
679 bool fieldValueIs( FieldType val_r ) const
680 { return _bitfield.isEqual<_Field>( val_r ); }
682 /** Set the corresponding Field to value \a val_r.
684 template<class _Field>
685 void fieldValueAssign( FieldType val_r )
686 { _bitfield.assign<_Field>( val_r ); }
688 /** compare two values.
690 template<class _Field>
691 bool isGreaterThan( FieldType val_r )
692 { return _bitfield.value<_Field>() > val_r; }
694 template<class _Field>
695 bool isLessThan( FieldType val_r )
696 { return _bitfield.value<_Field>() < val_r; }
699 friend class resstatus::StatusBackup;
700 BitFieldType _bitfield;
702 ///////////////////////////////////////////////////////////////////
704 /** \relates ResStatus Stream output */
705 std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
707 /** \relates ResStatus Stream output */
708 std::ostream & operator<<( std::ostream & str, ResStatus::TransactValue obj );
710 /** \relates ResStatus Stream output */
711 std::ostream & operator<<( std::ostream & str, ResStatus::TransactByValue obj );
713 /** \relates ResStatus */
714 inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
715 { return lhs._bitfield == rhs._bitfield; }
717 /** \relates ResStatus */
718 inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
719 { return ! (lhs == rhs); }
721 ///////////////////////////////////////////////////////////////////
732 StatusBackup( ResStatus & status_r )
733 : _status( &status_r )
734 , _bitfield( _status->_bitfield )
738 { if ( _status ) _status->_bitfield = _bitfield; }
742 ResStatus::BitFieldType _bitfield;
746 /////////////////////////////////////////////////////////////////
748 ///////////////////////////////////////////////////////////////////
749 #endif // ZYPP_RESSTATUS_H