[Positioning] Redesign Timestamp

Use almost only operators for the public interface.
This commit is contained in:
Matteo Cypriani 2010-03-01 16:52:37 +01:00
parent c559b827ee
commit 0430b1a5da
10 changed files with 351 additions and 135 deletions

View File

@ -44,10 +44,9 @@
principes exposés dans le chapitre 6 (p. 103) : implanter
systématiquement des accesseurs pour tous les attributs d'une
classe expose l'implantation de la classe et rend ses attributs
publics. La classe Direction tend à respecter ce principe en
utilisant mieux les opérateurs et en ne proposant pas d'accesseur
direct. La classe Timestamp serait facile à modifier de cette
manière.
publics. La classe Direction (et maintenant Timestamp) tend à
respecter ce principe en utilisant mieux les opérateurs et en ne
proposant pas d'accesseur direct.
- Divers
° Passage de pointeurs en argument : const * const <type>

View File

@ -58,7 +58,7 @@ const string InputLogCSV::request_to_csv(const Request &request) const
ostringstream csv_line ;
if (request.get_mobile() != NULL)
csv_line << request.get_mobile()->get_mac_addr() ;
csv_line << ';' << request.get_timestamp().get_timestamp_ms() << ';' ;
csv_line << ';' << request.get_timestamp() << ';' ;
const CalibrationRequest *calibration_request =
dynamic_cast<const CalibrationRequest*>(&request) ;

View File

@ -64,7 +64,7 @@ Request::~Request()
void Request::clear()
{
mobile = NULL ;
timestamp.set_timestamp_ms(0) ;
timestamp.clear() ;
measurements.clear() ;
}

View File

@ -145,7 +145,7 @@ inline Request::operator bool() const
{
return
mobile != NULL ||
timestamp.get_timestamp_ms() != 0 ||
timestamp ||
measurements.size() > 0 ;
}

View File

@ -7,46 +7,40 @@
Timestamp::Timestamp()
{
timestamp.tv_sec = 0 ;
timestamp.tv_nsec = 0 ;
clear() ;
}
Timestamp::Timestamp(const struct timespec &source)
{
set_timestamp(source) ;
set(source) ;
round_to_ms() ;
}
Timestamp::Timestamp(const uint64_t source_ms)
Timestamp::Timestamp(const uint64_t source)
{
set_timestamp_ms(source_ms) ;
set(source) ;
}
Timestamp::Timestamp(const Timestamp &source)
{
timestamp.tv_sec = source.timestamp.tv_sec ;
timestamp.tv_nsec = source.timestamp.tv_nsec ;
set(source.timestamp) ;
}
/* *** Read accessors *** */
/* *** Internal accessors *** */
uint64_t Timestamp::get_timestamp_ms(void) const
inline void Timestamp::set(const struct timespec &source)
{
return timestamp.tv_sec * 1000 + timestamp.tv_nsec / 1000000 ;
timestamp = source ;
}
/* *** Write accessors *** */
void Timestamp::set_timestamp_ms(const uint64_t source_ms)
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 ;
@ -57,24 +51,6 @@ void Timestamp::set_timestamp_ms(const uint64_t source_ms)
/* *** Operations *** */
bool Timestamp::now_ns()
{
if (clock_gettime(CLOCK_REALTIME, &timestamp))
return false ;
return true ;
}
/**
* #timestamp nanosecond field precision is set to ms, but the value
* is still in ns.
*/
void Timestamp::round_to_ms()
{
timestamp.tv_nsec = timestamp.tv_nsec / 1000000 * 1000000 ;
}
bool Timestamp::now()
{
if (! now_ns())
@ -85,6 +61,65 @@ bool Timestamp::now()
}
inline bool Timestamp::now_ns()
{
return clock_gettime(CLOCK_REALTIME, &timestamp) == 0 ;
}
/**
* #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) ;
return equals(tmp.timestamp) ;
}
bool Timestamp::less_than(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::greater_than(const struct timespec &source) const
{
if (equals(source))
return false ;
return ! less_than(source) ;
}
/* *** Operators *** */
@ -94,8 +129,7 @@ const Timestamp& Timestamp::operator=(const Timestamp &source)
if (this == &source)
return *this ;
timestamp.tv_sec = source.timestamp.tv_sec ;
timestamp.tv_nsec = source.timestamp.tv_nsec ;
set(source.timestamp) ;
return *this ;
}
@ -105,32 +139,13 @@ bool Timestamp::operator==(const Timestamp &source) const
{
if (this == &source)
return true ;
return
timestamp.tv_sec == source.timestamp.tv_sec &&
timestamp.tv_nsec == source.timestamp.tv_nsec ;
}
bool Timestamp::operator<(const Timestamp &source) const
{
if (timestamp.tv_sec < source.timestamp.tv_sec)
return true ;
if (timestamp.tv_sec > source.timestamp.tv_sec)
return false ;
// Second values are equal
if (timestamp.tv_nsec < source.timestamp.tv_nsec)
return true ;
return false ;
return equals(source.timestamp) ;
}
std::ostream& operator<<(std::ostream &os, const Timestamp &t)
{
os << t.get_timestamp_ms() ;
os << static_cast<uint64_t>(t) ;
return os ;
}

View File

@ -16,6 +16,21 @@ protected:
/// Time data
struct timespec timestamp ;
/** @name Internal accessors */
//@{
void set(const struct timespec &source) ;
/// Initialises the Timestamp with a value in milliseconds
void set(const uint64_t source_ms) ;
//@}
/** @name Comparison functions */
//@{
bool equals(const struct timespec &source) const ;
bool equals(const uint64_t source) const ;
bool less_than(const struct timespec &source) const ;
bool greater_than(const struct timespec &source) const ;
//@}
/** @name Operations */
//@{
/// \brief Initialises #timestamp at the current time whith a
@ -27,49 +42,47 @@ protected:
public:
/// Default constructor
Timestamp(void) ;
/// Constructs a Timestamp from a struct timespec
Timestamp(const struct timespec &source) ;
/// Constructs a Timsestamp from a value in milliseconds
Timestamp(const uint64_t source_ms) ;
/// Copy constructor
Timestamp(const uint64_t source) ;
Timestamp(const Timestamp &source) ;
~Timestamp(void) {} ///< Destructor (do nothing)
~Timestamp(void) {}
/** @name Read accessors */
//@{
/// #timestamp read accessor
const struct timespec& get_timestamp(void) const ;
/// Get the #timestamp in milliseconds
uint64_t get_timestamp_ms(void) const ;
//@}
/** @name Write accessors */
//@{
/// #timestamp write accessor
void set_timestamp(const struct timespec &source) ;
/// #timestamp write accessor with a value in milliseconds
void set_timestamp_ms(const uint64_t source_ms) ;
//@}
/** @name Operations */
//@{
/// \brief Initialises #timestamp to the current time with a
/// millisecond precision
bool now(void) ;
//@}
void clear(void) ;
/** @name Operators */
//@{
const Timestamp& operator=(const Timestamp &source) ;
const Timestamp& operator=(const struct timespec &source) ;
const Timestamp& operator=(const uint64_t source) ;
bool operator==(const Timestamp &source) const ;
bool operator==(const struct timespec &source) const ;
bool operator==(const uint64_t source) const ;
bool operator!=(const Timestamp &source) const ;
bool operator!=(const struct timespec &source) const ;
bool operator!=(const uint64_t source) const ;
bool operator<(const Timestamp &source) const ;
bool operator<(const struct timespec &source) const ;
bool operator<(const uint64_t source) const ;
bool operator>(const Timestamp &source) const ;
bool operator>(const struct timespec &source) const ;
bool operator>(const uint64_t source) const ;
bool operator<=(const Timestamp &source) const ;
bool operator<=(const struct timespec &source) const ;
bool operator<=(const uint64_t source) const ;
bool operator>=(const Timestamp &source) const ;
bool operator>=(const struct timespec &source) const ;
bool operator>=(const uint64_t source) const ;
operator bool(void) const ;
operator const struct timespec&(void) const ;
/// Cast to milliseconds
operator uint64_t(void) const ;
//@}
/// Display a Timestamp
@ -78,22 +91,10 @@ public:
/* *** Read accessors *** */
inline const struct timespec& Timestamp::get_timestamp() const
inline void Timestamp::clear(void)
{
return timestamp ;
}
/* *** Write accessors *** */
inline void Timestamp::set_timestamp(const struct timespec &source)
{
timestamp = source ;
timestamp.tv_sec = 0 ;
timestamp.tv_nsec = 0 ;
}
@ -101,15 +102,84 @@ inline void Timestamp::set_timestamp(const struct timespec &source)
/* *** Operators *** */
inline const Timestamp& Timestamp::
operator=(const struct timespec &source)
{
set(source) ;
return *this ;
}
inline const Timestamp& Timestamp::operator=(const uint64_t source)
{
set(source) ;
return *this ;
}
inline bool Timestamp::operator==(const struct timespec &source) const
{
return equals(source) ;
}
inline bool Timestamp::operator==(const uint64_t source) const
{
return equals(source) ;
}
inline bool Timestamp::operator!=(const Timestamp &source) const
{
return !(*this == source) ;
}
inline bool Timestamp::operator!=(const struct timespec &source) const
{
return !(*this == source) ;
}
inline bool Timestamp::operator!=(const uint64_t source) const
{
return !(*this == source) ;
}
inline bool Timestamp::operator<(const Timestamp &source) const
{
return less_than(source.timestamp) ;
}
inline bool Timestamp::operator<(const struct timespec &source) const
{
return less_than(source) ;
}
inline bool Timestamp::operator<(const uint64_t source) const
{
return static_cast<uint64_t>(*this) < source ;
}
inline bool Timestamp::operator>(const Timestamp &source) const
{
return source < *this ;
return greater_than(source.timestamp) ;
}
inline bool Timestamp::operator>(const struct timespec &source) const
{
return greater_than(source) ;
}
inline bool Timestamp::operator>(const uint64_t source) const
{
return static_cast<uint64_t>(*this) > source ;
}
@ -119,10 +189,53 @@ inline bool Timestamp::operator<=(const Timestamp &source) const
}
inline bool Timestamp::operator<=(const struct timespec &source) const
{
return *this == source || *this < source ;
}
inline bool Timestamp::operator<=(const uint64_t source) const
{
return *this == source || *this < source ;
}
inline bool Timestamp::operator>=(const Timestamp &source) const
{
return source <= *this ;
}
inline bool Timestamp::operator>=(const struct timespec &source) const
{
return *this == source || !(*this < source) ;
}
inline bool Timestamp::operator>=(const uint64_t source) const
{
return *this == source || !(*this < source) ;
}
inline Timestamp::operator bool() const
{
return static_cast<uint64_t>(*this) > 0 ;
}
inline Timestamp::operator const struct timespec&() const
{
return timestamp ;
}
inline Timestamp::operator uint64_t(void) const
{
return timestamp.tv_sec * 1000 + timestamp.tv_nsec / 1000000 ;
}
#endif // _OWLPS_POSITIONING_TIMESTAMP_HH_

View File

@ -52,7 +52,7 @@ public:
calibrationrequest1.set_mobile(&mobile2) ;
TS_ASSERT_EQUALS(calibrationrequest1.get_mobile(), &mobile2) ;
timestamp1.set_timestamp_ms(42) ;
timestamp1 = 42 ;
calibrationrequest1.set_timestamp(timestamp1) ;
TS_ASSERT_EQUALS(calibrationrequest1.get_timestamp(), timestamp1) ;

View File

@ -47,7 +47,7 @@ public:
r1.set_mobile(&mob2) ;
TS_ASSERT_EQUALS(r1.get_mobile(), &mob2) ;
current_time.set_timestamp_ms(current_time.get_timestamp_ms() + 10) ;
current_time = static_cast<uint64_t>(current_time) + 10 ;
r1.set_timestamp(current_time) ;
TS_ASSERT_EQUALS(r1.get_timestamp(), current_time) ;

View File

@ -161,7 +161,7 @@ create_test_csv_file(const string &file_name, bool with_spaces)
if (with_spaces)
line << "\n \n " ;
line << mobiles[0].get_mac_addr() ;
line << ';' << requests.at(0)->get_timestamp().get_timestamp_ms() ;
line << ';' << requests.at(0)->get_timestamp() ;
line << ";0;0;0;0;" ;
line << aps[0].get_mac_addr() ;
line << ';' << requests.at(0)->get_measurements()
@ -186,7 +186,7 @@ create_test_csv_file(const string &file_name, bool with_spaces)
CalibrationRequest *calibration_request =
dynamic_cast<CalibrationRequest*>(requests.at(1)) ;
assert(calibration_request) ;
line << ';' << calibration_request->get_timestamp().get_timestamp_ms() ;
line << ';' << calibration_request->get_timestamp() ;
line << ';' << reference_points.at(0).get_x() ;
line << ';' << reference_points.at(0).get_y() ;
line << ';' << reference_points.at(0).get_z() ;
@ -218,7 +218,7 @@ create_test_csv_file(const string &file_name, bool with_spaces)
if (with_spaces)
line << '\t' ;
line << mobiles[0].get_mac_addr() ;
line << ';' << requests.at(2)->get_timestamp().get_timestamp_ms() ;
line << ';' << requests.at(2)->get_timestamp() ;
line << ";0;0;0;0;" ;
line << aps[2].get_mac_addr() ;
line << ';' << requests.at(2)->get_measurements()

View File

@ -34,9 +34,15 @@ public:
Timestamp timestamp3(msec) ;
TS_ASSERT_EQUALS(timestamp1, timestamp3) ;
// Read accessors
TS_ASSERT_EQUALS(timestamp1.get_timestamp(), timespec1) ;
TS_ASSERT_EQUALS(timestamp1.get_timestamp_ms(), msec) ;
// Copy constructor
Timestamp timestamp4(timestamp1) ;
TS_ASSERT_EQUALS(timestamp1, timestamp4) ;
// Equality
TS_ASSERT_EQUALS(static_cast<struct timespec>(timestamp1), timespec1) ;
TS_ASSERT_EQUALS(timestamp1, timespec1) ;
TS_ASSERT_EQUALS(static_cast<uint64_t>(timestamp1), msec) ;
TS_ASSERT_EQUALS(timestamp1, msec) ;
}
void test_non_zero(void)
@ -51,14 +57,22 @@ public:
// struct timespec constructor
Timestamp timestamp1(timespec1) ;
timespec1.tv_nsec = nsec / 1000000 * 1000000 ; // Round to ms
TS_ASSERT_EQUALS(timestamp1.get_timestamp(), timespec1) ;
TS_ASSERT_EQUALS(timestamp1.get_timestamp_ms(), msec) ;
TS_ASSERT_EQUALS(static_cast<struct timespec>(timestamp1), timespec1) ;
TS_ASSERT_EQUALS(timestamp1, timespec1) ;
TS_ASSERT_EQUALS(static_cast<uint64_t>(timestamp1), msec) ;
TS_ASSERT_EQUALS(timestamp1, msec) ;
// ms constructor
Timestamp timestamp2(msec) ;
TS_ASSERT_EQUALS(timestamp2.get_timestamp(), timespec1) ;
TS_ASSERT_EQUALS(timestamp2.get_timestamp_ms(), msec) ;
TS_ASSERT_EQUALS(static_cast<struct timespec>(timestamp2), timespec1) ;
TS_ASSERT_EQUALS(timestamp2, timespec1) ;
TS_ASSERT_EQUALS(static_cast<uint64_t>(timestamp2), msec) ;
TS_ASSERT_EQUALS(timestamp2, msec) ;
TS_ASSERT_EQUALS(timestamp1, timestamp2) ;
// Copy constructor
Timestamp timestamp3(timestamp1) ;
TS_ASSERT_EQUALS(timestamp1, timestamp3) ;
}
void test_current_time(void)
@ -66,8 +80,8 @@ public:
Timestamp timestamp1 ;
struct timespec current_time ;
if (! timestamp1.now() ||
clock_gettime(CLOCK_REALTIME, &current_time))
TS_ASSERT(timestamp1.now()) ;
if (clock_gettime(CLOCK_REALTIME, &current_time))
{
TS_FAIL("Error getting current time!") ;
return ;
@ -75,16 +89,18 @@ public:
Timestamp timestamp2(current_time) ;
TS_ASSERT_DELTA(timestamp1.get_timestamp_ms(),
timestamp2.get_timestamp_ms(),
TS_ASSERT_DELTA(static_cast<uint64_t>(timestamp1),
static_cast<uint64_t>(timestamp2),
100) ;
// The following tests may fail if the ns value is a ms
TS_ASSERT_DIFFERS(timestamp1.get_timestamp(), current_time) ;
TS_ASSERT_DIFFERS(timestamp2.get_timestamp(), current_time) ;
TS_ASSERT_DIFFERS(static_cast<struct timespec>(timestamp1), current_time) ;
TS_ASSERT_DIFFERS(timestamp1, current_time) ;
TS_ASSERT_DIFFERS(static_cast<struct timespec>(timestamp2), current_time) ;
TS_ASSERT_DIFFERS(timestamp2, current_time) ;
}
void test_accessors(void)
void test_affectation(void)
{
struct timespec current_time ;
if (clock_gettime(CLOCK_REALTIME, &current_time))
@ -95,28 +111,101 @@ public:
// struct timespec constructor
Timestamp timestamp1(current_time) ;
TS_ASSERT_DIFFERS(timestamp1.get_timestamp(), current_time) ;
TS_ASSERT_DIFFERS(static_cast<struct timespec>(timestamp1), current_time) ;
TS_ASSERT_DIFFERS(timestamp1, current_time) ;
// ms constructor
current_time.tv_nsec = current_time.tv_nsec / 1000000 * 1000000 ;
uint64_t msec = timestamp1.get_timestamp_ms() ;
uint64_t msec = timestamp1 ;
Timestamp timestamp2(msec) ;
TS_ASSERT_EQUALS(timestamp2.get_timestamp_ms(), msec) ;
TS_ASSERT_EQUALS(timestamp2.get_timestamp(), current_time) ;
TS_ASSERT_EQUALS(static_cast<uint64_t>(timestamp2), msec) ;
TS_ASSERT_EQUALS(timestamp2, msec) ;
TS_ASSERT_EQUALS(static_cast<struct timespec>(timestamp2), current_time) ;
TS_ASSERT_EQUALS(timestamp2, current_time) ;
// Accessors
// Affectation
++current_time.tv_sec ;
timestamp2.set_timestamp(current_time) ;
timestamp2 = current_time ;
TS_ASSERT_DIFFERS(timestamp1, timestamp2) ;
msec = timestamp2.get_timestamp_ms() ;
TS_ASSERT_EQUALS(timestamp2.get_timestamp_ms(), msec) ;
TS_ASSERT_EQUALS(timestamp2.get_timestamp(), current_time) ;
msec = timestamp2 ;
TS_ASSERT_EQUALS(static_cast<uint64_t>(timestamp2), msec) ;
TS_ASSERT_EQUALS(timestamp2, msec) ;
TS_ASSERT_EQUALS(static_cast<struct timespec>(timestamp2), current_time) ;
TS_ASSERT_EQUALS(timestamp2, current_time) ;
msec = 1234567891234567ull ;
timestamp2.set_timestamp_ms(msec) ;
TS_ASSERT_EQUALS(timestamp2.get_timestamp_ms(), msec) ;
current_time = timestamp2.get_timestamp() ;
TS_ASSERT_EQUALS(timestamp2.get_timestamp(), current_time) ;
timestamp2 = msec ;
TS_ASSERT_EQUALS(static_cast<uint64_t>(timestamp2), msec) ;
TS_ASSERT_EQUALS(timestamp2, msec) ;
current_time = timestamp2 ;
TS_ASSERT_EQUALS(static_cast<struct timespec>(timestamp2), current_time) ;
TS_ASSERT_EQUALS(timestamp2, current_time) ;
}
void test_comparison(void)
{
Timestamp today ;
today.now() ;
Timestamp today2(today) ;
struct timespec today_timespec = today ;
uint64_t today_int = today ;
uint64_t yesterday_int = today_int - 3600*24 ;
Timestamp yesterday(yesterday_int) ;
struct timespec yesterday_timespec = yesterday ;
TS_ASSERT_EQUALS(today, today2) ;
TS_ASSERT_LESS_THAN_EQUALS(today, today2) ;
TS_ASSERT(today >= today2) ;
TS_ASSERT(! (today > today2)) ;
TS_ASSERT(! (today < today2)) ;
TS_ASSERT_EQUALS(today, today_int) ;
TS_ASSERT_LESS_THAN_EQUALS(today, today_int) ;
TS_ASSERT(today >= today_int) ;
TS_ASSERT(! (today > today_int)) ;
TS_ASSERT(! (today < today_int)) ;
TS_ASSERT_EQUALS(today, today_timespec) ;
TS_ASSERT_LESS_THAN_EQUALS(today, today_timespec) ;
TS_ASSERT(today >= today_timespec) ;
TS_ASSERT(! (today > today_timespec)) ;
TS_ASSERT(! (today < today_timespec)) ;
TS_ASSERT_DIFFERS(today, yesterday) ;
TS_ASSERT_LESS_THAN(yesterday, today) ;
TS_ASSERT_LESS_THAN_EQUALS(yesterday, today) ;
TS_ASSERT(! (yesterday > today)) ;
TS_ASSERT(! (yesterday >= today)) ;
TS_ASSERT_DIFFERS(today, yesterday_int) ;
TS_ASSERT_LESS_THAN(yesterday, today_int) ;
TS_ASSERT_LESS_THAN_EQUALS(yesterday, today_int) ;
TS_ASSERT(! (yesterday > today_int)) ;
TS_ASSERT(! (yesterday >= today_int)) ;
TS_ASSERT_DIFFERS(today, yesterday_timespec) ;
TS_ASSERT_LESS_THAN(yesterday, today_timespec) ;
TS_ASSERT_LESS_THAN_EQUALS(yesterday, today_timespec) ;
TS_ASSERT(! (yesterday > today_timespec)) ;
TS_ASSERT(! (yesterday >= today_timespec)) ;
}
void test_clear(void)
{
uint64_t zero = 0 ;
struct timespec zero_timespec ;
zero_timespec.tv_sec = 0 ;
zero_timespec.tv_nsec = 0 ;
Timestamp zero_timestamp ;
Timestamp today ;
today.now() ;
TS_ASSERT_DIFFERS(today, zero) ;
TS_ASSERT_DIFFERS(today, zero_timespec) ;
TS_ASSERT_DIFFERS(today, zero_timestamp) ;
today.clear() ;
TS_ASSERT_EQUALS(today, zero) ;
TS_ASSERT_EQUALS(today, zero_timespec) ;
TS_ASSERT_EQUALS(today, zero_timestamp) ;
}
} ;