/* * This file is part of the Owl Positioning System (OwlPS) project. * It is subject to the copyright notice and license terms in the * COPYRIGHT.t2t file found in the top-level directory of this * distribution and at * https://code.lm7.fr/mcy/owlps/src/master/COPYRIGHT.t2t * No part of the OwlPS Project, including this file, may be copied, * modified, propagated, or distributed except according to the terms * contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be * distributed along with this file, either separately or by replacing * this notice by the COPYRIGHT.t2t file's contents. */ #include "timestamp.hh" #include "configuration.hh" #include #include using namespace std ; Timestamp Timestamp::current_time ; /* *** Constructors *** */ Timestamp::Timestamp() { clear() ; } Timestamp::Timestamp(const struct timespec &source) { set(source) ; } Timestamp::Timestamp(const owl_timestamp &source) { set(source) ; } Timestamp::Timestamp(const uint_fast32_t source_s, const uint_fast32_t source_ns) { set(source_s, source_ns) ; } Timestamp::Timestamp(const uint64_t source) { set(source) ; } Timestamp::Timestamp(const Timestamp &source) { set(source.timestamp) ; } /* *** Internal accessors *** */ inline void Timestamp::set(const struct timespec &source) { timestamp = source ; } inline void Timestamp::set(const owl_timestamp &source) { set(source.tv_sec, source.tv_nsec) ; } inline void Timestamp::set(const uint_fast32_t source_s, const uint_fast32_t source_ns) { timestamp.tv_sec = source_s ; timestamp.tv_nsec = source_ns ; } inline void Timestamp::set(const uint64_t source_ms) { timestamp.tv_sec = source_ms / 1000 ; timestamp.tv_nsec = (source_ms - timestamp.tv_sec * 1000) * 1000000 ; } /* *** Operations *** */ Timestamp Timestamp::get_current_time() { if (! Configuration::bool_value("replay")) current_time.now() ; return current_time ; } /** * @param source A reference to the new time. */ void Timestamp::update_current_time(const Timestamp &source) { // We should only call this function if we are in replay mode: assert(Configuration::bool_value("replay")) ; // According to human perception, time generally goes only forward: if (current_time < source) { current_time = source ; if (Configuration::is_configured("verbose")) cerr << "Current time set to " << current_time << ".\n" ; } else if (Configuration::is_configured("verbose")) cerr << "Current time left unchanged to " << current_time << " (time proposed: " << source << ").\n" ; } bool Timestamp::now() { return clock_gettime(CLOCK_REALTIME, ×tamp) == 0 ; } /** * @returns A Timestamp containing the time elapsed, or an empty * Timestamp in case of error. */ Timestamp Timestamp::elapsed() const { return elapsed(get_current_time()) ; } Timestamp Timestamp::elapsed(const Timestamp &source) const { owl_timestamp d1 = *this, d2 = source, elapsed ; owl_time_elapsed(&d1, &d2, &elapsed) ; return Timestamp(elapsed); } /** * #timestamp nanosecond field precision is set to ms, but the value * is still in ns. */ inline void Timestamp::round_to_ms() { timestamp.tv_nsec = timestamp.tv_nsec / 1000000 * 1000000 ; } /* *** Internal comparison functions *** */ bool Timestamp::equals(const struct timespec &source) const { return timestamp.tv_sec == source.tv_sec && timestamp.tv_nsec == source.tv_nsec ; } bool Timestamp::equals(const uint64_t source) const { Timestamp tmp(source) ; Timestamp me(*this) ; me.round_to_ms() ; return me == tmp ; } bool Timestamp::before(const struct timespec &source) const { if (timestamp.tv_sec < source.tv_sec) return true ; if (timestamp.tv_sec > source.tv_sec) return false ; // Second values are equal if (timestamp.tv_nsec < source.tv_nsec) return true ; return false ; } bool Timestamp::after(const struct timespec &source) const { if (equals(source)) return false ; return ! before(source) ; } /* *** Operators *** */ Timestamp& Timestamp::operator=(const struct timespec &source) { set(source) ; return *this ; } Timestamp& Timestamp::operator=(const uint64_t source) { set(source) ; return *this ; } Timestamp& Timestamp::operator=(const Timestamp &source) { if (this == &source) return *this ; set(source.timestamp) ; return *this ; } bool Timestamp::operator==(const Timestamp &source) const { if (this == &source) return true ; return equals(source.timestamp) ; } ostream& operator<<(ostream &os, const Timestamp &t) { os << t.timestamp.tv_sec << '.' << setw(9) << setfill('0') // force nanoseconds on 9 digits << t.timestamp.tv_nsec ; return os ; } inline Timestamp::operator owl_timestamp(void) const { owl_timestamp ret ; ret.tv_sec = timestamp.tv_sec ; ret.tv_nsec = timestamp.tv_nsec ; return ret ; }