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