SequenceNumber.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef OPENDDS_DCPS_SEQUENCENUMBER_H
00009 #define OPENDDS_DCPS_SEQUENCENUMBER_H
00010 
00011 #include "ace/Global_Macros.h"
00012 
00013 #include <utility>
00014 
00015 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00016 #pragma once
00017 #endif /* ACE_LACKS_PRAGMA_ONCE */
00018 
00019 #include "dds/DCPS/Serializer.h"
00020 
00021 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 namespace OpenDDS {
00024 namespace DCPS {
00025 
00026 /// Sequence number abstraction.  Only allows positive 64 bit values.
00027 class OpenDDS_Dcps_Export SequenceNumber {
00028 public:
00029   typedef ACE_INT64 Value;
00030   /// Construct with a value, default to one (starting point).
00031   SequenceNumber(Value value = MIN_VALUE) {
00032     setValue(value);
00033   }
00034 
00035   /// Pre-increment.
00036   SequenceNumber& operator++() {
00037     if (this->low_ == ACE_UINT32_MAX) {
00038       if (this->high_ == ACE_INT32_MAX) {
00039         // this code is here, despite the RTPS spec statement:
00040         // "sequence numbers never wrap"
00041         this->high_ = 0;
00042         this->low_ = 1;
00043       } else {
00044         ++this->high_;
00045         this->low_ = 0;
00046       }
00047     } else {
00048       ++this->low_;
00049     }
00050     return *this ;
00051   }
00052 
00053   /// Post-increment.
00054   SequenceNumber operator++(int) {
00055     SequenceNumber value(*this);
00056     ++*this;
00057     return value ;
00058   }
00059 
00060   SequenceNumber previous() const {
00061     SequenceNumber retVal(*this);
00062     if ((this->low_ == 1) && (this->high_ == 0)) {
00063       retVal.high_ = ACE_INT32_MAX;
00064       retVal.low_  = ACE_UINT32_MAX;
00065       return retVal;
00066     }
00067     if (this->low_ == 0) {
00068       --retVal.high_;
00069       retVal.low_ = ACE_UINT32_MAX;
00070     } else {
00071       --retVal.low_;
00072     }
00073     return retVal ;
00074   }
00075 
00076   void setValue(Value value) {
00077     if (value < MIN_VALUE) {
00078       value = MIN_VALUE;
00079     }
00080     this->high_ = ACE_INT32(value / LOW_BASE);
00081     this->low_  = ACE_UINT32(value % LOW_BASE);
00082   }
00083 
00084   void setValue(ACE_INT32 high, ACE_UINT32 low) {
00085     this->high_ = high;
00086     this->low_ = low;
00087     if (this->getValue() < MIN_VALUE) {
00088       this->setValue(MIN_VALUE);
00089     }
00090   }
00091 
00092   Value getValue() const {
00093     return LOW_BASE * this->high_ + this->low_;
00094   }
00095 
00096   bool operator<(const SequenceNumber& rvalue) const {
00097     return (this->high_ < rvalue.high_)
00098       || (this->high_ == rvalue.high_ && this->low_ < rvalue.low_);
00099   }
00100 
00101   /// Derive a full suite of logical operations.
00102   bool operator==(const SequenceNumber& rvalue) const {
00103     return (this->high_ == rvalue.high_) &&
00104            (this->low_ == rvalue.low_) ;
00105   }
00106   bool operator!=(const SequenceNumber& rvalue) const {
00107     return (this->high_ != rvalue.high_) ||
00108            (this->low_ != rvalue.low_) ;
00109   }
00110   bool operator>=(const SequenceNumber& rvalue) const {
00111     return !(*this  < rvalue);
00112   }
00113   bool operator<=(const SequenceNumber& rvalue) const {
00114     return !(rvalue < *this);
00115   }
00116   bool operator>(const SequenceNumber& rvalue) const {
00117     return (rvalue < *this)
00118            && (*this != rvalue);
00119   }
00120 
00121   ACE_INT32 getHigh() const {
00122     return high_;
00123   }
00124   ACE_UINT32 getLow() const {
00125     return low_;
00126   }
00127 
00128   // SEQUENCENUMBER_UNKOWN is defined by the RTPS spec.
00129   static SequenceNumber SEQUENCENUMBER_UNKNOWN() {
00130     return SequenceNumber(-1, 0);
00131   }
00132 
00133   static SequenceNumber ZERO() {
00134     return SequenceNumber(0, 0);
00135   }
00136 
00137   static const Value MAX_VALUE = ACE_INT64_MAX;
00138   static const Value MIN_VALUE = 1;
00139   static const Value LOW_BASE = 0x0000000100000000LL;
00140 
00141   friend ACE_CDR::Boolean operator>>(Serializer& s, SequenceNumber& x);
00142 
00143 private:
00144 
00145   // Private constructor used to force construction of SEQUENCENUMBER_UNKNOWN.
00146   // Also used by operator>> to allow deserialization of the same value.
00147   SequenceNumber(ACE_INT32 high, ACE_UINT32 low)
00148     : high_(high), low_(low) {
00149   }
00150 
00151   ACE_INT32  high_;
00152   ACE_UINT32 low_;
00153 };
00154 
00155 inline ACE_CDR::Boolean
00156 operator<<(Serializer& s, const SequenceNumber& x) {
00157   s << x.getHigh();
00158   s << x.getLow();
00159   return s.good_bit();
00160 }
00161 
00162 inline ACE_CDR::Boolean
00163 operator>>(Serializer& s, SequenceNumber& x) {
00164   ACE_INT32 high;
00165   ACE_UINT32 low;
00166   if (!(s >> high)) {
00167     return false;
00168   }
00169   if (!(s >> low)) {
00170     return false;
00171   }
00172   x = SequenceNumber(high, low);
00173   return true;
00174 }
00175 
00176 inline SequenceNumber
00177 operator+(const SequenceNumber& lhs, int rhs)
00178 {
00179   return SequenceNumber(lhs.getValue() + rhs);
00180 }
00181 
00182 inline SequenceNumber
00183 operator+=(SequenceNumber& lhs, int rhs)
00184 {
00185   lhs.setValue(lhs.getValue() + rhs);
00186   return lhs;
00187 }
00188 
00189 inline SequenceNumber
00190 operator+(int lhs, const SequenceNumber& rhs)
00191 {
00192   return rhs + lhs;
00193 }
00194 
00195 inline void
00196 gen_find_size(const SequenceNumber& /*sn*/, size_t& size, size_t& padding) {
00197   find_size_ulong(size, padding);
00198   size += gen_max_marshaled_size(CORBA::Long());
00199 }
00200 
00201 typedef std::pair<SequenceNumber, SequenceNumber> SequenceRange;
00202 
00203 } // namespace OpenDDS
00204 } // namespace DCPS
00205 
00206 OPENDDS_END_VERSIONED_NAMESPACE_DECL
00207 
00208 #endif /* OPENDDS_DCPS_SEQUENCENUMBER_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1