1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ResStatus.h
12 #ifndef ZYPP_RESSTATUS_H
13 #define ZYPP_RESSTATUS_H
18 ///////////////////////////////////////////////////////////////////
20 { /////////////////////////////////////////////////////////////////
24 class UserLockQueryManip;
27 ///////////////////////////////////////////////////////////////////
29 // CLASS NAME : ResStatus
33 * \li \c StateField Whether the resolvable is or uninstalled (available).
34 * \li \c ValidateField Validate status computed by the solver as
35 * nonrelevant: it is unimportant for the user
36 * satisfied: it important nothing has to be done
37 * broken: it is incomplete. So e.g. an update is needed
38 * \li \c TransactField Wheter to transact this resolvable
39 * (delete if installed install if uninstalled).
40 * In case the resolvable is locked, only USER may modify the
42 * \li \c TransactByField Who triggered the transaction. Transaction
43 * bit may be reset by higer levels only.
44 * \li \c TransactDetailField Reason why the Resolvable transacts.
45 * Splitted into \c InstallDetailValue and \c RemoveDetailValue
46 * dependent on the kind of transaction.
47 * \li \c WeakField The solvable will be recommended/suggested by
48 * a to be installed/deleted solvable.
53 friend std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
54 friend bool operator==( const ResStatus & lhs, const ResStatus & rhs );
57 /** \name BitField range definitions.
59 * \note Enlarge FieldType if more bit's needed. It's not yet
60 * checked by the compiler.
63 typedef uint16_t FieldType;
64 typedef bit::BitField<FieldType> BitFieldType;
65 // Bit Ranges within FieldType defined by 1st bit and size:
66 typedef bit::Range<FieldType,0, 1> StateField;
67 typedef bit::Range<FieldType,StateField::end, 2> ValidateField;
68 typedef bit::Range<FieldType,ValidateField::end, 2> TransactField;
69 typedef bit::Range<FieldType,TransactField::end, 2> TransactByField;
70 typedef bit::Range<FieldType,TransactByField::end, 2> TransactDetailField;
71 typedef bit::Range<FieldType,TransactDetailField::end, 1> SolverStateField;
72 typedef bit::Range<FieldType,SolverStateField::end, 1> LicenceConfirmedField;
73 typedef bit::Range<FieldType,LicenceConfirmedField::end, 2> WeakField;
74 typedef bit::Range<FieldType,WeakField::end, 1> UserLockQueryField; // internal
75 // enlarge FieldType if more bit's needed. It's not yet
76 // checked by the compiler.
80 /** \name Status values.
82 * Each enum corresponds to a BitField range.
83 * \note Take care that enumerator values actually fit into
84 * the corresponding field. It's not yet checked by the compiler.
89 UNINSTALLED = bit::RangeValue<StateField,0>::value,
90 INSTALLED = bit::RangeValue<StateField,1>::value
94 UNDETERMINED = bit::RangeValue<ValidateField,0>::value,
95 BROKEN = bit::RangeValue<ValidateField,1>::value,
96 SATISFIED = bit::RangeValue<ValidateField,2>::value,
97 NONRELEVANT = bit::RangeValue<ValidateField,3>::value
101 KEEP_STATE = bit::RangeValue<TransactField,0>::value,
102 LOCKED = bit::RangeValue<TransactField,1>::value, // locked, must not transact
103 TRANSACT = bit::RangeValue<TransactField,2>::value // transact according to state
107 SOLVER = bit::RangeValue<TransactByField,0>::value,
108 APPL_LOW = bit::RangeValue<TransactByField,1>::value,
109 APPL_HIGH = bit::RangeValue<TransactByField,2>::value,
110 USER = bit::RangeValue<TransactByField,3>::value
115 /** Detail for no transact, i.e. reset any Install/RemoveDetailValue. */
116 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
131 enum SolverStateValue
133 NORMAL = bit::RangeValue<SolverStateField,0>::value, // default, notthing special
134 SEEN = bit::RangeValue<SolverStateField,1>::value, // already seen during ResolverUpgrade
137 enum LicenceConfirmedValue
139 LICENCE_UNCONFIRMED = bit::RangeValue<LicenceConfirmedField,0>::value,
140 LICENCE_CONFIRMED = bit::RangeValue<LicenceConfirmedField,1>::value
145 NO_WEAK = bit::RangeValue<WeakField,0>::value,
146 SUGGESTED = bit::RangeValue<WeakField,1>::value,
147 RECOMMENDED = bit::RangeValue<WeakField,2>::value,
148 SUGGESTED_AND_RECOMMENDED = bit::RangeValue<WeakField,3>::value
151 enum UserLockQuery // internal
153 USERLOCK_NOMATCH = bit::RangeValue<UserLockQueryField,0>::value,
154 USERLOCK_MATCH = bit::RangeValue<UserLockQueryField,1>::value
163 /** Ctor setting the initial . */
164 ResStatus( bool isInstalled_r );
169 /** Debug helper returning the bitfield.
170 * It's save to expose the bitfield, as it can't be used to
171 * recreate a ResStatus. So it is not possible to bypass
174 BitFieldType bitfield() const
175 { return _bitfield; }
179 bool isLicenceConfirmed() const
180 { return fieldValueIs<LicenceConfirmedField>( LICENCE_CONFIRMED ); }
182 void setLicenceConfirmed( bool toVal_r = true )
183 { fieldValueAssign<LicenceConfirmedField>( toVal_r ? LICENCE_CONFIRMED : LICENCE_UNCONFIRMED ); }
187 bool isRecommended() const
188 { return fieldValueIs<WeakField>( RECOMMENDED ); }
190 bool isSuggested() const
191 { return fieldValueIs<WeakField>( SUGGESTED ); }
193 bool resetWeak() const
194 { return fieldValueIs<WeakField>( NO_WEAK ); }
196 void setRecommended( bool toVal_r = true )
198 fieldValueAssign<WeakField>( toVal_r ? SUGGESTED_AND_RECOMMENDED : SUGGESTED );
200 fieldValueAssign<WeakField>( toVal_r ? RECOMMENDED : NO_WEAK );
203 void setSuggested( bool toVal_r = true )
204 { if (isRecommended())
205 fieldValueAssign<WeakField>( toVal_r ? SUGGESTED_AND_RECOMMENDED : RECOMMENDED );
207 fieldValueAssign<WeakField>( toVal_r ? SUGGESTED : NO_WEAK );
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 isSoftLocked( TransactByValue causer_r = USER ) const
256 { return isKept() && fieldValueIs<TransactByField>( causer_r ); }
259 { return fieldValueIs<TransactField>( KEEP_STATE ); }
261 bool transacts() const
262 { return fieldValueIs<TransactField>( TRANSACT ); }
264 TransactValue getTransactValue() const
265 { return (TransactValue)_bitfield.value<TransactField>(); }
267 bool isBySolver() const
268 { return fieldValueIs<TransactByField>( SOLVER ); }
270 bool isByApplLow() const
271 { return fieldValueIs<TransactByField>( APPL_LOW ); }
273 bool isByApplHigh() const
274 { return fieldValueIs<TransactByField>( APPL_HIGH ); }
276 bool isByUser() const
277 { return fieldValueIs<TransactByField>( USER ); }
279 TransactByValue getTransactByValue() const
280 { return (TransactByValue)_bitfield.value<TransactByField>(); }
283 bool isToBeUninstalledDueToObsolete () const
284 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
286 bool isToBeUninstalledDueToUpgrade() const
287 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
289 bool isToBeInstalledSoft () const
290 { return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
292 bool isToBeInstalledNotSoft () const
293 { return isToBeInstalled() && !fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
295 bool isToBeUninstalledSoft () const
296 { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
300 /** \name Internal hard lock maintainance */
302 friend class resstatus::UserLockQueryManip;
304 bool isUserLockQueryMatch() const
305 { return fieldValueIs<UserLockQueryField>( USERLOCK_MATCH ); }
307 void setUserLockQueryMatch( bool match_r )
308 { fieldValueAssign<UserLockQueryField>( match_r ? USERLOCK_MATCH : USERLOCK_NOMATCH ); }
313 //------------------------------------------------------------------------
314 // get/set functions, returnig \c true if requested status change
315 // was successfull (i.e. leading to the desired transaction).
316 // If a lower level (e.g.SOLVER) wants to transact, but it's
317 // already set by a higher level, \c true should be returned.
318 // Removing a higher levels transaction bit should fail.
320 // The may functions checks only, if the action would return true
323 /** Set TransactValue.
324 * Convenience to set TransactValue from enum.
326 bool setTransactValue( TransactValue newVal_r, TransactByValue causer_r )
331 return setTransact( false, causer_r );
334 return setLock( true, causer_r );
337 return setTransact( true, causer_r );
343 bool maySetTransactValue( TransactValue newVal_r, TransactByValue causer_r )
345 bit::BitField<FieldType> savBitfield = _bitfield;
346 bool ret = setTransactValue( newVal_r, causer_r );
347 _bitfield = savBitfield;
351 /** Apply a lock (prevent transaction).
352 * Currently by USER only, but who knows... Set LOCKED
353 * from KEEP_STATE to be shure all transaction details
354 * were reset properly.
356 bool setLock( bool toLock_r, TransactByValue causer_r )
358 if ( toLock_r == isLocked() )
360 // we're already in the desired state, but in case of
361 // LOCKED, remember a superior causer.
362 if ( isLocked() && isLessThan<TransactByField>( causer_r ) )
363 fieldValueAssign<TransactByField>( causer_r );
366 // Here: Lock status is to be changed:
367 if ( causer_r != USER )
369 // Setting no transact removes an existing lock,
370 // or brings this into KEEP_STATE, and we apply the lock.
371 if ( ! setTransact( false, causer_r ) )
374 fieldValueAssign<TransactField>( LOCKED );
375 fieldValueAssign<TransactByField>( causer_r );
377 fieldValueAssign<TransactField>( KEEP_STATE );
378 fieldValueAssign<TransactByField>( SOLVER ); // reset to lowest causer
379 // in order to distinguish from keep_state_by_user
384 bool maySetLock( bool to_r, TransactByValue causer_r )
386 bit::BitField<FieldType> savBitfield = _bitfield;
387 bool ret = setLock( to_r, causer_r );
388 _bitfield = savBitfield;
392 /** Toggle between TRANSACT and KEEP_STATE.
393 * LOCKED state means KEEP_STATE. But in contrary to KEEP_STATE,
394 * LOCKED state is immutable for \a causer_r less than TransactByValue.
395 * KEEP_STATE may be canged by any \a causer_r.
397 bool setTransact( bool toTansact_r, TransactByValue causer_r )
399 if ( toTansact_r == transacts() )
401 // we're already in the desired state, but in case of
402 // TRANSACT, remember a superior causer.
403 if ( transacts() && isLessThan<TransactByField>( causer_r ) )
404 fieldValueAssign<TransactByField>( causer_r );
406 fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
409 // Here: transact status is to be changed:
410 if ( ! fieldValueIs<TransactField>( KEEP_STATE )
411 && isGreaterThan<TransactByField>( causer_r ) ) {
417 fieldValueAssign<TransactField>( TRANSACT );
421 fieldValueAssign<TransactField>( KEEP_STATE );
423 fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
424 fieldValueAssign<TransactByField>( causer_r );
428 bool maySetTransact( bool val_r, TransactByValue causer )
430 bit::BitField<FieldType> savBitfield = _bitfield;
431 bool ret = setTransact (val_r, causer);
432 _bitfield = savBitfield;
437 bool setSoftLock( TransactByValue causer_r )
439 if ( ! setTransact( false, causer_r ) )
441 if ( fieldValueIs<TransactField>( KEEP_STATE )
442 && isLessThan<TransactByField>( causer_r ) )
443 fieldValueAssign<TransactByField>( causer_r );
447 /** Not the same as setTransact( false ).
449 bool resetTransact( TransactByValue causer_r )
451 if ( ! setTransact( false, causer_r ) )
453 if ( fieldValueIs<TransactField>( KEEP_STATE ) )
454 fieldValueAssign<TransactByField>( SOLVER );
458 /** Soft toggle between TRANSACT and KEEP_STATE.
459 * Similar to setTransact, but leaving KEEP_STATE also requires
460 * a superior \a causerLimit_r. So this is a kind of soft lock.
462 * // SOLVER wants to set TRANSACT, iff KEEP_STATE is
463 * // not superior to APPL_LOW.
464 * setSoftTransact( true, SOLVER, APPL_LOW );
467 bool setSoftTransact( bool toTansact_r, TransactByValue causer_r,
468 TransactByValue causerLimit_r )
470 if ( fieldValueIs<TransactField>( KEEP_STATE )
471 && toTansact_r != transacts()
472 && isGreaterThan<TransactByField>( causerLimit_r ) )
474 // any transact status change requires a superior causer.
477 return setTransact( toTansact_r, causer_r );
480 bool setSoftTransact( bool toTansact_r, TransactByValue causer_r )
481 { return setSoftTransact( toTansact_r, causer_r, causer_r ); }
483 bool maySetSoftTransact( bool val_r, TransactByValue causer,
484 TransactByValue causerLimit_r )
486 bit::BitField<FieldType> savBitfield = _bitfield;
487 bool ret = setSoftTransact( val_r, causer, causerLimit_r );
488 _bitfield = savBitfield;
492 bool maySetSoftTransact( bool val_r, TransactByValue causer )
493 { return maySetSoftTransact( val_r, causer, causer ); }
495 bool setToBeInstalled (TransactByValue causer)
497 if (isInstalled()) return false;
498 return setTransact (true, causer);
501 bool maySetToBeInstalled (TransactByValue causer)
503 bit::BitField<FieldType> savBitfield = _bitfield;
504 bool ret = setToBeInstalled (causer);
505 _bitfield = savBitfield;
509 bool setToBeUninstalled (TransactByValue causer)
511 if (!isInstalled()) return false;
512 return setTransact (true, causer);
515 bool maySetToBeUninstalled (TransactByValue causer)
517 bit::BitField<FieldType> savBitfield = _bitfield;
518 bool ret = setToBeUninstalled (causer);
519 _bitfield = savBitfield;
523 //------------------------------------------------------------------------
524 // *** These are only for the Resolver ***
526 bool setToBeUninstalledDueToObsolete ( )
528 if (!setToBeUninstalled (SOLVER)) return false;
529 fieldValueAssign<TransactDetailField>(DUE_TO_OBSOLETE);
533 bool setToBeUninstalledDueToUpgrade ( TransactByValue causer )
535 if (!setToBeUninstalled (causer)) return false;
536 fieldValueAssign<TransactDetailField>(DUE_TO_UPGRADE);
540 bool setToBeInstalledSoft ( )
543 || !setSoftTransact (true, SOLVER))
546 fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
550 bool setToBeUninstalledSoft ( )
553 || !setSoftTransact (true, SOLVER))
556 fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
560 bool maySetToBeUninstalledSoft ()
562 bit::BitField<FieldType> savBitfield = _bitfield;
563 bool ret = setToBeUninstalledSoft ();
564 _bitfield = savBitfield;
568 bool isSoftInstall () {
569 return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
572 bool isSoftUninstall () {
573 return fieldValueIs<TransactDetailField> (SOFT_REMOVE);
576 bool setSoftInstall (bool flag) {
577 fieldValueAssign<TransactDetailField>(flag?SOFT_INSTALL:0);
581 bool setSoftUninstall (bool flag) {
582 fieldValueAssign<TransactDetailField>(flag?SOFT_REMOVE:0);
586 bool setUndetermined ()
588 fieldValueAssign<ValidateField>(UNDETERMINED);
594 fieldValueAssign<ValidateField>(SATISFIED);
600 fieldValueAssign<ValidateField>(BROKEN);
604 bool setNonRelevant ()
606 fieldValueAssign<ValidateField>(NONRELEVANT);
611 { return fieldValueIs<SolverStateField>( SEEN ); }
613 bool setSeen (bool value)
615 fieldValueAssign<SolverStateField>( value ? SEEN : NORMAL );
619 bool setStatus( ResStatus newStatus_r )
621 // State field is immutable!
622 if ( _bitfield.value<StateField>() != newStatus_r._bitfield.value<StateField>() )
624 // Transaction state change allowed?
625 if ( ! setTransactValue( newStatus_r.getTransactValue(), newStatus_r.getTransactByValue() ) )
628 // Ok, we take it all..
629 _bitfield = newStatus_r._bitfield;
633 /** \name Builtin ResStatus constants. */
635 static const ResStatus toBeInstalled;
636 static const ResStatus toBeUninstalled;
637 static const ResStatus toBeUninstalledDueToUpgrade;
641 /** Ctor for intialization of builtin constants. */
642 ResStatus( StateValue s,
643 ValidateValue v = UNDETERMINED,
644 TransactValue t = KEEP_STATE,
645 InstallDetailValue i = EXPLICIT_INSTALL,
646 RemoveDetailValue r = EXPLICIT_REMOVE,
647 SolverStateValue ssv = NORMAL );
649 /** Return whether the corresponding Field has value \a val_r.
651 template<class _Field>
652 bool fieldValueIs( FieldType val_r ) const
653 { return _bitfield.isEqual<_Field>( val_r ); }
655 /** Set the corresponding Field to value \a val_r.
657 template<class _Field>
658 void fieldValueAssign( FieldType val_r )
659 { _bitfield.assign<_Field>( val_r ); }
661 /** compare two values.
663 template<class _Field>
664 bool isGreaterThan( FieldType val_r )
665 { return _bitfield.value<_Field>() > val_r; }
667 template<class _Field>
668 bool isLessThan( FieldType val_r )
669 { return _bitfield.value<_Field>() < val_r; }
672 BitFieldType _bitfield;
674 ///////////////////////////////////////////////////////////////////
676 /** \relates ResStatus Stream output */
677 std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
679 /** \relates ResStatus */
680 inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
681 { return lhs._bitfield == rhs._bitfield; }
683 /** \relates ResStatus */
684 inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
685 { return ! (lhs == rhs); }
687 /////////////////////////////////////////////////////////////////
689 ///////////////////////////////////////////////////////////////////
690 #endif // ZYPP_RESSTATUS_H