00001 #include "ace/Time_Value.h"
00002 
00003 ACE_RCSID (ace,
00004            Time_Value,
00005            "$Id: Time_Value.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00006 
00007 
00008 #if !defined (__ACE_INLINE__)
00009 #include "ace/Time_Value.inl"
00010 #endif 
00011 
00012 #include "ace/Numeric_Limits.h"
00013 #include "ace/If_Then_Else.h"
00014 
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016 
00017 
00018 
00019 const ACE_Time_Value ACE_Time_Value::zero;
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 const ACE_Time_Value ACE_Time_Value::max_time (
00028   ACE_Numeric_Limits<time_t>::max (),
00029   ACE_ONE_SECOND_IN_USECS - 1);
00030 
00031 ACE_ALLOC_HOOK_DEFINE (ACE_Time_Value)
00032 
00033 
00034 
00035 
00036 ACE_Time_Value
00037 ACE_Time_Value::operator ++ (int)
00038 {
00039   
00040   ACE_Time_Value tv (*this);
00041   ++*this;
00042   return tv;
00043 }
00044 
00045 ACE_Time_Value &
00046 ACE_Time_Value::operator ++ (void)
00047 {
00048   
00049   this->usec (this->usec () + 1);
00050   this->normalize ();
00051   return *this;
00052 }
00053 
00054 
00055 
00056 
00057 ACE_Time_Value
00058 ACE_Time_Value::operator -- (int)
00059 {
00060   
00061   ACE_Time_Value tv (*this);
00062   --*this;
00063   return tv;
00064 }
00065 
00066 ACE_Time_Value &
00067 ACE_Time_Value::operator -- (void)
00068 {
00069   
00070   this->usec (this->usec () - 1);
00071   this->normalize ();
00072   return *this;
00073 }
00074 
00075 #if defined (ACE_WIN32)
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 # if defined (ACE_LACKS_LONGLONG_T)
00084 const ACE_U_LongLong ACE_Time_Value::FILETIME_to_timval_skew =
00085 ACE_U_LongLong (0xd53e8000, 0x19db1de);
00086 # else
00087 const DWORDLONG ACE_Time_Value::FILETIME_to_timval_skew =
00088 ACE_INT64_LITERAL (0x19db1ded53e8000);
00089 # endif
00090 
00091 
00092 
00093 ACE_Time_Value::ACE_Time_Value (const FILETIME &file_time)
00094 {
00095   
00096   this->set (file_time);
00097 }
00098 
00099 void ACE_Time_Value::set (const FILETIME &file_time)
00100 {
00101   
00102 #if defined (ACE_LACKS_LONGLONG_T)
00103   ACE_U_LongLong LL_100ns(file_time.dwLowDateTime, file_time.dwHighDateTime);
00104   LL_100ns -= ACE_Time_Value::FILETIME_to_timval_skew;
00105   
00106   this->tv_.tv_sec = (long) (LL_100ns / ((double) (10000 * 1000)));
00107   
00108   this->tv_.tv_usec = (suseconds_t)((LL_100ns % ((ACE_UINT32)(10000 * 1000))) / 10);
00109 #else
00110   
00111   ULARGE_INTEGER _100ns;
00112   _100ns.LowPart = file_time.dwLowDateTime;
00113   _100ns.HighPart = file_time.dwHighDateTime;
00114 
00115   _100ns.QuadPart -= ACE_Time_Value::FILETIME_to_timval_skew;
00116 
00117   
00118   this->tv_.tv_sec = (long) (_100ns.QuadPart / (10000 * 1000));
00119   
00120   this->tv_.tv_usec = (suseconds_t) ((_100ns.QuadPart % (10000 * 1000)) / 10);
00121 #endif // ACE_LACKS_LONGLONG_T
00122   this->normalize ();
00123 }
00124 
00125 
00126 
00127 ACE_Time_Value::operator FILETIME () const
00128 {
00129   FILETIME file_time;
00130   
00131 
00132 #if defined (ACE_LACKS_LONGLONG_T)
00133   ACE_U_LongLong LL_sec(this->tv_.tv_sec);
00134   ACE_U_LongLong LL_usec(this->tv_.tv_usec);
00135   ACE_U_LongLong LL_100ns = LL_sec * (ACE_UINT32)(10000 * 1000) +
00136                             LL_usec * (ACE_UINT32)10 +
00137                             ACE_Time_Value::FILETIME_to_timval_skew;
00138   file_time.dwLowDateTime = LL_100ns.lo();
00139   file_time.dwHighDateTime = LL_100ns.hi();
00140 #else
00141   ULARGE_INTEGER _100ns;
00142   _100ns.QuadPart = (((DWORDLONG) this->tv_.tv_sec * (10000 * 1000) +
00143                      this->tv_.tv_usec * 10) +
00144                      ACE_Time_Value::FILETIME_to_timval_skew);
00145 
00146   file_time.dwLowDateTime = _100ns.LowPart;
00147   file_time.dwHighDateTime = _100ns.HighPart;
00148 #endif //ACE_LACKS_LONGLONG_T
00149 
00150   return file_time;
00151 }
00152 
00153 #endif 
00154 
00155 void
00156 ACE_Time_Value::dump (void) const
00157 {
00158 #if defined (ACE_HAS_DUMP)
00159   
00160 #if 0
00161   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00162   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntv_sec_ = %d"), this->tv_.tv_sec));
00163   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntv_usec_ = %d\n"), this->tv_.tv_usec));
00164   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00165 #endif 
00166 #endif 
00167 }
00168 
00169 void
00170 ACE_Time_Value::normalize (void)
00171 {
00172   
00173   
00174 
00175   if (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS)
00176     {
00177 
00178 
00179       do
00180         {
00181           ++this->tv_.tv_sec;
00182           this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
00183         }
00184       while (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS);
00185     }
00186   else if (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS)
00187     {
00188 
00189 
00190       do
00191         {
00192           --this->tv_.tv_sec;
00193           this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
00194         }
00195       while (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS);
00196     }
00197 
00198   if (this->tv_.tv_sec >= 1 && this->tv_.tv_usec < 0)
00199     {
00200       --this->tv_.tv_sec;
00201       this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
00202     }
00203 
00204 #if !defined ( __QNXNTO__)
00205   else if (this->tv_.tv_sec < 0 && this->tv_.tv_usec > 0)
00206     {
00207       ++this->tv_.tv_sec;
00208       this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
00209     }
00210 #endif 
00211 }
00212 
00213 
00214 ACE_Time_Value &
00215 ACE_Time_Value::operator *= (double d)
00216 {
00217   
00218   
00219   
00220   
00221   
00222   
00223   
00224   
00225   
00226   
00227   typedef ACE::If_Then_Else<(sizeof (double) > sizeof (time_t)),
00228                             double,
00229                             long double>::result_type float_type;
00230 
00231   float_type time_total =
00232     (this->sec ()
00233      + static_cast<float_type> (this->usec ()) / ACE_ONE_SECOND_IN_USECS) * d;
00234 
00235   
00236   static const float_type max_int =
00237     ACE_Numeric_Limits<time_t>::max () + 0.999999;
00238   static const float_type min_int =
00239     ACE_Numeric_Limits<time_t>::min () - 0.999999;
00240 
00241   if (time_total > max_int)
00242     time_total = max_int;
00243   if (time_total < min_int)
00244     time_total = min_int;
00245 
00246   const time_t time_sec = static_cast<time_t> (time_total);
00247 
00248   time_total -= time_sec;
00249   time_total *= ACE_ONE_SECOND_IN_USECS;
00250 
00251   suseconds_t time_usec = static_cast<suseconds_t> (time_total);
00252 
00253   
00254   if (time_usec > 0 && (time_total - time_usec) >= 0.5)
00255     ++time_usec;
00256   else if (time_usec < 0 && (time_total - time_usec) <= -0.5)
00257     --time_usec;
00258 
00259   this->set (time_sec, time_usec);
00260 
00261   return *this;
00262 }
00263 
00264 ACE_END_VERSIONED_NAMESPACE_DECL