00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <libplumbing/config.h>
00019 #include <cstdio>
00020 #include <cassert>
00021 #include <cmath>
00022 #include <cstdlib>
00023 #include <libexplain/gettimeofday.h>
00024
00025 #include <libplumbing/logging.h>
00026 #include <libplumbing/time_value.h>
00027
00028
00029 plumbing::time_value::time_value(long sec, long usec)
00030 {
00031 if (usec >= 1000000)
00032 {
00033 ldiv_t q = ldiv(usec, 1000000);
00034 tv_sec = sec + q.quot;
00035 tv_usec = q.rem;
00036 }
00037 else if (usec < 0)
00038 {
00039
00040
00041
00042
00043
00044 ldiv_t q = ldiv(-usec, 1000000);
00045 tv_sec = sec - q.quot;
00046 if (q.rem)
00047 {
00048 tv_sec--;
00049 tv_usec = 1000000 - q.rem;
00050 }
00051 else
00052 tv_usec = 0;
00053 }
00054 else
00055 {
00056 tv_sec = sec;
00057 tv_usec = usec;
00058 }
00059 assert(in_normal_form());
00060 }
00061
00062
00063 plumbing::time_value::time_value(double sec)
00064 {
00065 long long usec = (long long)floor(sec * 1e6 + 0.5);
00066 tv_sec = usec / 1000000;
00067 tv_usec = usec - tv_sec * 1000000;
00068 if (tv_usec < 0)
00069 {
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 tv_sec--;
00087 tv_usec += 1000000;
00088 }
00089 assert(in_normal_form());
00090 }
00091
00092
00093 plumbing::time_value::time_value(const time_value &rhs)
00094 {
00095 assert(rhs.in_normal_form());
00096 tv_sec = rhs.tv_sec;
00097 tv_usec = rhs.tv_usec;
00098 }
00099
00100
00101 plumbing::time_value::time_value(const char *str)
00102 {
00103 double n = strtod(str, 0);
00104 *this = time_value(n);
00105 }
00106
00107
00108 plumbing::time_value &
00109 plumbing::time_value::operator=(double sec)
00110 {
00111 double usec = floor(sec * 1e6 + 0.5);
00112 tv_sec = long(floor(usec * 1e-6));
00113 tv_usec = long(usec - tv_sec * 1e6);
00114 assert(in_normal_form());
00115 return *this;
00116 }
00117
00118
00119 plumbing::time_value::operator double()
00120 const
00121 {
00122 return (tv_sec + tv_usec * 1e-6);
00123 }
00124
00125
00126 plumbing::time_value &
00127 plumbing::time_value::operator+=(const time_value &rhs)
00128 {
00129 assert(in_normal_form());
00130 assert(rhs.in_normal_form());
00131 tv_sec += rhs.tv_sec;
00132 tv_usec += rhs.tv_usec;
00133 if (tv_usec >= 1000000)
00134 {
00135 tv_sec++;
00136 tv_usec -= 1000000;
00137 }
00138 assert(in_normal_form());
00139 return *this;
00140 }
00141
00142
00143 plumbing::time_value
00144 plumbing::time_value::operator+(const time_value &rhs)
00145 const
00146 {
00147 time_value result(*this);
00148 result += rhs;
00149 return result;
00150 }
00151
00152
00153 plumbing::time_value &
00154 plumbing::time_value::operator-=(const time_value &rhs)
00155 {
00156 assert(in_normal_form());
00157 assert(rhs.in_normal_form());
00158 tv_sec -= rhs.tv_sec;
00159 tv_usec -= rhs.tv_usec;
00160 if (tv_usec < 0)
00161 {
00162 tv_sec--;
00163 tv_usec += 1000000;
00164 }
00165 assert(in_normal_form());
00166 return *this;
00167 }
00168
00169
00170 plumbing::time_value
00171 plumbing::time_value::operator-(const time_value &rhs)
00172 const
00173 {
00174 time_value result(*this);
00175 result -= rhs;
00176 return result;
00177 }
00178
00179
00180 bool
00181 plumbing::time_value::operator==(const time_value &rhs)
00182 const
00183 {
00184 return (tv_sec == rhs.tv_sec && tv_usec == rhs.tv_usec);
00185 }
00186
00187
00188 bool
00189 plumbing::time_value::operator!=(const time_value &rhs)
00190 const
00191 {
00192 return (tv_sec != rhs.tv_sec || tv_usec != rhs.tv_usec);
00193 }
00194
00195
00196 bool
00197 plumbing::time_value::operator<(const time_value &rhs)
00198 const
00199 {
00200 if (tv_sec == rhs.tv_sec)
00201 return (tv_usec < rhs.tv_usec);
00202 return (tv_sec < rhs.tv_sec);
00203 }
00204
00205
00206 bool
00207 plumbing::time_value::operator<=(const time_value &rhs)
00208 const
00209 {
00210 if (tv_sec == rhs.tv_sec)
00211 return (tv_usec <= rhs.tv_usec);
00212 return (tv_sec < rhs.tv_sec);
00213 }
00214
00215
00216 bool
00217 plumbing::time_value::operator>(const time_value &rhs)
00218 const
00219 {
00220 if (tv_sec == rhs.tv_sec)
00221 return (tv_usec > rhs.tv_usec);
00222 return (tv_sec > rhs.tv_sec);
00223 }
00224
00225
00226 bool
00227 plumbing::time_value::operator>=(const time_value &rhs)
00228 const
00229 {
00230 if (tv_sec == rhs.tv_sec)
00231 return (tv_usec >= rhs.tv_usec);
00232 return (tv_sec > rhs.tv_sec);
00233 }
00234
00235
00236 plumbing::time_value &
00237 plumbing::time_value::operator*=(double x)
00238 {
00239 *this = x * double(*this);
00240 return *this;
00241 }
00242
00243
00244 plumbing::time_value
00245 plumbing::time_value::operator*(double x)
00246 const
00247 {
00248 return time_value(x * double(*this));
00249 }
00250
00251
00252 plumbing::time_value &
00253 plumbing::time_value::operator*=(long x)
00254 {
00255 *this = x * double(*this);
00256 return *this;
00257 }
00258
00259
00260 plumbing::time_value
00261 plumbing::time_value::operator*(long x)
00262 const
00263 {
00264 return time_value(x * double(*this));
00265 }
00266
00267
00268 plumbing::time_value
00269 plumbing::time_value::operator-()
00270 const
00271 {
00272 assert(in_normal_form());
00273 if (tv_usec == 0)
00274 return time_value(-tv_sec);
00275 time_value result(-tv_sec - 1, 1000000 - tv_usec);
00276 return result;
00277 }
00278
00279
00280 int
00281 plumbing::time_value::get_time_of_day()
00282 {
00283 if (gettimeofday(this, 0) < 0)
00284 return -1;
00285 assert(in_normal_form());
00286 return 0;
00287 }
00288
00289
00290 plumbing::time_value
00291 plumbing::time_value::now()
00292 {
00293 time_value result;
00294 if (result.get_time_of_day() < 0)
00295 log().fatal_error("%s", explain_gettimeofday(&result, 0));
00296 return result;
00297 }
00298
00299
00300 std::string
00301 plumbing::time_value::representation()
00302 const
00303 {
00304 char buffer[20];
00305 snprintf(buffer, sizeof(buffer), "%8.6f", double(*this));
00306 return buffer;
00307 }
00308
00309
00310