GCC Code Coverage Report


Directory: ./
File: Fw/Time/Time.cpp
Date: 2026-09-23 22:11:34
Exec Total Coverage
Lines: 69 162 42.6%
Functions: 17 37 45.9%
Branches: 29 73 39.7%

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 7752 times.
7762 Time::Time() : m_val() {
8
1/1
✓ Branch 1 taken 7755 times.
7752 m_val.set_timeBase(TimeBase::TB_NONE);
9
1/1
✓ Branch 1 taken 7753 times.
7755 m_val.set_timeContext(0);
10
1/1
✓ Branch 1 taken 7753 times.
7753 m_val.set_seconds(0);
11
1/1
✓ Branch 1 taken 7753 times.
7753 m_val.set_useconds(0);
12 7753 }
13
14 24984 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 4118 void Time::set(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds) {
37 // Assert microseconds portion is less than 10^6
38 4118 FW_ASSERT(useconds < 1000000, static_cast<FwAssertArgType>(useconds));
39 4118 this->m_val.set(timeBase, context, seconds, useconds);
40 4117 }
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 3619 Time& Time::operator=(const Time& other) {
58
1/2
✓ Branch 0 taken 3619 times.
✗ Branch 1 not taken.
3619 if (this != &other) {
59 3619 this->m_val = other.m_val;
60 }
61 3619 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 3150 bool Time::operator==(const Time& other) const {
75
1/1
✓ Branch 1 taken 3148 times.
3150 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 3985 SerializeStatus Time::serializeTo(SerialBufferBase& buffer, Fw::Endianness mode) const {
111 3985 return this->m_val.serializeTo(buffer, mode);
112 }
113
114 466 SerializeStatus Time::deserializeFrom(SerialBufferBase& buffer, Fw::Endianness mode) {
115
1/1
✓ Branch 1 taken 466 times.
466 TimeValue value;
116
1/1
✓ Branch 1 taken 466 times.
466 const SerializeStatus status = value.deserializeFrom(buffer, mode);
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 466 times.
466 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 466 times.
466 if (value.get_useconds() >= 1000000) {
122 ✗ return FW_DESERIALIZE_FORMAT_ERROR;
123 }
124
1/1
✓ Branch 1 taken 466 times.
466 this->m_val = value;
125 466 return FW_SERIALIZE_OK;
126 466 }
127
128 6769 U32 Time::getSeconds() const {
129 6769 return this->m_val.get_seconds();
130 }
131
132 6768 U32 Time::getUSeconds() const {
133 6768 return this->m_val.get_useconds();
134 }
135
136 6783 TimeBase Time::getTimeBase() const {
137 6783 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 3156 TimeComparison Time ::compare(const Time& time1, const Time& time2) {
150
4/4
✓ Branch 1 taken 3156 times.
✓ Branch 5 taken 3156 times.
✓ Branch 10 taken 9 times.
✓ Branch 11 taken 3147 times.
3156 if (time1.getTimeBase() != time2.getTimeBase()) {
151 9 return TimeComparison::INCOMPARABLE;
152 }
153
154 // Do not compare time context
155
156 3147 const U32 s1 = time1.getSeconds();
157 3147 const U32 s2 = time2.getSeconds();
158 3146 const U32 us1 = time1.getUSeconds();
159 3145 const U32 us2 = time2.getUSeconds();
160
161
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3145 times.
3146 if (s1 < s2) {
162 1 return TimeComparison::LT;
163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3145 times.
3145 } else if (s1 > s2) {
164 ✗ return TimeComparison::GT;
165
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3144 times.
3145 } else if (us1 < us2) {
166 1 return TimeComparison::LT;
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3144 times.
3144 } else if (us1 > us2) {
168 ✗ return TimeComparison::GT;
169 } else {
170 3144 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