LCOV - code coverage report
Current view: top level - INDI/libcommon - IndiProperty.hpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 0.0 % 4 0
Test Date: 2026-01-03 21:03:39 Functions: 0.0 % 3 0

            Line data    Source code
       1              : /// IndiProperty.hpp
       2              : ///
       3              : /// @author Paul Grenz
       4              : ///
       5              : /// This class represents a list of INDI elements with additional information
       6              : /// associated with it. All access is protected by a read-write lock.
       7              : ///
       8              : ////////////////////////////////////////////////////////////////////////////////
       9              : 
      10              : #ifndef INDI_PROPERTY_HPP
      11              : #define INDI_PROPERTY_HPP
      12              : #pragma once
      13              : 
      14              : #include <string>
      15              : #include <map>
      16              : #include <exception>
      17              : #include "ReadWriteLock.hpp"
      18              : #include "TimeStamp.hpp"
      19              : #include "IndiElement.hpp"
      20              : 
      21              : namespace pcf
      22              : {
      23              : class IndiProperty
      24              : {
      25              :   public:
      26              :     enum Error
      27              :     {
      28              :       ErrNone =                   0,
      29              :       ErrCouldntFindElement =    -3,
      30              :       ErrElementAlreadyExists =  -5,
      31              :       ErrIndexOutOfBounds =      -6,
      32              :       ErrWrongElementType =      -7,
      33              :       ErrUndefined =          -9999
      34              :     };
      35              : 
      36              :     enum BLOBEnableType
      37              :     {
      38              :       UnknownBLOBEnable = 0,
      39              :       Also = 1,
      40              :       Only,
      41              :       Never
      42              :     };
      43              : 
      44              :     enum PropertyStateType
      45              :     {
      46              :       UnknownPropertyState = 0,
      47              :       Alert = 1,
      48              :       Busy,
      49              :       Ok,
      50              :       Idle
      51              :     };
      52              : 
      53              :     enum SwitchRuleType
      54              :     {
      55              :       UnknownSwitchRule = 0,
      56              :       AnyOfMany = 1,
      57              :       AtMostOne,
      58              :       OneOfMany
      59              :     };
      60              : 
      61              :     enum PropertyPermType
      62              :     {
      63              :       UnknownPropertyPerm = 0,
      64              :       ReadOnly = 1,
      65              :       ReadWrite,
      66              :       WriteOnly
      67              :     };
      68              : 
      69              :     // These are the types that a property can be.
      70              :     // The order and enumeration of this list is important.
      71              :     // Do not add or change enumerations here without adjusting
      72              :     // the indexing of the 'allowed attributes' list.
      73              :     enum Type
      74              :     {
      75              :       Unknown = 0,
      76              :       BLOB,
      77              :       Light,
      78              :       Number,
      79              :       Switch,
      80              :       Text,
      81              :     };
      82              : 
      83              :   public:
      84              :     class Excep : public std::exception
      85              :     {
      86              :       private:
      87              :         Excep() {}
      88              : 
      89              :       public:
      90            0 :         explicit Excep(const IndiProperty::Error &tCode ) : m_tCode( tCode ) {}
      91              : 
      92            0 :         ~Excep() throw() {}
      93              :         const IndiProperty::Error       &getCode() const
      94              :         {
      95              :           return m_tCode;
      96              :         }
      97            0 :         virtual const char* what() const throw()
      98              :         {
      99            0 :           return IndiProperty::getErrorMsg( m_tCode ).c_str();
     100              :         }
     101              :       private:
     102              :         IndiProperty::Error m_tCode;
     103              :     };
     104              : 
     105              :     // Constructor/copy constructor/destructor.
     106              :   public:
     107              :     /// Constructor.
     108              :     IndiProperty();
     109              :     /// Constructor with a type. This will be used often.
     110              :     explicit IndiProperty( const Type &tType );
     111              : 
     112              :     /// Constructor with a type, device and name. This will be used often.
     113              :     IndiProperty( const Type &tType,
     114              :                   const std::string &szDevice,
     115              :                   const std::string &szName );
     116              :     /// Constructor with a type, device, name, state, and perm.
     117              :     IndiProperty( const Type &tType,
     118              :                   const std::string &szDevice,
     119              :                   const std::string &szName,
     120              :                   const PropertyStateType &tState,
     121              :                   const PropertyPermType &tPerm,
     122              :                   const SwitchRuleType &tRule = UnknownSwitchRule );
     123              :     /// Copy constructor.
     124              :     IndiProperty( const IndiProperty &ipRhs );
     125              :     /// Destructor.
     126              :     virtual ~IndiProperty();
     127              : 
     128              :     // Operators.
     129              :   public:
     130              :     /// Assigns the internal data of this object from an existing one.
     131              :     const IndiProperty &operator= ( const IndiProperty &ipRhs );
     132              :     /// This is an alternate way of calling 'setBLOBEnable'.
     133              :     const BLOBEnableType &operator= ( const BLOBEnableType &tValue );
     134              :     /// Returns true if we have an exact match (value as well).
     135              :     bool operator== ( const IndiProperty &ipRhs ) const;
     136              :     // Return a reference to an element so it can be modified.
     137              :     const IndiElement &operator[] ( const std::string& szName ) const;
     138              :     IndiElement &operator[] ( const std::string& szName );
     139              :     // Return a reference to an element so it can be modified.
     140              :     const IndiElement &operator[] ( const unsigned int& uiIndex ) const;
     141              :     IndiElement &operator[] ( const unsigned int& uiIndex );
     142              : 
     143              :     // Methods.
     144              :   public:
     145              :     /// Reset this object.
     146              :     void clear();
     147              :     /// Compares one property with another instance. The values may not match,
     148              :     /// but the type must match, as must the device and name. The names of all
     149              :     /// the elements must match as well.
     150              :     bool compareProperty( const IndiProperty &ipComp ) const;
     151              :     /// Compares one element value contained in this class with another
     152              :     /// instance. The type must match, as must the device and name.
     153              :     /// The name of this element must match as well.
     154              :     bool compareValue( const IndiProperty &ipComp,
     155              :                        const std::string &szElementName ) const;
     156              :     /// Compares all the element values contained in this class with another
     157              :     /// instance. The type must match, as must the device and name. The number
     158              :     /// and names of all the elements must match as well.
     159              :     bool compareValues( const IndiProperty &ipComp ) const;
     160              :     /// Returns a string with each attribute enumerated.
     161              :     std::string createString() const;
     162              :     /// Create a name for this property based on the device name and the
     163              :     /// property name. A '.' is used as the character to join them together.
     164              :     /// This key should be unique for all indi devices.
     165              :     std::string createUniqueKey() const;
     166              : 
     167              :     // A getter for blob enable.
     168              :     const BLOBEnableType &getBLOBEnable() const;
     169              : 
     170              :     // A getter for each attribute.
     171              :     const std::string &getDevice() const;
     172              :     const std::string &getGroup() const;
     173              :     const std::string &getLabel() const;
     174              :     const std::string &getMessage() const;
     175              :     const std::string &getName() const;
     176              :     const PropertyPermType &getPerm() const;
     177              :     const SwitchRuleType &getRule() const;
     178              :     const PropertyStateType &getState() const;
     179              :     const double &getTimeout() const;
     180              :     const pcf::TimeStamp &getTimeStamp() const;
     181              :     /// There is only a 'getter' for the type, since it can't be changed.
     182              :     const Type &getType() const;
     183              :     const std::string &getVersion() const;
     184              :     /// Compares one element value contained in this class with another
     185              :     /// instance. The type must match, as must the device and name.
     186              :     /// The name of this element must match as well, and the value must be a
     187              :     /// new, non-blank value.
     188              :     bool hasNewValue( const IndiProperty &ipComp,
     189              :                       const std::string &szElementName ) const;
     190              :     const bool &isRequested() const;
     191              : 
     192              :     /// Returns the string type given the enumerated type.
     193              :     /// Throws exception if string is not found.
     194              :     static std::string convertTypeToString( const Type &tType );
     195              :     /// Returns the enumerated type given the tag.
     196              :     static Type convertStringToType( const std::string &szTag );
     197              :     /// Returns the string type given the enumerated type.
     198              :     static std::string getBLOBEnableString( const BLOBEnableType &tType );
     199              :     /// Returns the enumerated type given the string type.
     200              :     static BLOBEnableType getBLOBEnableType( const std::string &szType );
     201              :     /// Returns the string type given the enumerated type.
     202              :     static std::string getPropertyPermString( const PropertyPermType &tType );
     203              :     /// Returns the enumerated type given the string type.
     204              :     static PropertyPermType getPropertyPermType( const std::string &szType );
     205              :     /// Returns the string type given the enumerated type.
     206              :     static std::string getPropertyStateString( const PropertyStateType &tType );
     207              :     /// Returns the enumerated type given the string type.
     208              :     static PropertyStateType getPropertyStateType( const std::string &szType );
     209              :     /// Returns the string type given the enumerated type.
     210              :     static std::string getSwitchRuleString( const SwitchRuleType &tType );
     211              :     /// Returns the enumerated type given the string type.
     212              :     static SwitchRuleType getSwitchRuleType( const std::string &szType );
     213              :     /// Returns the message concerning the error.
     214              :     static std::string getErrorMsg( const int &nErr );
     215              :     /// Ensures that a name conforms to the INDI standard and can be used as
     216              :     /// an identifier. This means:
     217              :     ///     1) No ' ' - these will be converted to '_'
     218              :     ///     2) No '.' - these will be converted to '___'
     219              :     ///     3) No Unprintable chars - these will be converted to '_'
     220              :     static std::string scrubName( const std::string &szName );
     221              : 
     222              :     /// Returns the number of elements.
     223              :     unsigned int getNumElements() const;
     224              : 
     225              :     /// Returns true if this contains a valid BLOB-enable value.
     226              :     bool hasValidBLOBEnable() const;
     227              :     /// Returns true if this contains a non-empty 'device' attribute.
     228              :     bool hasValidDevice() const;
     229              :     /// Returns true if this contains a non-empty 'group' attribute.
     230              :     bool hasValidGroup() const;
     231              :     /// Returns true if this contains a non-empty 'label' attribute.
     232              :     bool hasValidLabel() const;
     233              :     /// Returns true if this contains a non-empty 'message' attribute.
     234              :     bool hasValidMessage() const;
     235              :     /// Returns true if this contains a non-empty 'name' attribute.
     236              :     bool hasValidName() const;
     237              :     /// Returns true if this contains a non-empty 'perm' attribute.
     238              :     bool hasValidPerm() const;
     239              :     /// Returns true if this contains a non-empty 'rule' attribute.
     240              :     bool hasValidRule() const;
     241              :     /// Returns true if this contains a non-empty 'state' attribute.
     242              :     bool hasValidState() const;
     243              :     /// Returns true if this contains a non-empty 'timeout' attribute.
     244              :     bool hasValidTimeout() const;
     245              :     /// Returns true if this contains a non-empty 'timestamp' attribute.
     246              :     bool hasValidTimeStamp() const;
     247              :     /// Returns true if this contains a non-empty 'version' attribute.
     248              :     bool hasValidVersion() const;
     249              : 
     250              :     /// All the attribute setters.
     251              :     void setBLOBEnable( const BLOBEnableType &tValue );
     252              :     void setDevice( const std::string &szValue );
     253              :     void setGroup( const std::string &szValue );
     254              :     void setLabel( const std::string &szValue );
     255              :     void setMessage( const std::string &szValue );
     256              :     void setName( const std::string &szValue );
     257              :     void setPerm( const PropertyPermType &tValue );
     258              :     void setRequested( const bool &oRequested );
     259              :     void setRule( const SwitchRuleType &tValue );
     260              :     void setState( const PropertyStateType &tValue );
     261              :     void setTimeout( const double &xValue );
     262              :     void setTimeStamp( const pcf::TimeStamp &tsValue );
     263              :     void setVersion( const std::string &szValue );
     264              : 
     265              :     // Element functions.
     266              :   public:
     267              :     // Return a reference to an element so it can be modified.
     268              :     const IndiElement &at( const std::string& szName ) const;
     269              :     IndiElement &at( const std::string& szName );
     270              :     // Return a reference to an element so it can be modified.
     271              :     const IndiElement &at( const unsigned int& uiIndex ) const;
     272              :     IndiElement &at( const unsigned int& uiIndex );
     273              :     /// Adds a new element.
     274              :     /// Throws if the element already exists.
     275              :     void add( const pcf::IndiElement &ieNew );
     276              :     /// Adds an element if it doesn't exist. If it does exist, this is a no-op.
     277              :     void addIfNoExist( const pcf::IndiElement &ieNew );
     278              :     ///  Returns true if the element 'szElementName' exists, false otherwise.
     279              :     bool find( const std::string &szElementName ) const;
     280              :     /// Get the entire map of elements.
     281              :     const std::map<std::string, pcf::IndiElement> &getElements() const;
     282              :     /// Removes an element named 'szElementName'.
     283              :     /// Throws if the element doesn't exist.
     284              :     void remove( const std::string &szElementName );
     285              :     /// Set the entire map of elements.
     286              :     void setElements( const std::map<std::string, pcf::IndiElement> &mapElements );
     287              :     /// Updates the value of an element named 'szElementName'.
     288              :     /// Throws if the element doesn't exist.
     289              :     void update( const std::string &szElementName,
     290              :                  const pcf::IndiElement &ieUpdate );
     291              :     /// Updates the value of an element, adds it if it doesn't exist.
     292              :     void update( const pcf::IndiElement &ieNew );
     293              : 
     294              :     // Members.
     295              :   private:
     296              : 
     297              :     std::string m_szDevice;
     298              : 
     299              :     std::string m_szGroup;
     300              : 
     301              :     std::string m_szLabel;
     302              : 
     303              :     std::string m_szMessage;
     304              : 
     305              :     std::string m_szName;
     306              : 
     307              :     PropertyPermType m_tPerm {UnknownPropertyPerm};
     308              : 
     309              :     SwitchRuleType m_tRule {UnknownSwitchRule};
     310              : 
     311              :     PropertyStateType m_tState {UnknownPropertyState};
     312              : 
     313              :     double m_xTimeout {0.0f};
     314              : 
     315              :     // This is a flag which can be used to show that this property
     316              :     // has been requested by a client. This is not managed automatically.
     317              :     bool m_oRequested {false};
     318              : 
     319              :     pcf::TimeStamp m_tsTimeStamp;
     320              : 
     321              :     std::string m_szVersion;
     322              : 
     323              :     /// This can also be the value.
     324              :     BLOBEnableType m_beValue {UnknownBLOBEnable};
     325              : 
     326              :     /// A dictionary of elements, indexable by name.
     327              :     std::map<std::string, pcf::IndiElement> m_mapElements;
     328              : 
     329              :     /// The type of this object. It cannot be changed.
     330              :     pcf::IndiProperty::Type m_tType {Unknown};
     331              : 
     332              :     // A read write lock to protect the internal data.
     333              :     mutable pcf::ReadWriteLock m_rwData;
     334              : 
     335              : }; // class IndiProperty
     336              : 
     337              : } // namespace pcf
     338              : 
     339              : ////////////////////////////////////////////////////////////////////////////////
     340              : 
     341              : #endif // INDI_PROPERTY_HPP
        

Generated by: LCOV version 2.0-1