libassa  3.5.1
TimeVal.cpp
Go to the documentation of this file.
1 // -*- c++ -*-
2 //------------------------------------------------------------------------------
3 // TimeVal.cpp
4 //------------------------------------------------------------------------------
5 // Copyright (c) 2000 by Vladislav Grinchenko
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Library General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //------------------------------------------------------------------------------
12 // Created: 09/28/99
13 //------------------------------------------------------------------------------
14 #include <time.h> // localtime(3), gmtime(3)
15 #include <stdio.h> // sprintf(3)
16 
17 #include "TimeVal.h"
18 #include "Logger.h"
19 
20 #if defined (WIN32)
21 # include <windows.h>
22 #endif
23 
24 using namespace ASSA;
25 
26 //------------------------------------------------------------------------------
27 // Static definitions
28 //------------------------------------------------------------------------------
29 
30 TimeVal TimeVal::m_zero; // zero time
31 static const long ONE_SECOND = 1000000;
32 
33 #ifndef __GNUC__
34 #define EPOCHFILETIME (116444736000000000i64)
35 #else
36 #define EPOCHFILETIME (116444736000000000LL)
37 #endif
38 
39 //------------------------------------------------------------------------------
40 // Wrappers
41 //------------------------------------------------------------------------------
42 TimeVal
44 gettimeofday ()
45 {
46  timeval tv;
47 
48 #ifdef WIN32
49  FILETIME ft;
50  LARGE_INTEGER li;
51  __int64 t;
52  static int tzflag;
53 
54  GetSystemTimeAsFileTime(&ft);
55  li.LowPart = ft.dwLowDateTime;
56  li.HighPart = ft.dwHighDateTime;
57  t = li.QuadPart; /* In 100-nanosecond intervals */
58  t -= EPOCHFILETIME; /* Offset to the Epoch time */
59  t /= 10; /* In microseconds */
60  tv.tv_sec = (long)(t / 1000000);
61  tv.tv_usec = (long)(t % 1000000);
62 #else
63  ::gettimeofday (&tv, 0);
64 #endif
65  return tv;
66 }
67 
68 //------------------------------------------------------------------------------
69 // Membe functions
70 //------------------------------------------------------------------------------
71 
72 TimeVal&
74 operator+=(const TimeVal& rhs_)
75 {
76  tv_sec += rhs_.tv_sec;
77  tv_usec += rhs_.tv_usec;
78 
79  if (tv_usec >= ONE_SECOND) {
80  tv_usec -= ONE_SECOND;
81  tv_sec++;
82  }
83  else if (tv_sec >= 1 && tv_usec < 0) {
84  tv_usec += ONE_SECOND;
85  tv_sec--;
86  }
87  normalize ();
88  return *this;
89 }
90 
91 TimeVal&
93 operator-=(const TimeVal& rhs_)
94 {
95  tv_sec -= rhs_.tv_sec;
96  tv_usec -= rhs_.tv_usec;
97 
98  if (tv_usec < 0) {
99  tv_usec += ONE_SECOND;
100  tv_sec--;
101  }
102  else if (tv_usec >= ONE_SECOND) {
103  tv_usec -= ONE_SECOND;
104  tv_sec++;
105  }
106  normalize ();
107  return *this;
108 }
109 
110 void
112 normalize ()
113 {
114  if (tv_usec >= ONE_SECOND) {
115  do {
116  tv_sec++;
117  tv_usec -= ONE_SECOND;
118  }
119  while (tv_usec >= ONE_SECOND);
120  }
121  else if (tv_usec <= -ONE_SECOND) {
122  do {
123  tv_sec--;
124  tv_usec += ONE_SECOND;
125  }
126  while (tv_usec <= -ONE_SECOND);
127  }
128 
129  if (tv_sec >= 1 && tv_usec < 0) {
130  tv_sec--;
131  tv_usec += ONE_SECOND;
132  }
133  else if (tv_sec < 0 && tv_usec > 0) {
134  tv_sec++;
135  tv_usec -= ONE_SECOND;
136  }
137 }
138 
139 
140 //------------------------------------------------------------------------------
141 // All possible variation of HH:MM:SS.MMM I could think of:
142 //------------------------------------------------------------------------------
143 
144 string
146 fmtString (const char* fmt_) const
147 {
148  struct tm ct;
149  char buf[80];
150  memset (buf, 0, 80);
151 
152  if (m_tz == gmt)
153  ct = *( localtime ((const time_t*) &tv_sec) );
154  else
155  ct = *( gmtime ((const time_t*) &tv_sec) );
156 
157  if (fmt_ == NULL) {
158  strftime (buf, 80, "%Y/%j %H:%M:%S", &ct);
159  sprintf (buf + strlen(buf),
160  ".%03ld", (tv_usec %1000000)/1000);
161  }
162  else {
163  strftime(buf, 80, fmt_, &ct);
164  }
165  return string (buf);
166 }
167 
168 string
170 fmt_hh_mm_ss_mls () const
171 {
172  struct tm ct;
173  char buf [80];
174  memset (buf, 0, 80);
175 
176  if (m_tz == gmt)
177  ct = *( localtime ((const time_t*) &tv_sec) );
178  else
179  ct = *( gmtime ((const time_t*) &tv_sec) );
180 
181  strftime (buf, 80, "%H:%M:%S", &ct);
182  sprintf (buf + strlen(buf), ".%03ld", millisec ());
183 
184  return string (buf);
185 }
186 
187 string
189 fmt_mm_ss_mls () const
190 {
191  struct tm ct;
192  char buf [80];
193  memset (buf, 0, 80);
194 
195  if (m_tz == gmt)
196  ct = *( localtime ((const time_t*) &tv_sec) );
197  else
198  ct = *( gmtime ((const time_t*) &tv_sec) );
199 
200  strftime (buf, 80, "%M:%S", &ct);
201  sprintf (buf + strlen(buf), ".%03ld", millisec ());
202 
203  return string (buf);
204 }
205 
206 string
208 fmt_ss_mls () const
209 {
210  struct tm ct;
211  char buf [80];
212  memset (buf, 0, 80);
213 
214  if (m_tz == gmt)
215  ct = *( localtime ((const time_t*) &tv_sec) );
216  else
217  ct = *( gmtime ((const time_t*) &tv_sec) );
218 
219  strftime (buf, 80, "%S", &ct);
220  sprintf (buf + strlen(buf), ".%03ld", millisec ());
221 
222  return string (buf);
223 }
224 
225 void
227 dump_to_log (const string& var_name_) const
228 {
229  static const char self []="TimeVal::dump_to_log"; trace(self);
230 
231  if (Logger::get_instance ()->group_enabled (REACT))
232  {
233  DL((REACT,"=== TimeVal %s ===\n", var_name_.c_str ()));
234  DL((REACT,"MM:SS:MLS = %s\n", fmt_mm_ss_mls ().c_str ()));
235  DL((REACT,"tv_sec = %d, tv_msec = %d, tv_mls = %d\n",
236  sec (), msec (), millisec ()));
237  DL((REACT,"(double) = %7.4f\n", double (*this)));
238  DL((REACT,"==================\n"));
239  }
240 }
241 
An abstraction to message logging facility.
#define trace(s)
trace() is used to trace function call chain in C++ program.
Definition: Logger.h:429
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
#define EPOCHFILETIME
Definition: TimeVal.cpp:34
static const long ONE_SECOND
Definition: TimeVal.cpp:31
Class TimeVal is a wrapper around UNIX timeval structure.
static Logger * get_instance()
Return an instance of templated class T.
Definition: Singleton.h:47
static TimeVal m_zero
Zero time value.
Definition: TimeVal.h:178
string fmtString(const char *fmt_=NULL) const
Format timeval structure into readable format.
Definition: TimeVal.cpp:146
void normalize()
Normalization after arithmetic operation.
Definition: TimeVal.cpp:112
string fmt_ss_mls() const
Format timeval structure in readable format SS.MLS.
Definition: TimeVal.cpp:208
@ gmt
GMT.
Definition: TimeVal.h:34
string fmt_mm_ss_mls() const
Format timeval structure in readable format MM:SS.MLS.
Definition: TimeVal.cpp:189
long msec(void) const
Get microseconds.
Definition: TimeVal.h:73
TimeVal & operator+=(const TimeVal &rhs_)
Addition.
Definition: TimeVal.cpp:74
long millisec() const
Convert tv_usec's microseconds (=1/1,000,000 sec) to milliseconds (=1/1,000 sec).
Definition: TimeVal.h:241
void dump_to_log(const string &name_="") const
Dump value of struct timeval to the log file with mask TRACE = DBG_APP15.
Definition: TimeVal.cpp:227
static TimeVal gettimeofday()
Shields off underlying OS differences in getting current time.
Definition: TimeVal.cpp:44
long sec(void) const
Get secons.
Definition: TimeVal.h:67
TimeVal & operator-=(const TimeVal &rhs_)
Substraction.
Definition: TimeVal.cpp:93
string fmt_hh_mm_ss_mls() const
Format timeval structure in readable format HH:MM:SS.MLS.
Definition: TimeVal.cpp:170
int m_tz
Time zone.
Definition: TimeVal.h:175
Definition: Acceptor.h:40
@ REACT
Class Reactor/PrioriyQueue messages
Definition: LogMask.h:39