LCOV - code coverage report
Current view: top level - DCPS - Time_Helper.inl (source / functions) Hit Total Coverage
Test: coverage.info Lines: 75 98 76.5 %
Date: 2023-04-30 01:32:43 Functions: 20 27 74.1 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *
       4             :  * Distributed under the OpenDDS License.
       5             :  * See: http://www.opendds.org/license.html
       6             :  */
       7             : 
       8             : #include "ace/OS_NS_string.h"
       9             : #include "ace/Truncate.h"
      10             : 
      11             : #include <cstring>
      12             : 
      13             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      14             : 
      15             : namespace OpenDDS {
      16             : namespace DCPS {
      17             : 
      18             : // These operators are used in some inline functions below.  Some
      19             : // compilers require the inline definition to appear before its use.
      20             : #ifndef OPENDDS_SAFETY_PROFILE
      21             : ACE_INLINE
      22         468 : bool operator==(const DDS::Duration_t& t1, const DDS::Duration_t& t2)
      23             : {
      24         468 :   return t1.sec == t2.sec && t1.nanosec == t2.nanosec;
      25             : }
      26             : 
      27             : ACE_INLINE
      28           0 : bool operator!=(const DDS::Duration_t& t1, const DDS::Duration_t& t2)
      29             : {
      30           0 :   return !(t1 == t2);
      31             : }
      32             : #endif
      33             : 
      34             : ACE_INLINE
      35          24 : bool operator<(const DDS::Duration_t& t1, const DDS::Duration_t& t2)
      36             : {
      37             :   // @note We wouldn't have to handle the case for INFINITY explicitly
      38             :   //       if both the Duration_t sec and nanosec fields were the
      39             :   //       maximum values for their corresponding types.
      40             :   //       Unfortunately, the OMG DDS specification defines the
      41             :   //       infinite nanosec value to be somewhere in the middle.
      42             : 
      43             :   // We assume that either both the DDS::Duration_t::sec and
      44             :   // DDS::Duration_t::nanosec fields are INFINITY or neither of them
      45             :   // are.  It doesn't make sense for only one of the fields to be
      46             :   // INFINITY.
      47             :   return
      48          24 :     !is_infinite(t1)
      49          34 :     && (is_infinite(t2)
      50          10 :         || t1.sec < t2.sec
      51          32 :         || (t1.sec == t2.sec && t1.nanosec < t2.nanosec));
      52             : }
      53             : 
      54             : ACE_INLINE
      55           0 : bool operator<=(const DDS::Duration_t& t1, const DDS::Duration_t& t2)
      56             : {
      57             :   // If t2 is *not* less than t1, t1 must be less than
      58             :   // or equal to t2.
      59             :   // This is more concise than:
      60             :   //   t1 < t2 || t1 == t2
      61           0 :   return !(t2 < t1);
      62             : }
      63             : 
      64             : ACE_INLINE
      65          24 : bool operator>(const DDS::Duration_t& t1, const DDS::Duration_t& t2)
      66             : {
      67          24 :   return t2 < t1;
      68             : }
      69             : 
      70             : ACE_INLINE
      71             : bool operator>=(const DDS::Duration_t& t1, const DDS::Duration_t& t2)
      72             : {
      73             :   return t2 <= t1;
      74             : }
      75             : 
      76             : ACE_INLINE
      77         112 : bool operator!(const DDS::Time_t& t)
      78             : {
      79         112 :   return t.sec == DDS::TIME_INVALID_SEC
      80         112 :          || t.nanosec == DDS::TIME_INVALID_NSEC;
      81             : }
      82             : 
      83             : #ifndef OPENDDS_SAFETY_PROFILE
      84             : ACE_INLINE bool
      85          28 : operator==(const DDS::Time_t& t1, const DDS::Time_t& t2)
      86             : {
      87          28 :   return !(t1 < t2) && !(t2 < t1);
      88             : }
      89             : 
      90             : ACE_INLINE bool
      91             : operator!=(const DDS::Time_t& t1, const DDS::Time_t& t2)
      92             : {
      93             :   return !(t1 == t2);
      94             : }
      95             : #endif
      96             : 
      97             : ACE_INLINE bool
      98          56 : operator<(const DDS::Time_t& t1, const DDS::Time_t& t2)
      99             : {
     100          56 :   if (!t1 || !t2) return false;
     101             : 
     102          56 :   return t1.sec < t2.sec
     103          56 :          || (t1.sec == t2.sec && t1.nanosec < t2.nanosec);
     104             : }
     105             : 
     106             : ACE_INLINE bool
     107             : operator<=(const DDS::Time_t& t1, const DDS::Time_t& t2)
     108             : {
     109             :   return !(t2 < t1);
     110             : }
     111             : 
     112             : ACE_INLINE bool
     113           0 : operator>(const DDS::Time_t& t1, const DDS::Time_t& t2)
     114             : {
     115           0 :   return t2 < t1;
     116             : }
     117             : 
     118             : ACE_INLINE bool
     119             : operator>=(const DDS::Time_t& t1, const DDS::Time_t& t2)
     120             : {
     121             :   return t2 <= t1;
     122             : }
     123             : 
     124             : ACE_INLINE DDS::Time_t
     125          13 : operator+(const DDS::Time_t& t1, const DDS::Duration_t& d1)
     126             : {
     127          13 :   CORBA::Long sec = static_cast<CORBA::Long>(static_cast<CORBA::ULong>(t1.sec) + static_cast<CORBA::ULong>(d1.sec));
     128          13 :   CORBA::ULong nanosec = t1.nanosec + d1.nanosec;
     129             : 
     130          38 :   while (nanosec >= ACE_ONE_SECOND_IN_NSECS) {
     131          25 :     ++sec;
     132          25 :     nanosec -= ACE_ONE_SECOND_IN_NSECS;
     133             :   }
     134             : 
     135          13 :   const DDS::Time_t t = { sec, nanosec };
     136          13 :   return t;
     137             : }
     138             : 
     139             : ACE_INLINE DDS::Duration_t
     140           2 : operator-(const DDS::Time_t& t1, const DDS::Time_t& t2)
     141             : {
     142           2 :   DDS::Duration_t t = { t1.sec - t2.sec, t1.nanosec - t2.nanosec };
     143             : 
     144           2 :   if (t2.nanosec > t1.nanosec) {
     145           1 :       t.nanosec = (t1.nanosec + ACE_ONE_SECOND_IN_NSECS) - t2.nanosec;
     146           1 :       t.sec = (t1.sec - 1) - t2.sec;
     147             :     }
     148             : 
     149           2 :   return t;
     150             : }
     151             : 
     152             : ACE_INLINE DDS::Time_t
     153             : operator-(const DDS::Time_t& t1, const DDS::Duration_t& t2)
     154             : {
     155             :   DDS::Time_t t = { t1.sec - t2.sec, t1.nanosec - t2.nanosec };
     156             : 
     157             :   if (t2.nanosec > t1.nanosec) {
     158             :       t.nanosec = (t1.nanosec + ACE_ONE_SECOND_IN_NSECS) - t2.nanosec;
     159             :       t.sec = (t1.sec - 1) - t2.sec;
     160             :     }
     161             : 
     162             :   return t;
     163             : }
     164             : 
     165             : ACE_INLINE DDS::Duration_t
     166           0 : operator-(const MonotonicTime_t& t1, const MonotonicTime_t& t2)
     167             : {
     168           0 :   DDS::Duration_t t = { t1.sec - t2.sec, t1.nanosec - t2.nanosec };
     169             : 
     170           0 :   if (t2.nanosec > t1.nanosec) {
     171           0 :       t.nanosec = (t1.nanosec + ACE_ONE_SECOND_IN_NSECS) - t2.nanosec;
     172           0 :       t.sec = (t1.sec - 1) - t2.sec;
     173             :     }
     174             : 
     175           0 :   return t;
     176             : }
     177             : 
     178             : ACE_INLINE bool
     179             : operator<(const MonotonicTime_t& t1, const MonotonicTime_t& t2)
     180             : {
     181             :   return t1.sec < t2.sec || (t1.sec == t2.sec && t1.nanosec < t2.nanosec);
     182             : }
     183             : 
     184             : #ifndef OPENDDS_SAFETY_PROFILE
     185             : ACE_INLINE bool
     186          10 : operator==(const MonotonicTime_t& t1, const MonotonicTime_t& t2)
     187             : {
     188          10 :   return t1.sec == t2.sec && t1.nanosec == t2.nanosec;
     189             : }
     190             : #endif
     191             : 
     192             : ACE_INLINE
     193           0 : ACE_Time_Value time_to_time_value(const DDS::Time_t& t)
     194             : {
     195           0 :   ACE_Time_Value tv(t.sec, t.nanosec / 1000);
     196           0 :   return tv;
     197             : }
     198             : 
     199             : ACE_INLINE
     200          12 : DDS::Time_t time_value_to_time(const ACE_Time_Value& tv)
     201             : {
     202             :   DDS::Time_t t;
     203          12 :   t.sec = ACE_Utils::truncate_cast<CORBA::Long>(tv.sec());
     204          12 :   t.nanosec = ACE_Utils::truncate_cast<CORBA::ULong>(tv.usec() * 1000);
     205          12 :   return t;
     206             : }
     207             : 
     208             : ACE_INLINE
     209           0 : MonotonicTime_t time_value_to_monotonic_time(const ACE_Time_Value& tv)
     210             : {
     211             :   MonotonicTime_t t;
     212           0 :   t.sec = ACE_Utils::truncate_cast<CORBA::Long>(tv.sec());
     213           0 :   t.nanosec = ACE_Utils::truncate_cast<CORBA::ULong>(tv.usec() * 1000);
     214           0 :   return t;
     215             : }
     216             : 
     217             : ACE_INLINE
     218           5 : ACE_Time_Value duration_to_time_value(const DDS::Duration_t& t)
     219             : {
     220           5 :   if (is_infinite(t)) {
     221           1 :     return ACE_Time_Value::max_time;
     222             :   }
     223             : 
     224           4 :   CORBA::LongLong sec = t.sec + t.nanosec/1000/ACE_ONE_SECOND_IN_USECS;
     225           4 :   CORBA::ULong usec = t.nanosec/1000 % ACE_ONE_SECOND_IN_USECS;
     226             : 
     227           4 :   if (sec > ACE_Time_Value::max_time.sec()) {
     228           0 :     return ACE_Time_Value::max_time;
     229             :   }
     230             :   else {
     231           4 :     return ACE_Time_Value(ACE_Utils::truncate_cast<time_t>(sec), usec);
     232             :   }
     233             : }
     234             : 
     235             : ACE_INLINE
     236           1 : ACE_Time_Value duration_to_absolute_time_value(const DDS::Duration_t& t,
     237             :                                                const ACE_Time_Value& now)
     238             : {
     239             :   CORBA::LongLong sec
     240           1 :     = t.sec + now.sec() + (t.nanosec/1000 + now.usec())/ACE_ONE_SECOND_IN_USECS;
     241           1 :   CORBA::ULong usec = (t.nanosec/1000 + now.usec()) % ACE_ONE_SECOND_IN_USECS;
     242             : 
     243           1 :   if (sec > ACE_Time_Value::max_time.sec()) {
     244           0 :     return ACE_Time_Value::max_time;
     245             :   }
     246             :   else {
     247           1 :     return ACE_Time_Value(ACE_Utils::truncate_cast<time_t>(sec), usec);
     248             :   }
     249             : }
     250             : 
     251             : ACE_INLINE
     252           1 : DDS::Duration_t time_value_to_duration(const ACE_Time_Value& tv)
     253             : {
     254             :   DDS::Duration_t t;
     255           1 :   t.sec = ACE_Utils::truncate_cast<CORBA::Long>(tv.sec());
     256           1 :   t.nanosec = ACE_Utils::truncate_cast<CORBA::ULong>(tv.usec() * 1000);
     257           1 :   return t;
     258             : }
     259             : 
     260             : ACE_INLINE
     261             : DDS::Duration_t time_to_duration(const DDS::Time_t& t)
     262             : {
     263             :   DDS::Duration_t d = { t.sec, t.nanosec };
     264             :   return d;
     265             : }
     266             : 
     267             : ACE_INLINE
     268           8 : bool valid_duration(const DDS::Duration_t& t)
     269             : {
     270             :   // Only accept infinite or positive finite durations.  (Zero
     271             :   // excluded).
     272             :   //
     273             :   // Note that it doesn't make much sense for users to set
     274             :   // durations less than 10 milliseconds since the underlying
     275             :   // timer resolution is generally no better than that.
     276           8 :   return is_infinite(t) || t.sec > 0 || (t.sec >= 0 && t.nanosec > 0);
     277             : }
     278             : 
     279             : ACE_INLINE
     280           8 : bool non_negative_duration(const DDS::Duration_t& t)
     281             : {
     282             :   return
     283           8 :     (t.sec == DDS::DURATION_ZERO_SEC  // Allow zero duration.
     284           2 :      && t.nanosec == DDS::DURATION_ZERO_NSEC)
     285          10 :     || valid_duration(t);
     286             : }
     287             : 
     288             : ACE_INLINE OpenDDS_Dcps_Export
     289             : ACE_UINT32 uint32_fractional_seconds_to_nanoseconds(ACE_UINT32 fraction)
     290             : {
     291             :   return static_cast<ACE_UINT32>((static_cast<ACE_UINT64>(fraction) * 1000000000) >> 32);
     292             : }
     293             : 
     294             : ACE_INLINE OpenDDS_Dcps_Export
     295           0 : ACE_UINT32 nanoseconds_to_uint32_fractional_seconds(ACE_UINT32 nsec)
     296             : {
     297           0 :   return static_cast<ACE_UINT32>((static_cast<ACE_UINT64>(nsec) << 32) / 1000000000);
     298             : }
     299             : 
     300             : ACE_INLINE OpenDDS_Dcps_Export
     301           3 : ACE_UINT32 uint32_fractional_seconds_to_microseconds(ACE_UINT32 fraction)
     302             : {
     303           3 :   return static_cast<ACE_UINT32>((static_cast<ACE_UINT64>(fraction) * 1000000) >> 32);
     304             : }
     305             : 
     306             : ACE_INLINE OpenDDS_Dcps_Export
     307             : ACE_UINT32 microseconds_to_uint32_fractional_seconds(ACE_UINT32 usec)
     308             : {
     309             :   return static_cast<ACE_UINT32>((static_cast<ACE_UINT64>(usec) << 32) / 1000000);
     310             : }
     311             : 
     312          72 : bool is_infinite(const DDS::Duration_t& value)
     313             : {
     314         111 :   return value.sec == DDS::DURATION_INFINITE_SEC &&
     315         111 :     value.nanosec == DDS::DURATION_INFINITE_NSEC;
     316             : }
     317             : 
     318             : ACE_INLINE OpenDDS_Dcps_Export
     319          10 : const MonotonicTime_t& monotonic_time_zero()
     320             : {
     321             :   static const MonotonicTime_t zero = { 0, 0 };
     322          10 :   return zero;
     323             : }
     324             : 
     325             : ACE_INLINE OpenDDS_Dcps_Export
     326          73 : DDS::Duration_t make_duration_t(int sec, unsigned long nanosec)
     327             : {
     328             :   DDS::Duration_t x;
     329          73 :   x.sec = sec;
     330          73 :   x.nanosec = nanosec;
     331          73 :   return x;
     332             : }
     333             : 
     334             : ACE_INLINE OpenDDS_Dcps_Export
     335          56 : DDS::Time_t make_time_t(int sec, unsigned long nanosec)
     336             : {
     337             :   DDS::Time_t x;
     338          56 :   x.sec = sec;
     339          56 :   x.nanosec = nanosec;
     340          56 :   return x;
     341             : }
     342             : 
     343             : } // namespace DCPS
     344             : } // namespace OpenDDS
     345             : 
     346             : OPENDDS_END_VERSIONED_NAMESPACE_DECL

Generated by: LCOV version 1.16