GCC Code Coverage Report


Directory: ./
File: Fw/Time/Time.cpp
Date: 2026-09-03 22:12:29
Exec Total Coverage
Lines: 67 162 41.4%
Functions: 17 37 45.9%
Branches: 27 73 37.0%

Line Branch Exec Source
1 #include <Fw/FPrimeBasicTypes.hpp>
2 #include <Fw/Time/Time.hpp>
3
4 namespace Fw {
5 const Time ZERO_TIME = Time();
6
7
1/1
✓ Branch 2 taken 7414 times.
7421 Time::Time() : m_val() {
8
1/1
✓ Branch 1 taken 7416 times.
7414 m_val.set_timeBase(TimeBase::TB_NONE);
9
1/1
✓ Branch 1 taken 7416 times.
7416 m_val.set_timeContext(0);
10
1/1
✓ Branch 1 taken 7415 times.
7416 m_val.set_seconds(0);
11
1/1
✓ Branch 1 taken 7419 times.
7415 m_val.set_useconds(0);
12 7419 }
13
14 21690 Time::~Time() {}
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 15 void Time::set(U32 seconds, U32 useconds) {
25
2/2
✓ Branch 3 taken 15 times.
✓ Branch 6 taken 15 times.
15 this->set(this->m_val.get_timeBase(), this->m_val.get_timeContext(), seconds, useconds);
26 15 }
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 3879 void Time::set(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds) {
37 // Assert microseconds portion is less than 10^6
38 3879 FW_ASSERT(useconds < 1000000, static_cast<FwAssertArgType>(useconds));
39 3879 this->m_val.set(timeBase, context, seconds, useconds);
40 3879 }
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 3517 Time& Time::operator=(const Time& other) {
58
1/2
✓ Branch 0 taken 3517 times.
✗ Branch 1 not taken.
3517 if (this != &other) {
59 3517 this->m_val = other.m_val;
60 }
61 3517 return *this;
62 }
63
64 Time& Fw::Time::operator=(F64 seconds) {
65 this->set(seconds);
66 return *this;
67 }
68
69 Time& Fw::Time::operator+=(F64 seconds) {
70 this->add(seconds);
71 return *this;
72 }
73
74 3069 bool Time::operator==(const Time& other) const {
75
1/1
✓ Branch 1 taken 3069 times.
3069 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 5 bool Time::operator>=(const Time& other) const {
91
1/1
✓ Branch 1 taken 5 times.
5 TimeComparison c = Time::compare(*this, other);
92
3/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 1 times.
10 return ((TimeComparison::GT == c) or (TimeComparison::EQ == c));
93 5 }
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
106 TimeValue Time::asTimeValue() const {
107 return this->m_val;
108 }
109
110 3760 SerializeStatus Time::serializeTo(SerialBufferBase& buffer, Fw::Endianness mode) const {
111 3760 return this->m_val.serializeTo(buffer, mode);
112 }
113
114 444 SerializeStatus Time::deserializeFrom(SerialBufferBase& buffer, Fw::Endianness mode) {
115
1/1
✓ Branch 1 taken 444 times.
444 TimeValue value;
116
1/1
✓ Branch 1 taken 444 times.
444 const SerializeStatus status = value.deserializeFrom(buffer, mode);
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 444 times.
444 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 444 times.
444 if (value.get_useconds() >= 1000000) {
122 return FW_DESERIALIZE_FORMAT_ERROR;
123 }
124
1/1
✓ Branch 1 taken 444 times.
444 this->m_val = value;
125 444 return FW_SERIALIZE_OK;
126 444 }
127
128 6606 U32 Time::getSeconds() const {
129 6606 return this->m_val.get_seconds();
130 }
131
132 6603 U32 Time::getUSeconds() const {
133 6603 return this->m_val.get_useconds();
134 }
135
136 6600 TimeBase Time::getTimeBase() const {
137 6600 return this->m_val.get_timeBase();
138 }
139
140 2 FwTimeContextStoreType Time::getContext() const {
141 2 return this->m_val.get_timeContext();
142 }
143
144 Time Time ::zero(TimeBase timeBase) {
145 Time time(timeBase, 0, 0, 0);
146 return time;
147 }
148
149 3075 TimeComparison Time ::compare(const Time& time1, const Time& time2) {
150
3/4
✓ Branch 1 taken 3076 times.
✓ Branch 5 taken 3076 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 3076 times.
3075 if (time1.getTimeBase() != time2.getTimeBase()) {
151 return TimeComparison::INCOMPARABLE;
152 }
153
154 // Do not compare time context
155
156 3076 const U32 s1 = time1.getSeconds();
157 3076 const U32 s2 = time2.getSeconds();
158 3076 const U32 us1 = time1.getUSeconds();
159 3076 const U32 us2 = time2.getUSeconds();
160
161
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3072 times.
3074 if (s1 < s2) {
162 2 return TimeComparison::LT;
163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3072 times.
3072 } else if (s1 > s2) {
164 return TimeComparison::GT;
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3072 times.
3072 } else if (us1 < us2) {
166 return TimeComparison::LT;
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3072 times.
3072 } else if (us1 > us2) {
168 return TimeComparison::GT;
169 } else {
170 3072 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, //!< Time minuend
198 const Time& subtrahend //!< 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
224 U32 Fw::Time::parseSeconds(F64 seconds) {
225 // Assert negative value
226 FW_ASSERT(seconds >= static_cast<F64>(0.0));
227 return static_cast<U32>(seconds);
228 }
229
230 U32 Fw::Time::parseUSeconds(F64 seconds) {
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 5 void Time::add(U32 seconds, U32 useconds) {
241 5 U32 newSeconds = this->m_val.get_seconds() + seconds;
242 5 U32 newUSeconds = this->m_val.get_useconds() + useconds;
243 5 FW_ASSERT(newUSeconds < 1999999, static_cast<FwAssertArgType>(newUSeconds));
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (newUSeconds >= 1000000) {
245 newSeconds += 1;
246 newUSeconds -= 1000000;
247 }
248 5 this->set(newSeconds, newUSeconds);
249 5 }
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 5 void Time::setTimeBase(TimeBase timeBase) {
259 5 this->m_val.set_timeBase(timeBase);
260 5 }
261
262 5 void Time::setTimeContext(FwTimeContextStoreType context) {
263 5 this->m_val.set_timeContext(context);
264 5 }
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
274