F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Time.cpp
Go to the documentation of this file.
2 #include <Fw/Time/Time.hpp>
3 
4 namespace Fw {
5 const Time ZERO_TIME = Time();
6 
7 Time::Time() : m_val() {
9  m_val.set_timeContext(0);
10  m_val.set_seconds(0);
11  m_val.set_useconds(0);
12 }
13 
15 
16 Time::Time(U32 seconds, U32 useconds) {
17  this->set(TimeBase::TB_NONE, 0, seconds, useconds);
18 }
19 
20 Time::Time(TimeBase timeBase, U32 seconds, U32 useconds) {
21  this->set(timeBase, 0, seconds, useconds);
22 }
23 
24 void Time::set(U32 seconds, U32 useconds) {
25  this->set(this->m_val.get_timeBase(), this->m_val.get_timeContext(), seconds, useconds);
26 }
27 
28 void Time::set(TimeBase timeBase, U32 seconds, U32 useconds) {
29  this->set(timeBase, this->m_val.get_timeContext(), seconds, useconds);
30 }
31 
32 Time::Time(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds) {
33  this->set(timeBase, context, seconds, useconds);
34 }
35 
36 void Time::set(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds) {
37  // Assert microseconds portion is less than 10^6
38  FW_ASSERT(useconds < 1000000, static_cast<FwAssertArgType>(useconds));
39  this->m_val.set(timeBase, context, seconds, useconds);
40 }
41 
42 Fw::Time::Time(F64 seconds) {
43  this->set(seconds);
44 }
45 
46 void Fw::Time::set(F64 seconds) {
47  U32 parsedSeconds = this->parseSeconds(seconds);
48  U32 parsedUseconds = this->parseUSeconds(seconds);
49  // parseUSeconds rounds up to a whole second at 999999.5 or above; carry it as add() does
50  if (parsedUseconds >= 1000000) {
51  parsedSeconds++;
52  parsedUseconds -= 1000000;
53  }
54  this->set(parsedSeconds, parsedUseconds);
55 }
56 
57 Time& Time::operator=(const Time& other) {
58  if (this != &other) {
59  this->m_val = other.m_val;
60  }
61  return *this;
62 }
63 
65  this->set(seconds);
66  return *this;
67 }
68 
70  this->add(seconds);
71  return *this;
72 }
73 
74 bool Time::operator==(const Time& other) const {
75  return (Time::compare(*this, other) == TimeComparison::EQ);
76 }
77 
78 bool Time::operator!=(const Time& other) const {
79  return (Time::compare(*this, other) != TimeComparison::EQ);
80 }
81 
82 bool Time::operator>(const Time& other) const {
83  return (Time::compare(*this, other) == TimeComparison::GT);
84 }
85 
86 bool Time::operator<(const Time& other) const {
87  return (Time::compare(*this, other) == TimeComparison::LT);
88 }
89 
90 bool Time::operator>=(const Time& other) const {
91  TimeComparison c = Time::compare(*this, other);
92  return ((TimeComparison::GT == c) or (TimeComparison::EQ == c));
93 }
94 
95 bool Time::operator<=(const Time& other) const {
96  TimeComparison c = Time::compare(*this, other);
97  return ((TimeComparison::LT == c) or (TimeComparison::EQ == c));
98 }
99 
100 Fw::Time::operator F64() const {
101  const U32 seconds = this->m_val.get_seconds();
102  const U32 useconds = this->m_val.get_useconds();
103  return static_cast<F64>(seconds) + (static_cast<F64>(useconds) / 1000000.0);
104 }
105 
107  return this->m_val;
108 }
109 
111  return this->m_val.serializeTo(buffer, mode);
112 }
113 
115  TimeValue value;
116  const SerializeStatus status = value.deserializeFrom(buffer, mode);
117  if (status != FW_SERIALIZE_OK) {
118  return status;
119  }
120  // Reject out-of-range microseconds rather than admitting a value that asserts on later use
121  if (value.get_useconds() >= 1000000) {
123  }
124  this->m_val = value;
125  return FW_SERIALIZE_OK;
126 }
127 
128 U32 Time::getSeconds() const {
129  return this->m_val.get_seconds();
130 }
131 
132 U32 Time::getUSeconds() const {
133  return this->m_val.get_useconds();
134 }
135 
137  return this->m_val.get_timeBase();
138 }
139 
141  return this->m_val.get_timeContext();
142 }
143 
145  Time time(timeBase, 0, 0, 0);
146  return time;
147 }
148 
149 TimeComparison Time ::compare(const Time& time1, const Time& time2) {
150  if (time1.getTimeBase() != time2.getTimeBase()) {
152  }
153 
154  // Do not compare time context
155 
156  const U32 s1 = time1.getSeconds();
157  const U32 s2 = time2.getSeconds();
158  const U32 us1 = time1.getUSeconds();
159  const U32 us2 = time2.getUSeconds();
160 
161  if (s1 < s2) {
162  return TimeComparison::LT;
163  } else if (s1 > s2) {
164  return TimeComparison::GT;
165  } else if (us1 < us2) {
166  return TimeComparison::LT;
167  } else if (us1 > us2) {
168  return TimeComparison::GT;
169  } else {
170  return TimeComparison::EQ;
171  }
172 }
173 
174 Time Time ::add(const Time& a, const Time& b) {
175  FW_ASSERT(a.getTimeBase() == b.getTimeBase(), static_cast<FwAssertArgType>(a.getTimeBase()),
176  static_cast<FwAssertArgType>(b.getTimeBase()));
177  // Do not assert on time context match
178 
179  U32 seconds = a.getSeconds() + b.getSeconds();
180  U32 uSeconds = a.getUSeconds() + b.getUSeconds();
181  FW_ASSERT(uSeconds < 1999999);
182  if (uSeconds >= 1000000) {
183  ++seconds;
184  uSeconds -= 1000000;
185  }
186 
187  // Return a time context of 0 if they do not match
188  FwTimeContextStoreType context = a.getContext();
189  if (a.getContext() != b.getContext()) {
190  context = 0;
191  }
192 
193  Time c(a.getTimeBase(), context, seconds, uSeconds);
194  return c;
195 }
196 
197 Time Time ::sub(const Time& minuend,
198  const Time& subtrahend
199 ) {
200  FW_ASSERT(minuend.getTimeBase() == subtrahend.getTimeBase(), static_cast<FwAssertArgType>(minuend.getTimeBase()),
201  static_cast<FwAssertArgType>(subtrahend.getTimeBase()));
202  // Do not assert on time context match
203  // Assert minuend is greater than subtrahend
204  FW_ASSERT(minuend >= subtrahend);
205 
206  U32 seconds = minuend.getSeconds() - subtrahend.getSeconds();
207  U32 uSeconds;
208  if (subtrahend.getUSeconds() > minuend.getUSeconds()) {
209  seconds--;
210  uSeconds = minuend.getUSeconds() + 1000000 - subtrahend.getUSeconds();
211  } else {
212  uSeconds = minuend.getUSeconds() - subtrahend.getUSeconds();
213  }
214 
215  // Return a time context of 0 if they do not match
216  FwTimeContextStoreType context = minuend.getContext();
217  if (minuend.getContext() != subtrahend.getContext()) {
218  context = 0;
219  }
220 
221  return Time(minuend.getTimeBase(), context, seconds, static_cast<U32>(uSeconds));
222 }
223 
225  // Assert negative value
226  FW_ASSERT(seconds >= static_cast<F64>(0.0));
227  return static_cast<U32>(seconds);
228 }
229 
231  // Assert negative value
232  FW_ASSERT(seconds >= static_cast<F64>(0.0));
233  U32 parsedSeconds = static_cast<U32>(seconds);
234  const F64 fractionalPart = seconds - static_cast<F64>(parsedSeconds);
235  // Add 0.5 to round to nearest microsecond (e.g, 999999.9999 = 1000000)
236  U32 parsedUSeconds = static_cast<U32>(fractionalPart * static_cast<F64>(1000000.0) + static_cast<F64>(0.5));
237  return parsedUSeconds;
238 }
239 
240 void Time::add(U32 seconds, U32 useconds) {
241  U32 newSeconds = this->m_val.get_seconds() + seconds;
242  U32 newUSeconds = this->m_val.get_useconds() + useconds;
243  FW_ASSERT(newUSeconds < 1999999, static_cast<FwAssertArgType>(newUSeconds));
244  if (newUSeconds >= 1000000) {
245  newSeconds += 1;
246  newUSeconds -= 1000000;
247  }
248  this->set(newSeconds, newUSeconds);
249 }
250 
251 void Time::add(F64 seconds) {
252  U32 parsedSeconds = this->parseSeconds(seconds);
253  U32 parsedUseconds = this->parseUSeconds(seconds);
254  // Add parsed seconds and useconds
255  this->add(parsedSeconds, parsedUseconds);
256 }
257 
258 void Time::setTimeBase(TimeBase timeBase) {
259  this->m_val.set_timeBase(timeBase);
260 }
261 
263  this->m_val.set_timeContext(context);
264 }
265 
266 #ifdef BUILD_UT
267 std::ostream& operator<<(std::ostream& os, const Time& val) {
268  os << "(" << val.getTimeBase() << "," << val.getUSeconds() << "," << val.getSeconds() << ")";
269  return os;
270 }
271 #endif
272 
273 } // namespace Fw
Serialization/Deserialization operation was successful.
bool operator<=(const Time &other) const
Definition: Time.cpp:95
U32 get_useconds() const
Get member useconds.
FwTimeContextStoreType get_timeContext() const
Get member timeContext.
Time & operator=(const Time &other)
Definition: Time.cpp:57
TimeValue asTimeValue() const
get the underlying TimeValue
Definition: Time.cpp:106
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG)
Deserialization.
const Time ZERO_TIME
Definition: Time.cpp:5
TimeBase getTimeBase() const
Definition: Time.cpp:136
Deserialization data had incorrect values (unexpected data types)
No time base has been established (Required)
TimeBase::T get_timeBase() const
Get member timeBase.
U8 FwTimeContextStoreType
The type used to serialize a time context value.
Fw::SerializeStatus serializeTo(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) const
Serialization.
static Time sub(const Time &minuend, const Time &subtrahend)
Definition: Time.cpp:197
bool operator==(const Time &other) const
Definition: Time.cpp:74
SerializeStatus
forward declaration for string
static Time zero(TimeBase timeBase=TimeBase::TB_NONE)
The type of a comparison result.
Definition: Time.cpp:144
bool operator!=(const Time &other) const
Definition: Time.cpp:78
void set_seconds(U32 seconds)
Set member seconds.
void setTimeContext(FwTimeContextStoreType context)
Definition: Time.cpp:262
static U32 parseUSeconds(F64 seconds)
Extract microseconds from a floating-point (F64)
Definition: Time.cpp:230
void set(U32 seconds, U32 useconds)
Definition: Time.cpp:24
Time & operator+=(F64 seconds)
Add floating-point (F64) value to this Time.
Definition: Time.cpp:69
bool operator>(const Time &other) const
Definition: Time.cpp:82
bool operator>=(const Time &other) const
Definition: Time.cpp:90
static U32 parseSeconds(F64 seconds)
Extract seconds from a floating-point (F64)
Definition: Time.cpp:224
U32 getSeconds() const
Definition: Time.cpp:128
void set(TimeBase::T timeBase, FwTimeContextStoreType timeContext, U32 seconds, U32 useconds)
Set all members.
void setTimeBase(TimeBase timeBase)
Definition: Time.cpp:258
Data structure for Time.
void set_timeBase(TimeBase::T timeBase)
Set member timeBase.
void set_timeContext(FwTimeContextStoreType timeContext)
Set member timeContext.
static TimeComparison compare(const Time &time1, const Time &time2)
Definition: Time.cpp:149
static Time add(const Time &a, const Time &b)
Definition: Time.cpp:174
FwTimeContextStoreType getContext() const
Definition: Time.cpp:140
U32 getUSeconds() const
Definition: Time.cpp:132
Time()
Definition: Time.cpp:7
double F64
64-bit floating point (double). Required for compiler-supplied double promotion.
Definition: BasicTypes.h:86
U32 get_seconds() const
Get member seconds.
SerializeStatus serializeTo(SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) const override
Serialize the contents of this object to a buffer.
Definition: Time.cpp:110
Implementation of malloc based allocator.
Endianness
virtual ~Time()
Definition: Time.cpp:14
bool operator<(const Time &other) const
Definition: Time.cpp:86
Define enumeration for Time base types.
#define FW_ASSERT(...)
Definition: Assert.hpp:14
SerializeStatus deserializeFrom(SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Deserialize the contents of this object from a buffer.
Definition: Time.cpp:114
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
void set_useconds(U32 useconds)
Set member useconds.