libzypp  10.5.0
ResStatus.h
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #ifndef ZYPP_RESSTATUS_H
00013 #define ZYPP_RESSTATUS_H
00014 
00015 #include <inttypes.h>
00016 #include <iosfwd>
00017 #include "zypp/Bit.h"
00018 
00020 namespace zypp
00021 { 
00022 
00023   namespace resstatus
00024   {
00025     class UserLockQueryManip;
00026     class StatusBackup;
00027   }
00028 
00030   //
00031   //    CLASS NAME : ResStatus
00032   //
00053   class ResStatus
00054   {
00055     friend std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
00056     friend bool operator==( const ResStatus & lhs, const ResStatus & rhs );
00057 
00058   public:
00065     typedef uint16_t FieldType;
00066     typedef bit::BitField<FieldType> BitFieldType;
00067     // Bit Ranges within FieldType defined by 1st bit and size:
00068     typedef bit::Range<FieldType,0,                          1> StateField;
00069     typedef bit::Range<FieldType,StateField::end,            2> ValidateField;
00070     typedef bit::Range<FieldType,ValidateField::end,         2> TransactField;
00071     typedef bit::Range<FieldType,TransactField::end,         2> TransactByField;
00072     typedef bit::Range<FieldType,TransactByField::end,       2> TransactDetailField;
00073     typedef bit::Range<FieldType,TransactDetailField::end,   1> LicenceConfirmedField;
00074     typedef bit::Range<FieldType,LicenceConfirmedField::end, 3> WeakField;
00075     typedef bit::Range<FieldType,WeakField::end,             1> UserLockQueryField; // internal
00076     // enlarge FieldType if more bit's needed. It's not yet
00077     // checked by the compiler.
00079   public:
00080 
00088     enum StateValue
00089       {
00090         UNINSTALLED = bit::RangeValue<StateField,0>::value,
00091         INSTALLED   = bit::RangeValue<StateField,1>::value
00092       };
00093     enum ValidateValue
00094       {
00095         UNDETERMINED = bit::RangeValue<ValidateField,0>::value,
00096         BROKEN       = bit::RangeValue<ValidateField,1>::value,
00097         SATISFIED    = bit::RangeValue<ValidateField,2>::value,
00098         NONRELEVANT  = bit::RangeValue<ValidateField,3>::value
00099       };
00100     enum TransactValue
00101       {
00102         KEEP_STATE = bit::RangeValue<TransactField,0>::value,
00103         LOCKED     = bit::RangeValue<TransactField,1>::value, // locked, must not transact
00104         TRANSACT   = bit::RangeValue<TransactField,2>::value  // transact according to state
00105       };
00106     enum TransactByValue
00107       {
00108         SOLVER    = bit::RangeValue<TransactByField,0>::value,
00109         APPL_LOW  = bit::RangeValue<TransactByField,1>::value,
00110         APPL_HIGH = bit::RangeValue<TransactByField,2>::value,
00111         USER      = bit::RangeValue<TransactByField,3>::value
00112       };
00113 
00114     enum DetailValue
00115       {
00117         NO_DETAIL = bit::RangeValue<TransactDetailField,0>::value,
00118       };
00119     enum InstallDetailValue
00120       {
00121         EXPLICIT_INSTALL = bit::RangeValue<TransactDetailField,0>::value,
00122         SOFT_INSTALL     = bit::RangeValue<TransactDetailField,1>::value
00123       };
00124     enum RemoveDetailValue
00125       {
00126         EXPLICIT_REMOVE = bit::RangeValue<TransactDetailField,0>::value,
00127         SOFT_REMOVE     = bit::RangeValue<TransactDetailField,1>::value,
00128         DUE_TO_OBSOLETE = bit::RangeValue<TransactDetailField,2>::value,
00129         DUE_TO_UPGRADE  = bit::RangeValue<TransactDetailField,3>::value
00130       };
00131 
00132     enum LicenceConfirmedValue
00133       {
00134         LICENCE_UNCONFIRMED = bit::RangeValue<LicenceConfirmedField,0>::value,
00135         LICENCE_CONFIRMED   = bit::RangeValue<LicenceConfirmedField,1>::value
00136       };
00137 
00138     enum WeakValue      // Unlike the other fields those are BITS that may be or'ed!
00139       {
00140         NO_WEAK                 = bit::RangeValue<WeakField,0>::value,
00141         SUGGESTED               = bit::RangeValue<WeakField,1<<0>::value,
00142         RECOMMENDED             = bit::RangeValue<WeakField,1<<1>::value,
00143         ORPHANED                = bit::RangeValue<WeakField,1<<2>::value
00144       };
00145 
00146     enum UserLockQuery // internal
00147       {
00148         USERLOCK_NOMATCH        = bit::RangeValue<UserLockQueryField,0>::value,
00149         USERLOCK_MATCH          = bit::RangeValue<UserLockQueryField,1>::value
00150       };
00152 
00153   public:
00154 
00156     ResStatus();
00157 
00159     ResStatus( bool isInstalled_r );
00160 
00162     ~ResStatus();
00163 
00169     BitFieldType bitfield() const
00170     { return _bitfield; }
00171 
00172   public:
00173 
00174     bool isLicenceConfirmed() const
00175     { return fieldValueIs<LicenceConfirmedField>( LICENCE_CONFIRMED ); }
00176 
00177     void setLicenceConfirmed( bool toVal_r = true )
00178     { fieldValueAssign<LicenceConfirmedField>( toVal_r ? LICENCE_CONFIRMED : LICENCE_UNCONFIRMED ); }
00179 
00180   public:
00181     bool isRecommended() const
00182     { return _bitfield.test( RECOMMENDED ); }
00183 
00184     bool isSuggested() const
00185     { return _bitfield.test( SUGGESTED ); }
00186 
00187     bool isOrphaned() const
00188     { return _bitfield.test( ORPHANED ); }
00189 
00190     void resetWeak()
00191     { return fieldValueAssign<WeakField>( NO_WEAK ); }
00192 
00193     void setRecommended( bool toVal_r = true )
00194     { _bitfield.set( RECOMMENDED, toVal_r ); }
00195 
00196     void setSuggested( bool toVal_r = true )
00197     { _bitfield.set( SUGGESTED, toVal_r ); }
00198 
00199     void setOrphaned( bool toVal_r = true )
00200     { _bitfield.set( ORPHANED, toVal_r ); }
00201 
00202   public:
00203     ValidateValue validate() const
00204     { return (ValidateValue)_bitfield.value<ValidateField>(); }
00205 
00206     bool isUndetermined() const
00207     { return fieldValueIs<ValidateField>( UNDETERMINED ); }
00208 
00209     bool isSatisfied() const
00210     { return fieldValueIs<ValidateField>( SATISFIED ); }
00211 
00212     bool isBroken() const
00213     { return fieldValueIs<ValidateField>( BROKEN ); }
00214 
00215     bool isNonRelevant() const
00216     { return fieldValueIs<ValidateField>( NONRELEVANT ); }
00217 
00218   public:
00219     // These two are IMMUTABLE!
00220 
00221     bool isInstalled() const
00222     { return fieldValueIs<StateField>( INSTALLED ); }
00223 
00224     bool isUninstalled() const
00225     { return fieldValueIs<StateField>( UNINSTALLED ); }
00226 
00227   public:
00228 
00229     bool staysInstalled() const
00230     { return isInstalled() && !transacts(); }
00231 
00232     bool wasInstalled() const { return staysInstalled(); }      //for old status
00233 
00234     bool isToBeInstalled() const
00235     { return isUninstalled() && transacts(); }
00236 
00237     bool staysUninstalled() const
00238     { return isUninstalled() && !transacts(); }
00239 
00240     bool wasUninstalled() const { return staysUninstalled(); }  // for old status
00241 
00242     bool isToBeUninstalled() const
00243     { return isInstalled() && transacts(); }
00244 
00245     bool isLocked() const
00246     { return fieldValueIs<TransactField>( LOCKED ); }
00247 
00248     bool isUserLocked() const
00249     { return isLocked() && isByUser(); }
00250 
00251     bool isSoftLocked( TransactByValue causer_r = USER ) const
00252     { return isKept() && fieldValueIs<TransactByField>( causer_r ); }
00253 
00254     bool isKept() const
00255     { return fieldValueIs<TransactField>( KEEP_STATE ); }
00256 
00257     bool transacts() const
00258     { return fieldValueIs<TransactField>( TRANSACT ); }
00259 
00260     TransactValue getTransactValue() const
00261     { return (TransactValue)_bitfield.value<TransactField>(); }
00262 
00264     bool onSystem() const
00265     { return( isInstalled() != transacts() ); }
00266 
00268     bool offSystem() const
00269     { return ! onSystem(); }
00270 
00271     bool isBySolver() const
00272     { return fieldValueIs<TransactByField>( SOLVER ); }
00273 
00274     bool isByApplLow() const
00275     { return fieldValueIs<TransactByField>( APPL_LOW ); }
00276 
00277     bool isByApplHigh() const
00278     { return fieldValueIs<TransactByField>( APPL_HIGH ); }
00279 
00280     bool isByUser() const
00281     { return fieldValueIs<TransactByField>( USER ); }
00282 
00283     TransactByValue getTransactByValue() const
00284     { return (TransactByValue)_bitfield.value<TransactByField>(); }
00285 
00286     bool setTransactByValue(TransactByValue causer)
00287     {
00288         if ( isLessThan<TransactByField>( causer ) ) {
00289             fieldValueAssign<TransactByField>( causer );
00290             return true;
00291         } else {
00292             return false;
00293         }
00294     }
00295 
00296     bool isToBeUninstalledDueToObsolete () const
00297     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
00298 
00299     bool isToBeUninstalledDueToUpgrade() const
00300     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
00301 
00302     bool isToBeInstalledSoft () const
00303     { return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
00304 
00305     bool isToBeInstalledNotSoft () const
00306     { return isToBeInstalled() && !fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
00307 
00308     bool isToBeUninstalledSoft () const
00309     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
00310 
00311   private:
00312 
00315     friend class resstatus::UserLockQueryManip;
00316 
00317     bool isUserLockQueryMatch() const
00318     { return fieldValueIs<UserLockQueryField>( USERLOCK_MATCH ); }
00319 
00320     void setUserLockQueryMatch( bool match_r )
00321     { fieldValueAssign<UserLockQueryField>( match_r ? USERLOCK_MATCH : USERLOCK_NOMATCH ); }
00323 
00324   public:
00325 
00326     //------------------------------------------------------------------------
00327     // get/set functions, returnig \c true if requested status change
00328     // was successfull (i.e. leading to the desired transaction).
00329     // If a lower level (e.g.SOLVER) wants to transact, but it's
00330     // already set by a higher level, \c true should be returned.
00331     // Removing a higher levels transaction bit should fail.
00332     //
00333     // The may functions checks only, if the action would return true
00334     // if it is called.
00335 
00339     bool setTransactValue( TransactValue newVal_r, TransactByValue causer_r )
00340     {
00341       switch ( newVal_r )
00342         {
00343         case KEEP_STATE:
00344           return setTransact( false, causer_r );
00345           break;
00346         case LOCKED:
00347           return setLock( true, causer_r );
00348           break;
00349         case TRANSACT:
00350           return setTransact( true, causer_r );
00351           break;
00352         }
00353       return false;
00354     }
00355 
00356     bool maySetTransactValue( TransactValue newVal_r, TransactByValue causer_r )
00357     {
00358         bit::BitField<FieldType> savBitfield = _bitfield;
00359         bool ret = setTransactValue( newVal_r, causer_r );
00360         _bitfield = savBitfield;
00361         return ret;
00362     }
00363 
00369     bool setLock( bool toLock_r, TransactByValue causer_r )
00370     {
00371       if ( toLock_r == isLocked() )
00372         {
00373           // we're already in the desired state, but in case of
00374           // LOCKED, remember a superior causer.
00375           if ( isLocked() && isLessThan<TransactByField>( causer_r ) )
00376             fieldValueAssign<TransactByField>( causer_r );
00377            return true;
00378         }
00379       // Here: Lock status is to be changed:
00380       if ( causer_r != USER && causer_r != APPL_HIGH )
00381         return false;
00382       if ( toLock_r ) {
00383         // We're in unlocked state, which includes TRANSACT.
00384         // Causer must be allowed to reset this. But from
00385         // KEEP_STATE every causer is allowed to set the lock.
00386         if ( ! setTransact( false, causer_r ) )
00387           return false;
00388         fieldValueAssign<TransactField>( LOCKED );
00389         fieldValueAssign<TransactByField>( causer_r );
00390       } else {
00391         // To leave Locked state it needs a superior causer.
00392         if ( isGreaterThan<TransactByField>( causer_r ) )
00393           return false;
00394         fieldValueAssign<TransactField>( KEEP_STATE );
00395         fieldValueAssign<TransactByField>( SOLVER ); // reset to lowest causer
00396                                                      // in order to distinguish from keep_state_by_user
00397       }
00398       return true;
00399     }
00400 
00401     bool maySetLock( bool to_r, TransactByValue causer_r )
00402     {
00403         bit::BitField<FieldType> savBitfield = _bitfield;
00404         bool ret = setLock( to_r, causer_r );
00405         _bitfield = savBitfield;
00406         return ret;
00407     }
00408 
00414     bool setTransact( bool toTansact_r, TransactByValue causer_r )
00415     {
00416       if ( toTansact_r == transacts() )
00417         {
00418           // we're already in the desired state, but in case of
00419           // TRANSACT, remember a superior causer.
00420           if ( transacts() && isLessThan<TransactByField>( causer_r ) )
00421               fieldValueAssign<TransactByField>( causer_r );
00422 
00423           fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
00424           return true;
00425         }
00426       // Here: transact status is to be changed:
00427       if (    ! fieldValueIs<TransactField>( KEEP_STATE )
00428               && isGreaterThan<TransactByField>( causer_r ) ) {
00429         return false;
00430       }
00431 
00432       if ( toTansact_r )
00433       {
00434           fieldValueAssign<TransactField>( TRANSACT );
00435       }
00436       else
00437       {
00438           fieldValueAssign<TransactField>( KEEP_STATE );
00439       }
00440       fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
00441       fieldValueAssign<TransactByField>( causer_r );
00442       return true;
00443     }
00444 
00445     bool maySetTransact( bool val_r, TransactByValue causer )
00446     {
00447         bit::BitField<FieldType> savBitfield = _bitfield;
00448         bool ret = setTransact (val_r, causer);
00449         _bitfield = savBitfield;
00450         return ret;
00451     }
00452 
00454     bool setSoftLock( TransactByValue causer_r )
00455     {
00456       if ( ! setTransact( false, causer_r ) )
00457         return false;
00458       if ( fieldValueIs<TransactField>( KEEP_STATE )
00459            && isLessThan<TransactByField>( causer_r ) )
00460         fieldValueAssign<TransactByField>( causer_r );
00461       return true;
00462     }
00463 
00466     bool resetTransact( TransactByValue causer_r )
00467     {
00468       if ( ! setTransact( false, causer_r ) )
00469         return false;
00470       if ( fieldValueIs<TransactField>( KEEP_STATE ) )
00471         fieldValueAssign<TransactByField>( SOLVER );
00472       return true;
00473     }
00474 
00484     bool setSoftTransact( bool toTansact_r, TransactByValue causer_r,
00485                           TransactByValue causerLimit_r )
00486     {
00487       if ( fieldValueIs<TransactField>( KEEP_STATE )
00488            && toTansact_r != transacts()
00489            && isGreaterThan<TransactByField>( causerLimit_r ) )
00490         {
00491           // any transact status change requires a superior causer.
00492           return false;
00493         }
00494       return setTransact( toTansact_r, causer_r );
00495     }
00496 
00497     bool setSoftTransact( bool toTansact_r, TransactByValue causer_r )
00498     { return setSoftTransact( toTansact_r, causer_r, causer_r ); }
00499 
00500     bool maySetSoftTransact( bool val_r, TransactByValue causer,
00501                              TransactByValue causerLimit_r )
00502     {
00503         bit::BitField<FieldType> savBitfield = _bitfield;
00504         bool ret = setSoftTransact( val_r, causer, causerLimit_r );
00505         _bitfield = savBitfield;
00506         return ret;
00507     }
00508 
00509     bool maySetSoftTransact( bool val_r, TransactByValue causer )
00510     { return maySetSoftTransact( val_r, causer, causer ); }
00511 
00512     bool setToBeInstalled (TransactByValue causer)
00513     {
00514       if (isInstalled()) return false;
00515       return setTransact (true, causer);
00516     }
00517 
00518     bool maySetToBeInstalled (TransactByValue causer)
00519     {
00520         bit::BitField<FieldType> savBitfield = _bitfield;
00521         bool ret = setToBeInstalled (causer);
00522         _bitfield = savBitfield;
00523         return ret;
00524     }
00525 
00526     bool setToBeUninstalled (TransactByValue causer)
00527     {
00528       if (!isInstalled()) return false;
00529       return setTransact (true, causer);
00530     }
00531 
00532     bool maySetToBeUninstalled (TransactByValue causer)
00533     {
00534         bit::BitField<FieldType> savBitfield = _bitfield;
00535         bool ret = setToBeUninstalled (causer);
00536         _bitfield = savBitfield;
00537         return ret;
00538     }
00539 
00540     //------------------------------------------------------------------------
00541     // *** These are only for the Resolver ***
00542 
00543     bool setToBeUninstalledDueToObsolete ( )
00544     {
00545       if (!setToBeUninstalled (SOLVER)) return false;
00546       fieldValueAssign<TransactDetailField>(DUE_TO_OBSOLETE);
00547       return true;
00548     }
00549 
00550     bool setToBeUninstalledDueToUpgrade ( TransactByValue causer )
00551     {
00552       if (!setToBeUninstalled (causer)) return false;
00553       fieldValueAssign<TransactDetailField>(DUE_TO_UPGRADE);
00554       return true;
00555     }
00556 
00557     bool setToBeInstalledSoft ( )
00558     {
00559       if (isInstalled()
00560           || !setSoftTransact (true, SOLVER))
00561           return false;
00562 
00563       fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
00564       return true;
00565     }
00566 
00567     bool setToBeUninstalledSoft ( )
00568     {
00569       if (!isInstalled()
00570           || !setSoftTransact (true, SOLVER))
00571           return false;
00572 
00573       fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
00574       return true;
00575     }
00576 
00577     bool maySetToBeUninstalledSoft ()
00578     {
00579         bit::BitField<FieldType> savBitfield = _bitfield;
00580         bool ret = setToBeUninstalledSoft ();
00581         _bitfield = savBitfield;
00582         return ret;
00583     }
00584 
00585     bool isSoftInstall () {
00586         return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
00587     }
00588 
00589     bool isSoftUninstall () {
00590         return fieldValueIs<TransactDetailField> (SOFT_REMOVE);
00591     }
00592 
00593     bool setSoftInstall (bool flag) {
00594         fieldValueAssign<TransactDetailField>(flag?SOFT_INSTALL:0);
00595         return true;
00596     }
00597 
00598     bool setSoftUninstall (bool flag) {
00599         fieldValueAssign<TransactDetailField>(flag?SOFT_REMOVE:0);
00600         return true;
00601     }
00602 
00603     bool setUndetermined ()
00604     {
00605       fieldValueAssign<ValidateField>(UNDETERMINED);
00606       return true;
00607     }
00608 
00609     bool setSatisfied ()
00610     {
00611       fieldValueAssign<ValidateField>(SATISFIED);
00612       return true;
00613     }
00614 
00615     bool setBroken ()
00616     {
00617       fieldValueAssign<ValidateField>(BROKEN);
00618       return true;
00619     }
00620 
00621     bool setNonRelevant ()
00622     {
00623       fieldValueAssign<ValidateField>(NONRELEVANT);
00624       return true;
00625     }
00626 
00627     bool setStatus( ResStatus newStatus_r )
00628     {
00629       // State field is immutable!
00630       if ( _bitfield.value<StateField>() != newStatus_r._bitfield.value<StateField>() )
00631         return false;
00632       // Transaction state change allowed?
00633       if ( ! setTransactValue( newStatus_r.getTransactValue(), newStatus_r.getTransactByValue() ) )
00634         return false;
00635 
00636       // Ok, we take it all..
00637       _bitfield = newStatus_r._bitfield;
00638       return true;
00639     }
00640 
00643     static const ResStatus toBeInstalled;
00644     static const ResStatus toBeUninstalled;
00645     static const ResStatus toBeUninstalledDueToUpgrade;
00646     static const ResStatus toBeUninstalledDueToObsolete;
00648 
00649   private:
00651     ResStatus( StateValue s,
00652                ValidateValue v      = UNDETERMINED,
00653                TransactValue t      = KEEP_STATE,
00654                InstallDetailValue i = EXPLICIT_INSTALL,
00655                RemoveDetailValue r  = EXPLICIT_REMOVE );
00656 
00659     template<class _Field>
00660       bool fieldValueIs( FieldType val_r ) const
00661     { return _bitfield.isEqual<_Field>( val_r ); }
00662 
00665     template<class _Field>
00666       void fieldValueAssign( FieldType val_r )
00667     { _bitfield.assign<_Field>( val_r ); }
00668 
00671     template<class _Field>
00672       bool isGreaterThan( FieldType val_r )
00673     { return _bitfield.value<_Field>() > val_r; }
00674 
00675     template<class _Field>
00676       bool isLessThan( FieldType val_r )
00677     { return _bitfield.value<_Field>() < val_r; }
00678 
00679   private:
00680     friend class resstatus::StatusBackup;
00681     BitFieldType _bitfield;
00682   };
00684 
00686   std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
00687 
00689   std::ostream & operator<<( std::ostream & str, ResStatus::TransactValue obj );
00690 
00692   std::ostream & operator<<( std::ostream & str, ResStatus::TransactByValue obj );
00693 
00695   inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
00696   { return lhs._bitfield == rhs._bitfield; }
00697 
00699   inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
00700   { return ! (lhs == rhs); }
00701 
00703 
00704   namespace resstatus
00705   {
00706     class StatusBackup
00707     {
00708       public:
00709         StatusBackup()
00710         : _status( 0 )
00711         {}
00712 
00713         StatusBackup( ResStatus & status_r )
00714         : _status( &status_r )
00715         , _bitfield( _status->_bitfield )
00716         {}
00717 
00718         void replay()
00719         { if ( _status ) _status->_bitfield = _bitfield; }
00720 
00721       private:
00722         ResStatus *             _status;
00723         ResStatus::BitFieldType _bitfield;
00724     };
00725   }
00726 
00728 } // namespace zypp
00730 #endif // ZYPP_RESSTATUS_H