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 Whether 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> LicenceConfirmedField;
74 typedef bit::Range<FieldType,LicenceConfirmedField::end, 4> WeakField;
75 typedef bit::Range<FieldType,WeakField::end, 1> UserLockQueryField; // internal
76 // enlarge FieldType if more bit's needed. It's not yet
77 // checked by the compiler.
81 /** \name Status values.
83 * Each enum corresponds to a BitField range.
84 * \note Take care that enumerator values actually fit into
85 * the corresponding field. It's not yet checked by the compiler.
90 UNINSTALLED = bit::RangeValue<StateField,0>::value,
91 INSTALLED = bit::RangeValue<StateField,1>::value
95 UNDETERMINED = bit::RangeValue<ValidateField,0>::value,
96 BROKEN = bit::RangeValue<ValidateField,1>::value,
97 SATISFIED = bit::RangeValue<ValidateField,2>::value,
98 NONRELEVANT = bit::RangeValue<ValidateField,3>::value
102 KEEP_STATE = bit::RangeValue<TransactField,0>::value,
103 LOCKED = bit::RangeValue<TransactField,1>::value, // locked, must not transact
104 TRANSACT = bit::RangeValue<TransactField,2>::value // transact according to state
108 SOLVER = bit::RangeValue<TransactByField,0>::value,
109 APPL_LOW = bit::RangeValue<TransactByField,1>::value,
110 APPL_HIGH = bit::RangeValue<TransactByField,2>::value,
111 USER = bit::RangeValue<TransactByField,3>::value
116 /** Detail for no transact, i.e. reset any Install/RemoveDetailValue. */
117 NO_DETAIL = bit::RangeValue<TransactDetailField,0>::value,
119 enum InstallDetailValue
121 EXPLICIT_INSTALL = bit::RangeValue<TransactDetailField,0>::value,
122 SOFT_INSTALL = bit::RangeValue<TransactDetailField,1>::value
124 enum RemoveDetailValue
126 EXPLICIT_REMOVE = bit::RangeValue<TransactDetailField,0>::value,
127 SOFT_REMOVE = bit::RangeValue<TransactDetailField,1>::value,
128 DUE_TO_OBSOLETE = bit::RangeValue<TransactDetailField,2>::value,
129 DUE_TO_UPGRADE = bit::RangeValue<TransactDetailField,3>::value
132 enum LicenceConfirmedValue
134 LICENCE_UNCONFIRMED = bit::RangeValue<LicenceConfirmedField,0>::value,
135 LICENCE_CONFIRMED = bit::RangeValue<LicenceConfirmedField,1>::value
138 enum WeakValue // Unlike the other fields those are BITS that may be or'ed!
140 NO_WEAK = bit::RangeValue<WeakField,0>::value,
141 SUGGESTED = bit::RangeValue<WeakField,1<<0>::value,
142 RECOMMENDED = bit::RangeValue<WeakField,1<<1>::value,
143 ORPHANED = bit::RangeValue<WeakField,1<<2>::value,
144 UNNEEDED = bit::RangeValue<WeakField,1<<3>::value
147 enum UserLockQuery // internal
149 USERLOCK_NOMATCH = bit::RangeValue<UserLockQueryField,0>::value,
150 USERLOCK_MATCH = bit::RangeValue<UserLockQueryField,1>::value
159 /** Ctor setting the initial . */
160 ResStatus( bool isInstalled_r );
165 /** Debug helper returning the bitfield.
166 * It's save to expose the bitfield, as it can't be used to
167 * recreate a ResStatus. So it is not possible to bypass
170 BitFieldType bitfield() const
171 { return _bitfield; }
175 bool isLicenceConfirmed() const
176 { return fieldValueIs<LicenceConfirmedField>( LICENCE_CONFIRMED ); }
178 void setLicenceConfirmed( bool toVal_r = true )
179 { fieldValueAssign<LicenceConfirmedField>( toVal_r ? LICENCE_CONFIRMED : LICENCE_UNCONFIRMED ); }
182 bool isRecommended() const
183 { return _bitfield.test( RECOMMENDED ); }
185 bool isSuggested() const
186 { return _bitfield.test( SUGGESTED ); }
188 bool isOrphaned() const
189 { return _bitfield.test( ORPHANED ); }
191 bool isUnneeded() const
192 { return _bitfield.test( UNNEEDED ); }
195 { return fieldValueAssign<WeakField>( NO_WEAK ); }
197 void setRecommended( bool toVal_r = true )
198 { _bitfield.set( RECOMMENDED, toVal_r ); }
200 void setSuggested( bool toVal_r = true )
201 { _bitfield.set( SUGGESTED, toVal_r ); }
203 void setOrphaned( bool toVal_r = true )
204 { _bitfield.set( ORPHANED, toVal_r ); }
206 void setUnneeded( bool toVal_r = true )
207 { _bitfield.set( UNNEEDED, toVal_r ); }
210 ValidateValue validate() const
211 { return (ValidateValue)_bitfield.value<ValidateField>(); }
213 bool isUndetermined() const
214 { return fieldValueIs<ValidateField>( UNDETERMINED ); }
216 bool isSatisfied() const
217 { return fieldValueIs<ValidateField>( SATISFIED ); }
219 bool isBroken() const
220 { return fieldValueIs<ValidateField>( BROKEN ); }
222 bool isNonRelevant() const
223 { return fieldValueIs<ValidateField>( NONRELEVANT ); }
226 // These two are IMMUTABLE!
228 bool isInstalled() const
229 { return fieldValueIs<StateField>( INSTALLED ); }
231 bool isUninstalled() const
232 { return fieldValueIs<StateField>( UNINSTALLED ); }
236 bool staysInstalled() const
237 { return isInstalled() && !transacts(); }
239 bool wasInstalled() const { return staysInstalled(); } //for old status
241 bool isToBeInstalled() const
242 { return isUninstalled() && transacts(); }
244 bool staysUninstalled() const
245 { return isUninstalled() && !transacts(); }
247 bool wasUninstalled() const { return staysUninstalled(); } // for old status
249 bool isToBeUninstalled() const
250 { return isInstalled() && transacts(); }
252 bool isLocked() const
253 { return fieldValueIs<TransactField>( LOCKED ); }
255 bool isUserLocked() const
256 { return isLocked() && isByUser(); }
258 bool isSoftLocked() const
259 { return isKept() && ( isByApplLow() || isByUser() ); }
262 { return fieldValueIs<TransactField>( KEEP_STATE ); }
264 bool transacts() const
265 { return fieldValueIs<TransactField>( TRANSACT ); }
267 TransactValue getTransactValue() const
268 { return (TransactValue)_bitfield.value<TransactField>(); }
270 /** True if would be on system after commit. */
271 bool onSystem() const
272 { return( isInstalled() != transacts() ); }
274 /** True if would be off system after commit. */
275 bool offSystem() const
276 { return ! onSystem(); }
278 bool isBySolver() const
279 { return fieldValueIs<TransactByField>( SOLVER ); }
281 bool isByApplLow() const
282 { return fieldValueIs<TransactByField>( APPL_LOW ); }
284 bool isByApplHigh() const
285 { return fieldValueIs<TransactByField>( APPL_HIGH ); }
287 bool isByUser() const
288 { return fieldValueIs<TransactByField>( USER ); }
290 TransactByValue getTransactByValue() const
291 { return (TransactByValue)_bitfield.value<TransactByField>(); }
293 bool setTransactByValue(TransactByValue causer)
295 if ( isLessThan<TransactByField>( causer ) ) {
296 fieldValueAssign<TransactByField>( causer );
303 bool isToBeUninstalledDueToObsolete () const
304 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
306 bool isToBeUninstalledDueToUpgrade() const
307 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
309 bool isToBeInstalledSoft () const
310 { return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
312 bool isToBeInstalledNotSoft () const
313 { return isToBeInstalled() && !fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
315 bool isToBeUninstalledSoft () const
316 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
320 /** \name Internal hard lock maintainance */
322 friend class resstatus::UserLockQueryManip;
324 bool isUserLockQueryMatch() const
325 { return fieldValueIs<UserLockQueryField>( USERLOCK_MATCH ); }
327 void setUserLockQueryMatch( bool match_r )
328 { fieldValueAssign<UserLockQueryField>( match_r ? USERLOCK_MATCH : USERLOCK_NOMATCH ); }
333 //------------------------------------------------------------------------
334 // get/set functions, returnig \c true if requested status change
335 // was successfull (i.e. leading to the desired transaction).
336 // If a lower level (e.g.SOLVER) wants to transact, but it's
337 // already set by a higher level, \c true should be returned.
338 // Removing a higher levels transaction bit should fail.
340 // The may functions checks only, if the action would return true
343 /** Set TransactValue.
344 * Convenience to set TransactValue from enum.
346 bool setTransactValue( TransactValue newVal_r, TransactByValue causer_r )
351 return setTransact( false, causer_r );
354 return setLock( true, causer_r );
357 return setTransact( true, causer_r );
363 bool maySetTransactValue( TransactValue newVal_r, TransactByValue causer_r )
365 bit::BitField<FieldType> savBitfield = _bitfield;
366 bool ret = setTransactValue( newVal_r, causer_r );
367 _bitfield = savBitfield;
371 /** Apply a lock (prevent transaction).
372 * Currently by USER or APPL_HIGH only, but who knows...
373 * Set LOCKED from KEEP_STATE to be shure all transaction
374 * details were reset properly.
376 bool setLock( bool toLock_r, TransactByValue causer_r )
378 if ( toLock_r == isLocked() )
380 // we're already in the desired state, but in case of
381 // LOCKED, remember a superior causer.
382 if ( isLocked() && isLessThan<TransactByField>( causer_r ) )
383 fieldValueAssign<TransactByField>( causer_r );
386 // Here: Lock status is to be changed:
387 if ( causer_r != USER && causer_r != APPL_HIGH )
390 // We're in unlocked state, which includes TRANSACT.
391 // Causer must be allowed to reset this. But from
392 // KEEP_STATE every causer is allowed to set the lock.
393 if ( ! setTransact( false, causer_r ) )
395 fieldValueAssign<TransactField>( LOCKED );
396 fieldValueAssign<TransactByField>( causer_r );
398 // To leave Locked state it needs a superior causer.
399 if ( isGreaterThan<TransactByField>( causer_r ) )
401 fieldValueAssign<TransactField>( KEEP_STATE );
402 fieldValueAssign<TransactByField>( SOLVER ); // reset to lowest causer
403 // in order to distinguish from keep_state_by_user
408 bool maySetLock( bool to_r, TransactByValue causer_r )
410 bit::BitField<FieldType> savBitfield = _bitfield;
411 bool ret = setLock( to_r, causer_r );
412 _bitfield = savBitfield;
416 /** Toggle between TRANSACT and KEEP_STATE.
417 * LOCKED state means KEEP_STATE. But in contrary to KEEP_STATE,
418 * LOCKED state is immutable for \a causer_r less than TransactByValue.
419 * KEEP_STATE may be canged by any \a causer_r.
421 bool setTransact( bool toTansact_r, TransactByValue causer_r )
423 if ( toTansact_r == transacts() )
425 // we're already in the desired state, but in case of
426 // TRANSACT, remember a superior causer.
427 if ( transacts() && isLessThan<TransactByField>( causer_r ) )
428 fieldValueAssign<TransactByField>( causer_r );
430 fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
433 // Here: transact status is to be changed:
434 if ( ! fieldValueIs<TransactField>( KEEP_STATE )
435 && isGreaterThan<TransactByField>( causer_r ) ) {
441 fieldValueAssign<TransactField>( TRANSACT );
445 fieldValueAssign<TransactField>( KEEP_STATE );
447 fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
448 fieldValueAssign<TransactByField>( causer_r );
452 bool maySetTransact( bool val_r, TransactByValue causer )
454 bit::BitField<FieldType> savBitfield = _bitfield;
455 bool ret = setTransact (val_r, causer);
456 _bitfield = savBitfield;
461 bool setSoftLock( TransactByValue causer_r )
463 if ( ! setTransact( false, causer_r ) )
465 if ( fieldValueIs<TransactField>( KEEP_STATE )
466 && isLessThan<TransactByField>( causer_r ) )
467 fieldValueAssign<TransactByField>( causer_r );
471 /** Not the same as setTransact( false ).
473 bool resetTransact( TransactByValue causer_r )
475 if ( ! setTransact( false, causer_r ) )
477 if ( fieldValueIs<TransactField>( KEEP_STATE ) )
478 fieldValueAssign<TransactByField>( SOLVER );
482 /** Soft toggle between TRANSACT and KEEP_STATE.
483 * Similar to setTransact, but leaving KEEP_STATE also requires
484 * a superior \a causerLimit_r. So this is a kind of soft lock.
486 * // SOLVER wants to set TRANSACT, iff KEEP_STATE is
487 * // not superior to APPL_LOW.
488 * setSoftTransact( true, SOLVER, APPL_LOW );
491 bool setSoftTransact( bool toTansact_r, TransactByValue causer_r,
492 TransactByValue causerLimit_r )
494 if ( fieldValueIs<TransactField>( KEEP_STATE )
495 && toTansact_r != transacts()
496 && isGreaterThan<TransactByField>( causerLimit_r ) )
498 // any transact status change requires a superior causer.
501 return setTransact( toTansact_r, causer_r );
504 bool setSoftTransact( bool toTansact_r, TransactByValue causer_r )
505 { return setSoftTransact( toTansact_r, causer_r, causer_r ); }
507 bool maySetSoftTransact( bool val_r, TransactByValue causer,
508 TransactByValue causerLimit_r )
510 bit::BitField<FieldType> savBitfield = _bitfield;
511 bool ret = setSoftTransact( val_r, causer, causerLimit_r );
512 _bitfield = savBitfield;
516 bool maySetSoftTransact( bool val_r, TransactByValue causer )
517 { return maySetSoftTransact( val_r, causer, causer ); }
519 bool setToBeInstalled (TransactByValue causer)
521 if (isInstalled()) return false;
522 return setTransact (true, causer);
525 bool maySetToBeInstalled (TransactByValue causer)
527 bit::BitField<FieldType> savBitfield = _bitfield;
528 bool ret = setToBeInstalled (causer);
529 _bitfield = savBitfield;
533 bool setToBeUninstalled (TransactByValue causer)
535 if (!isInstalled()) return false;
536 return setTransact (true, causer);
539 bool maySetToBeUninstalled (TransactByValue causer)
541 bit::BitField<FieldType> savBitfield = _bitfield;
542 bool ret = setToBeUninstalled (causer);
543 _bitfield = savBitfield;
547 //------------------------------------------------------------------------
548 // *** These are only for the Resolver ***
550 bool setToBeUninstalledDueToObsolete ( )
552 if (!setToBeUninstalled (SOLVER)) return false;
553 fieldValueAssign<TransactDetailField>(DUE_TO_OBSOLETE);
557 bool setToBeUninstalledDueToUpgrade ( TransactByValue causer )
559 if (!setToBeUninstalled (causer)) return false;
560 fieldValueAssign<TransactDetailField>(DUE_TO_UPGRADE);
564 bool setToBeInstalledSoft ( )
567 || !setSoftTransact (true, SOLVER))
570 fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
574 bool setToBeUninstalledSoft ( )
577 || !setSoftTransact (true, SOLVER))
580 fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
584 bool maySetToBeUninstalledSoft ()
586 bit::BitField<FieldType> savBitfield = _bitfield;
587 bool ret = setToBeUninstalledSoft ();
588 _bitfield = savBitfield;
592 bool isSoftInstall () {
593 return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
596 bool isSoftUninstall () {
597 return fieldValueIs<TransactDetailField> (SOFT_REMOVE);
600 bool setSoftInstall (bool flag) {
601 fieldValueAssign<TransactDetailField>(flag?SOFT_INSTALL:0);
605 bool setSoftUninstall (bool flag) {
606 fieldValueAssign<TransactDetailField>(flag?SOFT_REMOVE:0);
610 bool setUndetermined ()
612 fieldValueAssign<ValidateField>(UNDETERMINED);
618 fieldValueAssign<ValidateField>(SATISFIED);
624 fieldValueAssign<ValidateField>(BROKEN);
628 bool setNonRelevant ()
630 fieldValueAssign<ValidateField>(NONRELEVANT);
634 bool setStatus( ResStatus newStatus_r )
636 // State field is immutable!
637 if ( _bitfield.value<StateField>() != newStatus_r._bitfield.value<StateField>() )
639 // Transaction state change allowed?
640 if ( ! setTransactValue( newStatus_r.getTransactValue(), newStatus_r.getTransactByValue() ) )
643 // Ok, we take it all..
644 _bitfield = newStatus_r._bitfield;
648 /** \name Builtin ResStatus constants. */
650 static const ResStatus toBeInstalled;
651 static const ResStatus toBeUninstalled;
652 static const ResStatus toBeUninstalledDueToUpgrade;
653 static const ResStatus toBeUninstalledDueToObsolete;
657 /** Ctor for intialization of builtin constants. */
658 ResStatus( StateValue s,
659 ValidateValue v = UNDETERMINED,
660 TransactValue t = KEEP_STATE,
661 InstallDetailValue i = EXPLICIT_INSTALL,
662 RemoveDetailValue r = EXPLICIT_REMOVE );
664 /** Return whether the corresponding Field has value \a val_r.
666 template<class TField>
667 bool fieldValueIs( FieldType val_r ) const
668 { return _bitfield.isEqual<TField>( val_r ); }
670 /** Set the corresponding Field to value \a val_r.
672 template<class TField>
673 void fieldValueAssign( FieldType val_r )
674 { _bitfield.assign<TField>( val_r ); }
676 /** compare two values.
678 template<class TField>
679 bool isGreaterThan( FieldType val_r )
680 { return _bitfield.value<TField>() > val_r; }
682 template<class TField>
683 bool isLessThan( FieldType val_r )
684 { return _bitfield.value<TField>() < val_r; }
687 friend class resstatus::StatusBackup;
688 BitFieldType _bitfield;
690 ///////////////////////////////////////////////////////////////////
692 /** \relates ResStatus Stream output */
693 std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
695 /** \relates ResStatus Stream output */
696 std::ostream & operator<<( std::ostream & str, ResStatus::TransactValue obj );
698 /** \relates ResStatus Stream output */
699 std::ostream & operator<<( std::ostream & str, ResStatus::TransactByValue obj );
701 /** \relates ResStatus */
702 inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
703 { return lhs._bitfield == rhs._bitfield; }
705 /** \relates ResStatus */
706 inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
707 { return ! (lhs == rhs); }
709 ///////////////////////////////////////////////////////////////////
720 StatusBackup( ResStatus & status_r )
721 : _status( &status_r )
722 , _bitfield( _status->_bitfield )
726 { if ( _status ) _status->_bitfield = _bitfield; }
730 ResStatus::BitFieldType _bitfield;
734 /////////////////////////////////////////////////////////////////
736 ///////////////////////////////////////////////////////////////////
737 #endif // ZYPP_RESSTATUS_H