00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #include "w_defines.h"
00031 
00032 
00033 
00034 
00035 #include <ctime>
00036 #include <cstring>
00037 #include <w_base.h>
00038 #include <stime.h>
00039 #include <w_stream.h>
00040 #include <climits>
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050   
00051 
00052 #define    NS_SECOND    1000000000    
00053 #define    US_SECOND    1000000    
00054 #define    MS_SECOND    1000    
00055 
00056 #ifdef USE_POSIX_TIME
00057 typedef    struct timespec _stime_t;
00058 #define    st_tod        tv_sec
00059 #define    st_hires    tv_nsec
00060 #define    HR_SECOND    NS_SECOND
00061 #else
00062 typedef struct timeval    _stime_t;
00063 #define    st_tod        tv_sec
00064 #define    st_hires    tv_usec
00065 #define    HR_SECOND    US_SECOND
00066 #endif
00067 
00068 #define    HR_MAX        (HR_SECOND-1)
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 stime_t::stime_t(time_t tod, long hires)
00084 {
00085     _time.st_tod = tod;
00086     _time.st_hires = hires;
00087 
00088     normalize();
00089 }
00090 
00091 
00092 stime_t::stime_t(int secs)
00093 {
00094     _time.st_tod = secs;
00095     _time.st_hires = 0;
00096 
00097     
00098 }
00099 
00100 stime_t::stime_t(long secs)
00101 {
00102     _time.st_tod = secs;
00103     _time.st_hires = 0;
00104 
00105     
00106 }
00107 
00108 
00109 stime_t::stime_t(double secs)
00110 {
00111     _time.st_tod = (long) secs;
00112     _time.st_hires = (long) ((secs - _time.st_tod) * HR_SECOND);
00113 
00114     
00115 }
00116 
00117 
00118 #ifdef USE_POSIX_TIME
00119 stime_t::stime_t(const struct timespec &tv)
00120 {
00121     _time.st_tod = tv.tv_sec;
00122     _time.st_hires = tv.tv_nsec * (HR_SECOND / NS_SECOND);
00123 
00124     normalize();
00125 }
00126 #endif
00127 
00128 stime_t::stime_t(const struct timeval &tv)
00129 {
00130     _time.st_tod = tv.tv_sec;
00131     _time.st_hires = tv.tv_usec * (HR_SECOND / US_SECOND);
00132 
00133     normalize();
00134 }
00135 
00136 
00137 bool    stime_t::operator==(const stime_t &r) const
00138 {
00139     return _time.st_tod == r._time.st_tod &&
00140         _time.st_hires == r._time.st_hires;
00141 }
00142 
00143 
00144 bool    stime_t::operator<(const stime_t &r) const
00145 {
00146     if (_time.st_tod == r._time.st_tod)
00147         return _time.st_hires < r._time.st_hires;
00148     return _time.st_tod < r._time.st_tod;
00149 }
00150 
00151 
00152 bool    stime_t::operator<=(const stime_t &r) const
00153 {
00154     return *this == r  ||  *this < r;
00155 }
00156 
00157 
00158 static inline int sign(const int i)
00159 {
00160     return i > 0 ? 1 : i < 0 ? -1 : 0;
00161     
00162 }
00163 
00164 
00165 
00166 
00167 
00168 
00169 void stime_t::signs()
00170 {
00171     if (_time.st_tod  &&  _time.st_hires
00172         && sign(_time.st_tod) != sign(_time.st_hires)) {
00173 
00174         if (sign(_time.st_tod) == 1) {
00175             _time.st_tod--;
00176             _time.st_hires += HR_SECOND;
00177         }
00178         else {
00179             _time.st_tod++;
00180             _time.st_hires -= HR_SECOND;
00181         }
00182     }
00183 }
00184 
00185 
00186 void stime_t::_normalize()
00187 {
00188     if (abs(_time.st_hires) >= HR_SECOND) {
00189         _time.st_tod += sign(_time.st_hires);
00190         _time.st_hires -= sign(_time.st_hires) * HR_SECOND;
00191     }
00192     signs();
00193 }
00194    
00195 
00196 
00197 void stime_t::normalize()
00198 {
00199     int    factor;
00200 
00201     factor = _time.st_hires / HR_SECOND;
00202     if (factor) {
00203         _time.st_tod += factor;
00204         _time.st_hires -= HR_SECOND * factor;
00205     }
00206 
00207     signs();
00208 }
00209 
00210 
00211 stime_t    stime_t::operator-() const
00212 {
00213     stime_t    result;
00214 
00215     result._time.st_tod = -_time.st_tod;
00216     result._time.st_hires = -_time.st_hires;
00217 
00218     return result;
00219 }
00220 
00221 
00222 stime_t    stime_t::operator+(const stime_t &r) const
00223 {
00224     stime_t    result;
00225 
00226     result._time.st_tod  = _time.st_tod  + r._time.st_tod;
00227     result._time.st_hires = _time.st_hires + r._time.st_hires;
00228 
00229     result._normalize();
00230 
00231     return result;
00232 }
00233 
00234 
00235 stime_t    stime_t::operator-(const stime_t &r) const
00236 {
00237     return *this + -r;
00238 }
00239 
00240 
00241 stime_t stime_t::operator*(const int factor) const
00242 {
00243     stime_t    result;
00244 
00245     result._time.st_tod = _time.st_tod * factor;
00246     result._time.st_hires = _time.st_hires * factor;
00247     result.normalize();
00248 
00249     return result;
00250 }
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259   
00260 
00261 
00262 stime_t stime_t::operator/(const int factor) const
00263 {
00264     return *this / (double)factor;
00265 }
00266 
00267 
00268 stime_t    stime_t::operator*(const double factor) const
00269 {
00270     double d = *this;
00271     d *= factor;
00272     stime_t result(d); 
00273     result.normalize();
00274 
00275     return result;
00276 }
00277 
00278 
00279 stime_t    stime_t::operator/(const double factor) const
00280 {
00281     return *this * (1.0 / factor);
00282 }
00283 
00284 
00285 
00286 stime_t &stime_t::operator+=(const stime_t &r)
00287 {
00288     _time.st_tod  += r._time.st_tod;
00289     _time.st_hires += r._time.st_hires;
00290 
00291     _normalize();
00292     
00293     return *this;
00294 }
00295 
00296 
00297 stime_t &stime_t::operator-=(const stime_t &r)
00298 {
00299     _time.st_tod  -= r._time.st_tod;
00300     _time.st_hires -= r._time.st_hires;
00301 
00302     _normalize();
00303     
00304     return *this;
00305 }
00306 
00307 
00308 stime_t::operator double() const
00309 {
00310     return _time.st_tod + _time.st_hires / (double) HR_SECOND;
00311 }
00312 
00313 
00314 stime_t::operator float() const
00315 {
00316     double res = (double) *this;
00317     return (float)res;
00318 
00319 }
00320 
00321 
00322 
00323 
00324 
00325 
00326 #ifdef USE_POSIX_TIME
00327 stime_t::operator struct timespec() const
00328 {
00329     struct    timespec tv;
00330     tv.tv_sec = _time.st_tod;
00331     tv.tv_nsec = _time.st_hires;
00332     return tv;
00333 }
00334 #endif
00335 
00336 
00337 stime_t::operator struct timeval() const
00338 {
00339     struct    timeval tv;
00340     tv.tv_sec = _time.st_tod;
00341     
00342 
00343     tv.tv_usec = _time.st_hires / (HR_SECOND / US_SECOND);
00344     return tv;
00345 }
00346 
00347 
00348 void    stime_t::gettime()
00349 {
00350     int    kr;
00351 #ifdef USE_POSIX_TIME
00352     kr = clock_gettime(CLOCK_REALTIME, &_time);
00353 #else
00354     kr = gettimeofday(&_time, 0);
00355 #endif
00356     if (kr == -1)
00357         W_FATAL(fcOS);
00358 }
00359 
00360 
00361 ostream    &stime_t::print(ostream &s) const
00362 {
00363     ctime(s);
00364 
00365     if (_time.st_hires) {
00366         stime_t    tod(_time.st_tod, 0);
00367 
00368         s << " and " << sinterval_t(*this - tod);
00369     }
00370 
00371     return s;
00372 }
00373 
00374 
00375 ostream &stime_t::ctime(ostream &s) const
00376 {
00377     
00378     time_t    kludge = _time.st_tod;
00379     const   int buflen(26); 
00380     char    buf[buflen];    
00381 
00382 
00383 #ifdef _POSIX_PTHREAD_SEMANTICS 
00384     char    *when = ctime_r(&kludge, buf);
00385 #elif defined(SOLARIS2)
00386     char    *when = ctime_r(&kludge, buf, buflen);
00387 #else
00388     char    *when = ctime_r(&kludge, buf);
00389 #endif
00390 
00391     
00392     char *nl = strchr(when, '\n');
00393     if (nl)
00394         *nl = '\0';
00395 
00396     return s << when;
00397 }
00398 
00399 
00400 static void factor_print(ostream &s, long what)
00401 {
00402     struct {
00403         const char    *label;
00404         int        factor;
00405     } factors[] = {
00406         {"%02d:", 60*60},
00407         {"%02d:", 60},
00408         {0, 0}
00409     }, *f = factors;
00410     long    mine;
00411     bool    printed = false;
00412     bool    negative = what < 0;
00413 
00414     if (negative) {
00415         s << '-';
00416         what = -what;
00417     }
00418 
00419     for (f = factors; f->label; f++) {
00420         mine = what / f->factor;
00421         what = what % f->factor;
00422         if (mine || printed) {
00423             W_FORM(s)(f->label, mine);
00424             printed = true;
00425         }
00426     }
00427 
00428     
00429     W_FORM(s)(printed ? "%02d" : "%d", what);
00430 }
00431 
00432 
00433 ostream    &sinterval_t::print(ostream &s) const
00434 {
00435     factor_print(s, _time.st_tod);
00436 
00437     if (_time.st_hires) {
00438 #ifdef USE_POSIX_TIME
00439         W_FORM(s)(".%09ld", _time.st_hires);
00440 #else
00441         W_FORM(s)(".%06ld", _time.st_hires);
00442 #endif
00443     }
00444 
00445     return s;
00446 }
00447 
00448 
00449 ostream &operator<<(ostream &s, const stime_t &t)
00450 {
00451     return t.print(s);
00452 }
00453 
00454 
00455 ostream &operator<<(ostream &s, const sinterval_t &t)
00456 {
00457     return t.print(s);
00458 }
00459 
00460 
00461 
00462 
00463 static inline void from_linear(int sec, int xsec,
00464                 int linear_secs, _stime_t &_time)
00465 {
00466     _time.st_tod = sec + xsec / linear_secs;
00467     xsec = xsec % linear_secs;
00468     if (linear_secs > HR_SECOND)
00469         _time.st_hires = xsec / (linear_secs / HR_SECOND);
00470     else
00471         _time.st_hires = xsec * (HR_SECOND / linear_secs);
00472 }
00473 
00474 
00475 stime_t stime_t::sec(int sec)
00476 {
00477     stime_t    r;
00478 
00479     r._time.st_tod = sec;
00480     r._time.st_hires = 0;
00481 
00482     return r;
00483 }
00484 
00485 
00486 stime_t    stime_t::msec(int ms, int sec)
00487 {
00488     stime_t    r;
00489 
00490     from_linear(sec, ms, MS_SECOND, r._time);
00491     
00492 
00493     return r;
00494 }
00495 
00496     
00497 stime_t    stime_t::usec(int us, int sec)
00498 {
00499     stime_t    r;
00500 
00501     from_linear(sec, us, US_SECOND, r._time);
00502     
00503 
00504     return r;
00505 }
00506 
00507 
00508 stime_t    stime_t::nsec(int ns, int sec)
00509 {
00510     stime_t    r;
00511 
00512     from_linear(sec, ns, NS_SECOND, r._time);
00513     
00514 
00515     return r;
00516 }
00517 
00518 
00519 stime_t    stime_t::now()
00520 {
00521     stime_t    now;
00522     now.gettime();
00523 
00524     return now;
00525 }
00526 
00527 
00528 
00529  
00530 
00531 
00532 #define    HR_ROUNDUP    (HR_SECOND / 2)
00533 
00534 static    inline long to_linear(const _stime_t &_time, const int linear_secs)
00535 {
00536     long    result;
00537     int    factor;
00538 
00539     result = _time.st_tod * linear_secs;
00540 
00541     if (linear_secs > HR_SECOND) {
00542         factor = linear_secs / HR_SECOND;
00543         result += _time.st_hires * factor;
00544     }
00545     else {
00546         factor = HR_SECOND / linear_secs;
00547         result += _time.st_hires / factor;
00548     }
00549 
00550     return result;
00551 }
00552 
00553 
00554 long    stime_t::secs() const
00555 {
00556     long    result;
00557 
00558     result = _time.st_tod;
00559     if (_time.st_hires >= HR_ROUNDUP)
00560         result++;
00561 
00562     return result;
00563 }
00564 
00565 long    stime_t::msecs() const
00566 {
00567     return to_linear(_time, MS_SECOND);
00568 }
00569 
00570 long    stime_t::usecs() const
00571 {
00572     return to_linear(_time, US_SECOND);
00573 }
00574 
00575 long    stime_t::nsecs() const
00576 {
00577     return to_linear(_time, NS_SECOND);
00578 }
00579 
00580