00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _TIMESTAMP_HXX
00028 #define _TIMESTAMP_HXX
00029
00030
00031 #ifndef __cplusplus
00032 # error This library requires C++
00033 #endif
00034
00035 #include <iosfwd>
00036 #include <iomanip>
00037 #include <sstream>
00038 #include <simgear/compiler.h>
00039 #include <simgear/math/SGCMath.hxx>
00040
00055 class SGTimeStamp {
00056 public:
00057 typedef long sec_type;
00058 typedef int nsec_type;
00059
00061 SGTimeStamp() :
00062 _nsec(0),
00063 _sec(0)
00064 { }
00065
00071
00072
00073
00074
00075
00076
00077
00079 void stamp();
00080
00082 void setTime(const double& seconds)
00083 {
00084 sec_type wholeSecs = sec_type(floor(seconds));
00085 nsec_type reminder;
00086 reminder = nsec_type(floor((seconds - wholeSecs)*(1000*1000*1000)));
00087 setTime(wholeSecs, reminder);
00088 }
00090 void setTime(sec_type sec, nsec_type nsec)
00091 {
00092 if (0 <= nsec) {
00093 _sec = sec + nsec / (1000*1000*1000);
00094 _nsec = nsec % (1000*1000*1000);
00095 } else {
00096 _sec = sec - 1 + nsec / (1000*1000*1000);
00097 _nsec = (1000*1000*1000) + nsec % (1000*1000*1000);
00098 }
00099 }
00100
00101
00103 long get_seconds() const { return _sec; }
00104
00106 int get_usec() const { return _nsec/1000; }
00107
00109 const sec_type& getSeconds() const
00110 { return _sec; }
00112 const nsec_type& getNanoSeconds() const
00113 { return _nsec; }
00114
00120 double toNSecs() const
00121 { return _nsec + double(_sec)*1000*1000*1000; }
00122
00128 double toUSecs() const
00129 { return 1e-3*_nsec + double(_sec)*1000*1000; }
00130
00136 double toMSecs() const
00137 { return 1e-6*_nsec + double(_sec)*1000; }
00138
00144 double toSecs() const
00145 { return 1e-9*_nsec + _sec; }
00146
00149 SGTimeStamp& operator+=(const SGTimeStamp& c)
00150 {
00151 _sec += c._sec;
00152 _nsec += c._nsec;
00153 if ((1000*1000*1000) <= _nsec) {
00154 _nsec -= (1000*1000*1000);
00155 _sec += 1;
00156 }
00157 return *this;
00158 }
00159
00162 SGTimeStamp& operator-=(const SGTimeStamp& c)
00163 {
00164 _sec -= c._sec;
00165 _nsec -= c._nsec;
00166 if (_nsec < 0) {
00167 _nsec += (1000*1000*1000);
00168 _sec -= 1;
00169 }
00170 return *this;
00171 }
00172
00176 static SGTimeStamp fromSecMSec(sec_type sec, nsec_type msec)
00177 { return SGTimeStamp(sec, 1000*1000*msec); }
00178 static SGTimeStamp fromSecUSec(sec_type sec, nsec_type usec)
00179 { return SGTimeStamp(sec, 1000*usec); }
00180 static SGTimeStamp fromSecNSec(sec_type sec, nsec_type nsec)
00181 { return SGTimeStamp(sec, nsec); }
00182
00183 static SGTimeStamp fromSec(int sec)
00184 { SGTimeStamp ts; ts.setTime(sec); return ts; }
00185 static SGTimeStamp fromSec(const double& sec)
00186 { SGTimeStamp ts; ts.setTime(sec); return ts; }
00187 static SGTimeStamp fromUSec(nsec_type usec)
00188 { return SGTimeStamp(0, 1000*usec); }
00189 static SGTimeStamp fromNSec(nsec_type nsec)
00190 { return SGTimeStamp(0, nsec); }
00191
00195 static SGTimeStamp now()
00196 { SGTimeStamp ts; ts.stamp(); return ts; }
00197
00198 private:
00199 SGTimeStamp(sec_type sec, nsec_type nsec)
00200 { setTime(sec, nsec); }
00201
00202 nsec_type _nsec;
00203 sec_type _sec;
00204 };
00205
00206 inline bool
00207 operator==(const SGTimeStamp& c1, const SGTimeStamp& c2)
00208 {
00209 if (c1.getNanoSeconds() != c2.getNanoSeconds())
00210 return false;
00211 return c1.getSeconds() == c2.getSeconds();
00212 }
00213
00214 inline bool
00215 operator!=(const SGTimeStamp& c1, const SGTimeStamp& c2)
00216 { return !operator==(c1, c2); }
00217
00218 inline bool
00219 operator<(const SGTimeStamp& c1, const SGTimeStamp& c2)
00220 {
00221 if (c1.getSeconds() < c2.getSeconds())
00222 return true;
00223 if (c1.getSeconds() > c2.getSeconds())
00224 return false;
00225 return c1.getNanoSeconds() < c2.getNanoSeconds();
00226 }
00227
00228 inline bool
00229 operator>(const SGTimeStamp& c1, const SGTimeStamp& c2)
00230 { return c2 < c1; }
00231
00232 inline bool
00233 operator>=(const SGTimeStamp& c1, const SGTimeStamp& c2)
00234 { return !(c1 < c2); }
00235
00236 inline bool
00237 operator<=(const SGTimeStamp& c1, const SGTimeStamp& c2)
00238 { return !(c1 > c2); }
00239
00240 inline SGTimeStamp
00241 operator+(const SGTimeStamp& c1)
00242 { return c1; }
00243
00244 inline SGTimeStamp
00245 operator-(const SGTimeStamp& c1)
00246 { return SGTimeStamp::fromSec(0) -= c1; }
00247
00248 inline SGTimeStamp
00249 operator+(const SGTimeStamp& c1, const SGTimeStamp& c2)
00250 { return SGTimeStamp(c1) += c2; }
00251
00252 inline SGTimeStamp
00253 operator-(const SGTimeStamp& c1, const SGTimeStamp& c2)
00254 { return SGTimeStamp(c1) -= c2; }
00255
00256 template<typename char_type, typename traits_type>
00257 inline
00258 std::basic_ostream<char_type, traits_type>&
00259 operator<<(std::basic_ostream<char_type, traits_type>& os, const SGTimeStamp& c)
00260 {
00261 std::basic_stringstream<char_type, traits_type> stream;
00262
00263 SGTimeStamp pos = c;
00264 if (c.getSeconds() < 0) {
00265 stream << stream.widen('-');
00266 pos = - c;
00267 }
00268 stream << pos.getSeconds() << stream.widen('.');
00269 stream << std::setw(9) << std::setfill('0') << pos.getNanoSeconds();
00270
00271 return os << stream.str();
00272 }
00273
00274 #endif // _TIMESTAMP_HXX
00275
00276