LCOV - code coverage report
Current view: top level - DCPS - SequenceNumber.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 75 84 89.3 %
Date: 2023-04-30 01:32:43 Functions: 21 22 95.5 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *
       4             :  * Distributed under the OpenDDS License.
       5             :  * See: http://www.opendds.org/license.html
       6             :  */
       7             : 
       8             : #ifndef OPENDDS_DCPS_SEQUENCENUMBER_H
       9             : #define OPENDDS_DCPS_SEQUENCENUMBER_H
      10             : 
      11             : #include "Serializer.h"
      12             : 
      13             : #include <ace/Global_Macros.h>
      14             : 
      15             : #if !defined (ACE_LACKS_PRAGMA_ONCE)
      16             : #pragma once
      17             : #endif /* ACE_LACKS_PRAGMA_ONCE */
      18             : 
      19             : #include <utility>
      20             : 
      21             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      22             : 
      23             : namespace OpenDDS {
      24             : namespace DCPS {
      25             : 
      26             : /// Sequence number abstraction.  Only allows positive 64 bit values.
      27             : class OpenDDS_Dcps_Export SequenceNumber {
      28             : public:
      29             :   typedef ACE_INT64 Value;
      30             :   /// Construct with a value, default to one (starting point).
      31        3833 :   SequenceNumber(Value value = INITIAL_VALUE) {
      32        3833 :     setValue(value);
      33        3833 :   }
      34             : 
      35             :   /// Pre-increment.
      36          67 :   SequenceNumber& operator++() {
      37          67 :     if (this->low_ == ACE_UINT32_MAX) {
      38           2 :       if (this->high_ == ACE_INT32_MAX) {
      39             :         // this code is here, despite the RTPS spec statement:
      40             :         // "sequence numbers never wrap"
      41           1 :         this->high_ = 0;
      42           1 :         this->low_ = 1;
      43             :       } else {
      44           1 :         ++this->high_;
      45           1 :         this->low_ = 0;
      46             :       }
      47             :     } else {
      48          65 :       ++this->low_;
      49             :     }
      50          67 :     return *this;
      51             :   }
      52             : 
      53             :   /// Post-increment.
      54           1 :   SequenceNumber operator++(int) {
      55           1 :     SequenceNumber value(*this);
      56           1 :     ++*this;
      57           1 :     return value;
      58             :   }
      59             : 
      60          35 :   SequenceNumber previous() const {
      61          35 :     SequenceNumber retVal(*this);
      62          35 :     if ((this->low_ == 0) && (this->high_ == 0)) {
      63           1 :       retVal.high_ = ACE_INT32_MAX;
      64           1 :       retVal.low_  = ACE_UINT32_MAX;
      65           1 :       return retVal;
      66             :     }
      67          34 :     if (this->low_ == 0) {
      68           1 :       --retVal.high_;
      69           1 :       retVal.low_ = ACE_UINT32_MAX;
      70             :     } else {
      71          33 :       --retVal.low_;
      72             :     }
      73          34 :     return retVal;
      74             :   }
      75             : 
      76        3833 :   void setValue(Value value) {
      77        3833 :     if (value < MIN_VALUE) {
      78           0 :       value = MIN_VALUE;
      79             :     }
      80        3833 :     this->high_ = ACE_INT32(value / LOW_BASE);
      81        3833 :     this->low_  = ACE_UINT32(value % LOW_BASE);
      82        3833 :   }
      83             : 
      84           0 :   void setValue(ACE_INT32 high, ACE_UINT32 low) {
      85           0 :     this->high_ = high;
      86           0 :     this->low_ = low;
      87           0 :     if (this->getValue() < MIN_VALUE) {
      88           0 :       this->setValue(MIN_VALUE);
      89             :     }
      90           0 :   }
      91             : 
      92        2825 :   Value getValue() const {
      93        2825 :     return LOW_BASE * this->high_ + this->low_;
      94             :   }
      95             : 
      96        6051 :   bool operator<(const SequenceNumber& rvalue) const {
      97        6051 :     return (this->high_ < rvalue.high_)
      98        6051 :       || (this->high_ == rvalue.high_ && this->low_ < rvalue.low_);
      99             :   }
     100             : 
     101             :   /// Derive a full suite of logical operations.
     102         735 :   bool operator==(const SequenceNumber& rvalue) const {
     103        1470 :     return (this->high_ == rvalue.high_) &&
     104        1470 :            (this->low_ == rvalue.low_);
     105             :   }
     106         603 :   bool operator!=(const SequenceNumber& rvalue) const {
     107        1205 :     return (this->high_ != rvalue.high_) ||
     108        1205 :            (this->low_ != rvalue.low_);
     109             :   }
     110          13 :   bool operator>=(const SequenceNumber& rvalue) const {
     111          13 :     return !(*this  < rvalue);
     112             :   }
     113         515 :   bool operator<=(const SequenceNumber& rvalue) const {
     114         515 :     return !(rvalue < *this);
     115             :   }
     116          67 :   bool operator>(const SequenceNumber& rvalue) const {
     117          67 :     return (rvalue < *this)
     118          67 :            && (*this != rvalue);
     119             :   }
     120             : 
     121         131 :   ACE_INT32 getHigh() const {
     122         131 :     return high_;
     123             :   }
     124         131 :   ACE_UINT32 getLow() const {
     125         131 :     return low_;
     126             :   }
     127             : 
     128             :   // SEQUENCENUMBER_UNKNOWN is defined by the RTPS spec.
     129           6 :   static SequenceNumber SEQUENCENUMBER_UNKNOWN() {
     130           6 :     return SequenceNumber(-1, 0);
     131             :   }
     132             : 
     133          56 :   static SequenceNumber ZERO() {
     134          56 :     return SequenceNumber(0, 0);
     135             :   }
     136             : 
     137             :   static const Value MAX_VALUE = ACE_INT64_MAX;
     138             :   static const Value INITIAL_VALUE = 1;
     139             :   static const Value MIN_VALUE = 0;
     140             :   static const Value LOW_BASE = 0x0000000100000000LL;
     141             : 
     142             :   friend ACE_CDR::Boolean operator>>(Serializer& s, SequenceNumber& x);
     143             : 
     144             : private:
     145             : 
     146             :   // Private constructor used to force construction of SEQUENCENUMBER_UNKNOWN.
     147             :   // Also used by operator>> to allow deserialization of the same value.
     148          95 :   SequenceNumber(ACE_INT32 high, ACE_UINT32 low)
     149          95 :     : high_(high), low_(low) {
     150          95 :   }
     151             : 
     152             :   ACE_INT32  high_;
     153             :   ACE_UINT32 low_;
     154             : };
     155             : 
     156             : inline ACE_CDR::Boolean
     157          23 : operator<<(Serializer& s, const SequenceNumber& x) {
     158          23 :   s << x.getHigh();
     159          23 :   s << x.getLow();
     160          23 :   return s.good_bit();
     161             : }
     162             : 
     163             : inline ACE_CDR::Boolean
     164          33 : operator>>(Serializer& s, SequenceNumber& x) {
     165             :   ACE_INT32 high;
     166             :   ACE_UINT32 low;
     167          33 :   if (!(s >> high)) {
     168           0 :     return false;
     169             :   }
     170          33 :   if (!(s >> low)) {
     171           0 :     return false;
     172             :   }
     173          33 :   x = SequenceNumber(high, low);
     174          33 :   return true;
     175             : }
     176             : 
     177             : inline SequenceNumber
     178          16 : operator+(const SequenceNumber& lhs, int rhs)
     179             : {
     180          16 :   return SequenceNumber(lhs.getValue() + rhs);
     181             : }
     182             : 
     183             : inline SequenceNumber
     184             : operator+=(SequenceNumber& lhs, int rhs)
     185             : {
     186             :   lhs.setValue(lhs.getValue() + rhs);
     187             :   return lhs;
     188             : }
     189             : 
     190             : inline SequenceNumber
     191             : operator+(int lhs, const SequenceNumber& rhs)
     192             : {
     193             :   return rhs + lhs;
     194             : }
     195             : 
     196             : inline
     197          33 : void serialized_size(const Encoding& encoding, size_t& size,
     198             :   const SequenceNumber& /*sn*/)
     199             : {
     200          33 :   primitive_serialized_size_ulong(encoding, size, 2);
     201          33 : }
     202             : 
     203             : typedef std::pair<SequenceNumber, SequenceNumber> SequenceRange;
     204             : extern OpenDDS_Dcps_Export const SequenceRange unknown_sequence_range;
     205             : 
     206             : typedef SequenceNumber::Value FragmentNumber;
     207             : static const FragmentNumber INVALID_FRAGMENT = -1;
     208             : 
     209             : } // namespace DCPS
     210             : } // namespace OpenDDS
     211             : 
     212             : OPENDDS_END_VERSIONED_NAMESPACE_DECL
     213             : 
     214             : #endif /* OPENDDS_DCPS_SEQUENCENUMBER_H */

Generated by: LCOV version 1.16