libzypp
10.5.0
|
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