Go to the documentation of this file.00001 #include "ace/Time_Value.h"
00002
00003 ACE_RCSID (ace,
00004 Time_Value,
00005 "$Id: Time_Value.cpp 89791 2010-04-07 14:36:21Z schmidt $")
00006
00007 #if !defined (__ACE_INLINE__)
00008 #include "ace/Time_Value.inl"
00009 #endif
00010
00011 #include "ace/Numeric_Limits.h"
00012 #include "ace/If_Then_Else.h"
00013 #include "ace/OS_NS_math.h"
00014
00015 #ifdef ACE_HAS_CPP98_IOSTREAMS
00016 #include <ostream>
00017 #include <iomanip>
00018 #endif
00019
00020 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00021
00022
00023
00024 const ACE_Time_Value ACE_Time_Value::zero;
00025
00026
00027
00028
00029
00030
00031
00032 const ACE_Time_Value ACE_Time_Value::max_time (
00033 ACE_Numeric_Limits<time_t>::max (),
00034 ACE_ONE_SECOND_IN_USECS - 1);
00035
00036 ACE_ALLOC_HOOK_DEFINE (ACE_Time_Value)
00037
00038
00039
00040 ACE_Time_Value
00041 ACE_Time_Value::operator ++ (int)
00042 {
00043
00044 ACE_Time_Value tv (*this);
00045 ++*this;
00046 return tv;
00047 }
00048
00049 ACE_Time_Value &
00050 ACE_Time_Value::operator ++ (void)
00051 {
00052
00053 this->usec (this->usec () + 1);
00054 this->normalize ();
00055 return *this;
00056 }
00057
00058
00059
00060 ACE_Time_Value
00061 ACE_Time_Value::operator -- (int)
00062 {
00063
00064 ACE_Time_Value tv (*this);
00065 --*this;
00066 return tv;
00067 }
00068
00069 ACE_Time_Value &
00070 ACE_Time_Value::operator -- (void)
00071 {
00072
00073 this->usec (this->usec () - 1);
00074 this->normalize ();
00075 return *this;
00076 }
00077
00078 #if defined (ACE_WIN32)
00079
00080
00081
00082
00083
00084
00085
00086 # if defined (ACE_LACKS_LONGLONG_T)
00087 const ACE_U_LongLong ACE_Time_Value::FILETIME_to_timval_skew =
00088 ACE_U_LongLong (0xd53e8000, 0x19db1de);
00089 # else
00090 const DWORDLONG ACE_Time_Value::FILETIME_to_timval_skew =
00091 ACE_INT64_LITERAL (0x19db1ded53e8000);
00092 # endif
00093
00094
00095 ACE_Time_Value::ACE_Time_Value (const FILETIME &file_time)
00096 {
00097
00098 this->set (file_time);
00099 }
00100
00101 void ACE_Time_Value::set (const FILETIME &file_time)
00102 {
00103
00104 #if defined (ACE_LACKS_LONGLONG_T)
00105 ACE_U_LongLong LL_100ns(file_time.dwLowDateTime, file_time.dwHighDateTime);
00106 LL_100ns -= ACE_Time_Value::FILETIME_to_timval_skew;
00107
00108 this->tv_.tv_sec = (long) (LL_100ns / ((double) (10000 * 1000)));
00109
00110 this->tv_.tv_usec = (suseconds_t)((LL_100ns % ((ACE_UINT32)(10000 * 1000))) / 10);
00111 #else
00112
00113 ULARGE_INTEGER _100ns;
00114 _100ns.LowPart = file_time.dwLowDateTime;
00115 _100ns.HighPart = file_time.dwHighDateTime;
00116
00117 _100ns.QuadPart -= ACE_Time_Value::FILETIME_to_timval_skew;
00118
00119
00120 this->tv_.tv_sec = (long) (_100ns.QuadPart / (10000 * 1000));
00121
00122 this->tv_.tv_usec = (suseconds_t) ((_100ns.QuadPart % (10000 * 1000)) / 10);
00123 #endif // ACE_LACKS_LONGLONG_T
00124 this->normalize ();
00125 }
00126
00127
00128 ACE_Time_Value::operator FILETIME () const
00129 {
00130 FILETIME file_time;
00131
00132
00133 #if defined (ACE_LACKS_LONGLONG_T)
00134 ACE_U_LongLong LL_sec(this->tv_.tv_sec);
00135 ACE_U_LongLong LL_usec(this->tv_.tv_usec);
00136 ACE_U_LongLong LL_100ns = LL_sec * (ACE_UINT32)(10000 * 1000) +
00137 LL_usec * (ACE_UINT32)10 +
00138 ACE_Time_Value::FILETIME_to_timval_skew;
00139 file_time.dwLowDateTime = LL_100ns.lo();
00140 file_time.dwHighDateTime = LL_100ns.hi();
00141 #else
00142 ULARGE_INTEGER _100ns;
00143 _100ns.QuadPart = (((DWORDLONG) this->tv_.tv_sec * (10000 * 1000) +
00144 this->tv_.tv_usec * 10) +
00145 ACE_Time_Value::FILETIME_to_timval_skew);
00146
00147 file_time.dwLowDateTime = _100ns.LowPart;
00148 file_time.dwHighDateTime = _100ns.HighPart;
00149 #endif //ACE_LACKS_LONGLONG_T
00150
00151 return file_time;
00152 }
00153
00154 #endif
00155
00156 void
00157 ACE_Time_Value::dump (void) const
00158 {
00159 #if defined (ACE_HAS_DUMP)
00160
00161 #if 0
00162 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00163 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntv_sec_ = %d"), this->tv_.tv_sec));
00164 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntv_usec_ = %d\n"), this->tv_.tv_usec));
00165 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00166 #endif
00167 #endif
00168 }
00169
00170 void
00171 ACE_Time_Value::normalize (bool saturate)
00172 {
00173
00174
00175
00176 if (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS)
00177 {
00178
00179
00180 if (!saturate)
00181 do
00182 {
00183 ++this->tv_.tv_sec;
00184 this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
00185 }
00186 while (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS);
00187 else
00188 do
00189 if (this->tv_.tv_sec < ACE_Numeric_Limits<time_t>::max())
00190 {
00191 ++this->tv_.tv_sec;
00192 this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
00193 }
00194 else
00195 this->tv_.tv_usec = ACE_ONE_SECOND_IN_USECS - 1;
00196 while (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS);
00197 }
00198 else if (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS)
00199 {
00200
00201
00202 if (!saturate)
00203 do
00204 {
00205 --this->tv_.tv_sec;
00206 this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
00207 }
00208 while (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS);
00209 else
00210 do
00211 if (this->tv_.tv_sec > ACE_Numeric_Limits<time_t>::min())
00212 {
00213 --this->tv_.tv_sec;
00214 this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
00215 }
00216 else
00217 this->tv_.tv_usec = -ACE_ONE_SECOND_IN_USECS + 1;
00218 while (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS);
00219 }
00220
00221 if (this->tv_.tv_sec >= 1 && this->tv_.tv_usec < 0)
00222 {
00223 --this->tv_.tv_sec;
00224 this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
00225 }
00226
00227 #if !defined ( __QNXNTO__)
00228 else if (this->tv_.tv_sec < 0 && this->tv_.tv_usec > 0)
00229 {
00230 ++this->tv_.tv_sec;
00231 this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
00232 }
00233 #endif
00234 }
00235
00236
00237 ACE_Time_Value &
00238 ACE_Time_Value::operator *= (double d)
00239 {
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 typedef ACE::If_Then_Else<(sizeof (double) > sizeof (time_t)),
00255 double,
00256 long double>::result_type float_type;
00257
00258 float_type sec_total = static_cast<float_type> (this->sec());
00259 sec_total *= d;
00260
00261
00262 static const float_type max_int =
00263 ACE_Numeric_Limits<time_t>::max() + 0.999999;
00264 static const float_type min_int =
00265 ACE_Numeric_Limits<time_t>::min() - 0.999999;
00266
00267 if (sec_total > max_int)
00268 {
00269 this->set(ACE_Numeric_Limits<time_t>::max(), ACE_ONE_SECOND_IN_USECS-1);
00270 }
00271 else if (sec_total < min_int)
00272 {
00273 this->set(ACE_Numeric_Limits<time_t>::min(), -ACE_ONE_SECOND_IN_USECS+1);
00274 }
00275 else
00276 {
00277 time_t time_sec = static_cast<time_t> (sec_total);
00278
00279 float_type usec_total = this->usec();
00280 usec_total *= d;
00281
00282
00283 usec_total += (sec_total-time_sec) * ACE_ONE_SECOND_IN_USECS;
00284
00285
00286 sec_total = usec_total / ACE_ONE_SECOND_IN_USECS;
00287
00288 if (sec_total > 0)
00289 {
00290 usec_total = (sec_total - ACE_OS::floor(sec_total));
00291 }
00292 else
00293 {
00294 usec_total = (sec_total - ACE_OS::ceil(sec_total));
00295 }
00296
00297 sec_total -= usec_total;
00298 usec_total *= ACE_ONE_SECOND_IN_USECS;
00299
00300
00301 sec_total += time_sec;
00302
00303
00304 if (sec_total > max_int)
00305 {
00306 this->set (ACE_Numeric_Limits<time_t>::max(), ACE_ONE_SECOND_IN_USECS - 1);
00307 }
00308 else if (sec_total < min_int)
00309 {
00310 this->set (ACE_Numeric_Limits<time_t>::min(), -ACE_ONE_SECOND_IN_USECS + 1);
00311 }
00312 else
00313 {
00314 time_sec = static_cast<time_t> (sec_total);
00315 suseconds_t time_usec = static_cast<suseconds_t> (usec_total);
00316
00317
00318 if (time_usec > 0 && (usec_total - time_usec) >= 0.5)
00319 {
00320 ++time_usec;
00321 }
00322 else if (time_usec < 0 && (usec_total - time_usec) <= -0.5)
00323 {
00324 --time_usec;
00325 }
00326
00327 this->set (time_sec, time_usec);
00328 }
00329 }
00330 return *this;
00331 }
00332
00333 #ifdef ACE_HAS_CPP98_IOSTREAMS
00334 ostream &operator<<(ostream &o, const ACE_Time_Value &v)
00335 {
00336 char oldFiller = o.fill ();
00337 o.fill ('0');
00338 const timeval *tv = v;
00339 if (tv->tv_sec)
00340 {
00341 o << tv->tv_sec;
00342 if (tv->tv_usec)
00343 o << '.' << std::setw (6) << ACE_STD_NAMESPACE::abs (tv->tv_usec);
00344 }
00345 else if (tv->tv_usec < 0)
00346 o << "-0." << std::setw (6) << - tv->tv_usec;
00347 else
00348 {
00349 o << '0';
00350 if (tv->tv_usec > 0)
00351 o << '.'<< std::setw (6) << tv->tv_usec;
00352 }
00353
00354 o.fill (oldFiller);
00355 return o;
00356 }
00357 #endif
00358
00359 ACE_END_VERSIONED_NAMESPACE_DECL