libassa
3.5.0
|
00001 // -*- c++ -*- 00002 //------------------------------------------------------------------------------ 00003 // TimeVal.cpp 00004 //------------------------------------------------------------------------------ 00005 // Copyright (c) 2000 by Vladislav Grinchenko 00006 // 00007 // This library is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Library General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 2 of the License, or (at your option) any later version. 00011 //------------------------------------------------------------------------------ 00012 // Created: 09/28/99 00013 //------------------------------------------------------------------------------ 00014 #include <time.h> // localtime(3), gmtime(3) 00015 #include <stdio.h> // sprintf(3) 00016 00017 #include "TimeVal.h" 00018 #include "Logger.h" 00019 00020 #if defined (WIN32) 00021 # include <windows.h> 00022 #endif 00023 00024 using namespace ASSA; 00025 00026 //------------------------------------------------------------------------------ 00027 // Static definitions 00028 //------------------------------------------------------------------------------ 00029 00030 TimeVal TimeVal::m_zero; // zero time 00031 static const long ONE_SECOND = 1000000; 00032 00033 #ifndef __GNUC__ 00034 #define EPOCHFILETIME (116444736000000000i64) 00035 #else 00036 #define EPOCHFILETIME (116444736000000000LL) 00037 #endif 00038 00039 //------------------------------------------------------------------------------ 00040 // Wrappers 00041 //------------------------------------------------------------------------------ 00042 TimeVal 00043 TimeVal:: 00044 gettimeofday () 00045 { 00046 timeval tv; 00047 00048 #ifdef WIN32 00049 FILETIME ft; 00050 LARGE_INTEGER li; 00051 __int64 t; 00052 static int tzflag; 00053 00054 GetSystemTimeAsFileTime(&ft); 00055 li.LowPart = ft.dwLowDateTime; 00056 li.HighPart = ft.dwHighDateTime; 00057 t = li.QuadPart; /* In 100-nanosecond intervals */ 00058 t -= EPOCHFILETIME; /* Offset to the Epoch time */ 00059 t /= 10; /* In microseconds */ 00060 tv.tv_sec = (long)(t / 1000000); 00061 tv.tv_usec = (long)(t % 1000000); 00062 #else 00063 ::gettimeofday (&tv, 0); 00064 #endif 00065 return tv; 00066 } 00067 00068 //------------------------------------------------------------------------------ 00069 // Membe functions 00070 //------------------------------------------------------------------------------ 00071 00072 TimeVal& 00073 TimeVal:: 00074 operator+=(const TimeVal& rhs_) 00075 { 00076 tv_sec += rhs_.tv_sec; 00077 tv_usec += rhs_.tv_usec; 00078 00079 if (tv_usec >= ONE_SECOND) { 00080 tv_usec -= ONE_SECOND; 00081 tv_sec++; 00082 } 00083 else if (tv_sec >= 1 && tv_usec < 0) { 00084 tv_usec += ONE_SECOND; 00085 tv_sec--; 00086 } 00087 normalize (); 00088 return *this; 00089 } 00090 00091 TimeVal& 00092 TimeVal:: 00093 operator-=(const TimeVal& rhs_) 00094 { 00095 tv_sec -= rhs_.tv_sec; 00096 tv_usec -= rhs_.tv_usec; 00097 00098 if (tv_usec < 0) { 00099 tv_usec += ONE_SECOND; 00100 tv_sec--; 00101 } 00102 else if (tv_usec >= ONE_SECOND) { 00103 tv_usec -= ONE_SECOND; 00104 tv_sec++; 00105 } 00106 normalize (); 00107 return *this; 00108 } 00109 00110 void 00111 TimeVal:: 00112 normalize () 00113 { 00114 if (tv_usec >= ONE_SECOND) { 00115 do { 00116 tv_sec++; 00117 tv_usec -= ONE_SECOND; 00118 } 00119 while (tv_usec >= ONE_SECOND); 00120 } 00121 else if (tv_usec <= -ONE_SECOND) { 00122 do { 00123 tv_sec--; 00124 tv_usec += ONE_SECOND; 00125 } 00126 while (tv_usec <= -ONE_SECOND); 00127 } 00128 00129 if (tv_sec >= 1 && tv_usec < 0) { 00130 tv_sec--; 00131 tv_usec += ONE_SECOND; 00132 } 00133 else if (tv_sec < 0 && tv_usec > 0) { 00134 tv_sec++; 00135 tv_usec -= ONE_SECOND; 00136 } 00137 } 00138 00139 00140 //------------------------------------------------------------------------------ 00141 // All possible variation of HH:MM:SS.MMM I could think of: 00142 //------------------------------------------------------------------------------ 00143 00144 string 00145 TimeVal:: 00146 fmtString (const char* fmt_) const 00147 { 00148 struct tm ct; 00149 char buf[80]; 00150 memset (buf, 0, 80); 00151 00152 if (m_tz == gmt) 00153 ct = *( localtime ((const time_t*) &tv_sec) ); 00154 else 00155 ct = *( gmtime ((const time_t*) &tv_sec) ); 00156 00157 if (fmt_ == NULL) { 00158 strftime (buf, 80, "%Y/%j %H:%M:%S", &ct); 00159 sprintf (buf + strlen(buf), 00160 ".%03ld", (tv_usec %1000000)/1000); 00161 } 00162 else { 00163 strftime(buf, 80, fmt_, &ct); 00164 } 00165 return string (buf); 00166 } 00167 00168 string 00169 TimeVal:: 00170 fmt_hh_mm_ss_mls () const 00171 { 00172 struct tm ct; 00173 char buf [80]; 00174 memset (buf, 0, 80); 00175 00176 if (m_tz == gmt) 00177 ct = *( localtime ((const time_t*) &tv_sec) ); 00178 else 00179 ct = *( gmtime ((const time_t*) &tv_sec) ); 00180 00181 strftime (buf, 80, "%H:%M:%S", &ct); 00182 sprintf (buf + strlen(buf), ".%03ld", millisec ()); 00183 00184 return string (buf); 00185 } 00186 00187 string 00188 TimeVal:: 00189 fmt_mm_ss_mls () const 00190 { 00191 struct tm ct; 00192 char buf [80]; 00193 memset (buf, 0, 80); 00194 00195 if (m_tz == gmt) 00196 ct = *( localtime ((const time_t*) &tv_sec) ); 00197 else 00198 ct = *( gmtime ((const time_t*) &tv_sec) ); 00199 00200 strftime (buf, 80, "%M:%S", &ct); 00201 sprintf (buf + strlen(buf), ".%03ld", millisec ()); 00202 00203 return string (buf); 00204 } 00205 00206 string 00207 TimeVal:: 00208 fmt_ss_mls () const 00209 { 00210 struct tm ct; 00211 char buf [80]; 00212 memset (buf, 0, 80); 00213 00214 if (m_tz == gmt) 00215 ct = *( localtime ((const time_t*) &tv_sec) ); 00216 else 00217 ct = *( gmtime ((const time_t*) &tv_sec) ); 00218 00219 strftime (buf, 80, "%S", &ct); 00220 sprintf (buf + strlen(buf), ".%03ld", millisec ()); 00221 00222 return string (buf); 00223 } 00224 00225 void 00226 TimeVal:: 00227 dump_to_log (const string& var_name_) const 00228 { 00229 static const char self []="TimeVal::dump_to_log"; trace(self); 00230 00231 if (Logger::get_instance ()->group_enabled (REACT)) 00232 { 00233 DL((REACT,"=== TimeVal %s ===\n", var_name_.c_str ())); 00234 DL((REACT,"MM:SS:MLS = %s\n", fmt_mm_ss_mls ().c_str ())); 00235 DL((REACT,"tv_sec = %d, tv_msec = %d, tv_mls = %d\n", 00236 sec (), msec (), millisec ())); 00237 DL((REACT,"(double) = %7.4f\n", double (*this))); 00238 DL((REACT,"==================\n")); 00239 } 00240 } 00241