// Created on: 2003-03-04 // Created by: Pavel TELKOV // Copyright (c) 2003-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. // The original implementation copyright (c) RINA S.p.A. #ifndef Message_ExecStatus_HeaderFile #define Message_ExecStatus_HeaderFile #include "Message_Status.hxx" /** * Tiny class for extended handling of error / execution * status of algorithm in universal way. * * It is in fact a set of integers represented as a collection of bit flags * for each of four types of status; each status flag has its own symbolic * name and can be set/tested individually. * * The flags are grouped in semantic groups: * - No flags means nothing done * - Done flags correspond to some operation successfully completed * - Warning flags correspond to warning messages on some * potentially wrong situation, not harming algorithm execution * - Alarm flags correspond to more severe warnings about incorrect * user data, while not breaking algorithm execution * - Fail flags correspond to cases when algorithm failed to complete */ class Message_ExecStatus { private: //! Mask to separate bits indicating status type and index within the type enum StatusMask { MType = 0x0000ff00, MIndex = 0x000000ff }; static inline int getBitFlag(int theStatus) { return 0x1 << (theStatus & MIndex); } public: //!@name Creation and simple operations with statuses //!@{ //! Create empty execution status Message_ExecStatus() : myDone(Message_None), myWarn(Message_None), myAlarm(Message_None), myFail(Message_None) { } //! Initialise the execution status Message_ExecStatus(Message_Status theStatus) : myDone(Message_None), myWarn(Message_None), myAlarm(Message_None), myFail(Message_None) { Set(theStatus); } //! Sets a status flag void Set(Message_Status theStatus) { switch (TypeOfStatus(theStatus)) { case Message_DONE: myDone |= (getBitFlag(theStatus)); break; case Message_WARN: myWarn |= (getBitFlag(theStatus)); break; case Message_ALARM: myAlarm |= (getBitFlag(theStatus)); break; case Message_FAIL: myFail |= (getBitFlag(theStatus)); break; } } //! Check status for being set bool IsSet(Message_Status theStatus) const { switch (TypeOfStatus(theStatus)) { case Message_DONE: return (myDone & getBitFlag(theStatus)) != 0; case Message_WARN: return (myWarn & getBitFlag(theStatus)) != 0; case Message_ALARM: return (myAlarm & getBitFlag(theStatus)) != 0; case Message_FAIL: return (myFail & getBitFlag(theStatus)) != 0; } return false; } //! Clear one status void Clear(Message_Status theStatus) { switch (TypeOfStatus(theStatus)) { case Message_DONE: myDone &= ~(getBitFlag(theStatus)); return; case Message_WARN: myWarn &= ~(getBitFlag(theStatus)); return; case Message_ALARM: myAlarm &= ~(getBitFlag(theStatus)); return; case Message_FAIL: myFail &= ~(getBitFlag(theStatus)); return; } } //!@} //!@name Advanced: Group operations (useful for analysis) //!@{ //! Check if at least one status of each type is set bool IsDone() const { return myDone != Message_None; } bool IsFail() const { return myFail != Message_None; } bool IsWarn() const { return myWarn != Message_None; } bool IsAlarm() const { return myAlarm != Message_None; } //! Set all statuses of each type void SetAllDone() { myDone = ~0; } void SetAllWarn() { myWarn = ~0; } void SetAllAlarm() { myAlarm = ~0; } void SetAllFail() { myFail = ~0; } //! Clear all statuses of each type void ClearAllDone() { myDone = Message_None; } void ClearAllWarn() { myWarn = Message_None; } void ClearAllAlarm() { myAlarm = Message_None; } void ClearAllFail() { myFail = Message_None; } //! Clear all statuses void Clear() { myDone = myWarn = myAlarm = myFail = Message_None; } //! Add statuses to me from theOther execution status void Add(const Message_ExecStatus& theOther) { myDone |= theOther.myDone; myWarn |= theOther.myWarn; myAlarm |= theOther.myAlarm; myFail |= theOther.myFail; } const Message_ExecStatus& operator|=(const Message_ExecStatus& theOther) { Add(theOther); return *this; } //! Leave only the statuses common with theOther void And(const Message_ExecStatus& theOther) { myDone &= theOther.myDone; myWarn &= theOther.myWarn; myAlarm &= theOther.myAlarm; myFail &= theOther.myFail; } const Message_ExecStatus& operator&=(const Message_ExecStatus& theOther) { And(theOther); return *this; } //@} public: //!@name Advanced: Iteration and analysis of status flags //!@{ //! Definitions of range of available statuses enum StatusRange { FirstStatus = 1, StatusesPerType = 32, NbStatuses = 128, LastStatus = 129 }; //! Returns index of status in whole range [FirstStatus, LastStatus] static int StatusIndex(Message_Status theStatus) { switch (TypeOfStatus(theStatus)) { case Message_DONE: return 0 * StatusesPerType + LocalStatusIndex(theStatus); case Message_WARN: return 1 * StatusesPerType + LocalStatusIndex(theStatus); case Message_ALARM: return 2 * StatusesPerType + LocalStatusIndex(theStatus); case Message_FAIL: return 3 * StatusesPerType + LocalStatusIndex(theStatus); } return 0; } //! Returns index of status inside type of status (Done or Warn or, etc) //! in range [1, StatusesPerType] static int LocalStatusIndex(Message_Status theStatus) { return ((unsigned int)theStatus & (unsigned int)MIndex) + 1; } //! Returns status type (DONE, WARN, ALARM, or FAIL) static Message_StatusType TypeOfStatus(Message_Status theStatus) { return (Message_StatusType)((unsigned int)theStatus & (unsigned int)MType); } //! Returns status with index theIndex in whole range [FirstStatus, LastStatus] static Message_Status StatusByIndex(const int theIndex) { int indx = theIndex - 1; if (indx < 32) return (Message_Status)(Message_DONE + indx); else if (indx < 64) return (Message_Status)(Message_WARN + (indx - 32)); else if (indx < 96) return (Message_Status)(Message_ALARM + (indx - 64)); else if (indx < 128) return (Message_Status)(Message_FAIL + (indx - 96)); return Message_None; } //!@} private: int myDone; int myWarn; int myAlarm; int myFail; }; #endif