GCC Code Coverage Report


Directory: ./
File: Fw/Types/StringBase.cpp
Date: 2026-09-23 21:11:01
Exec Total Coverage
Lines: 50 53 94.3%
Functions: 12 13 92.3%
Branches: 10 14 71.4%

Line Branch Exec Source
1 /**
2 * \file StringBase.cpp
3 * \author T. Canham
4 * \brief Implements F Prime string base class
5 *
6 * \copyright
7 * Copyright 2009-2016, by the California Institute of Technology.
8 * ALL RIGHTS RESERVED. United States Government Sponsorship
9 * acknowledged.
10 *
11 */
12
13 #include <Fw/Types/Assert.hpp>
14 #include <Fw/Types/StringFormatStatusEnumAc.hpp>
15 #include <Fw/Types/StringType.hpp>
16 #include <Fw/Types/StringUtils.hpp>
17 #include <cstdarg>
18 #include <cstring>
19
20 // Check consistency of every constant in the Fw::FormatStatus enum with the FPP shadow enum
21 static_assert(static_cast<FwIndexType>(Fw::StringFormatStatus::NUM_CONSTANTS) == 5,
22 "Format status and FPP shadow enum have inconsistent number of values");
23 static_assert(static_cast<Fw::StringFormatStatus::T>(Fw::FormatStatus::SUCCESS) == Fw::StringFormatStatus::T::SUCCESS,
24 "Format status and FPP shadow enum do not match");
25 static_assert(static_cast<Fw::StringFormatStatus::T>(Fw::FormatStatus::OVERFLOWED) ==
26 Fw::StringFormatStatus::T::OVERFLOWED,
27 "Format status and FPP shadow enum do not match");
28 static_assert(static_cast<Fw::StringFormatStatus::T>(Fw::FormatStatus::INVALID_FORMAT_STRING) ==
29 Fw::StringFormatStatus::T::INVALID_FORMAT_STRING,
30 "Format status and FPP shadow enum do not match");
31 static_assert(static_cast<Fw::StringFormatStatus::T>(Fw::FormatStatus::SIZE_OVERFLOW) ==
32 Fw::StringFormatStatus::T::SIZE_OVERFLOW,
33 "Format status and FPP shadow enum do not match");
34 static_assert(static_cast<Fw::StringFormatStatus::T>(Fw::FormatStatus::OTHER_ERROR) ==
35 Fw::StringFormatStatus::T::OTHER_ERROR,
36 "Format status and FPP shadow enum do not match");
37
38 namespace Fw {
39
40 20757184 StringBase::StringBase() {}
41
42 41514368 StringBase::~StringBase() {}
43
44 272 const CHAR* StringBase::operator+=(const CHAR* src) {
45 272 this->appendBuff(src, static_cast<SizeType>(StringUtils::string_length(src, this->getCapacity())));
46 272 return this->toChar();
47 }
48
49 4 const StringBase& StringBase::operator+=(const ConstStringBase& src) {
50 4 this->appendBuff(src.toChar(), src.length());
51 4 return *this;
52 }
53
54 4 const StringBase& StringBase::operator+=(const StringBase& src) {
55 4 return StringBase::operator+=(static_cast<const ConstStringBase&>(src));
56 }
57
58 177652 FormatStatus StringBase::format(const CHAR* formatString, ...) {
59 177652 va_list args;
60 177652 va_start(args, formatString);
61
1/1
✓ Branch 4 taken 177652 times.
177652 FormatStatus status = this->vformat(formatString, args);
62 177652 va_end(args);
63 177652 return status;
64 }
65
66 183661 FormatStatus StringBase::vformat(const CHAR* formatString, va_list args) {
67 183661 CHAR* us = const_cast<CHAR*>(this->toChar());
68 183661 SizeType cap = this->getCapacity();
69 183661 FW_ASSERT(us != nullptr);
70 // Needed until SizeType an FwSizeType are the same
71 static_assert(std::numeric_limits<FwSizeType>::max() >= std::numeric_limits<SizeType>::max(),
72 "String size type must fit into FwSizeType");
73 183661 return Fw::stringFormat(us, static_cast<FwSizeType>(cap), formatString, args);
74 }
75
76 #if FW_SERIALIZABLE_TO_STRING || BUILD_UT
77 ✗ void StringBase::toString(StringBase& text) const {
78 ✗ text = *this;
79 ✗ }
80 #endif
81
82 320231 StringBase& StringBase::operator=(const ConstStringBase& other) {
83
1/2
✓ Branch 1 taken 320231 times.
✗ Branch 2 not taken.
320231 if (this != &other) {
84 320231 (void)Fw::StringUtils::string_copy(const_cast<char*>(this->toChar()), other.toChar(), this->getCapacity());
85 }
86 320231 return *this;
87 }
88
89 153830 StringBase& StringBase::operator=(const StringBase& other) {
90 153830 return StringBase::operator=(static_cast<const ConstStringBase&>(other));
91 }
92
93 // Copy constructor doesn't make sense in this virtual class as there is nothing to copy. Derived classes should
94 // call the empty constructor and then call their own copy function
95 20728396 StringBase& StringBase::operator=(const CHAR* other) { // lgtm[cpp/rule-of-two]
96 20728396 (void)Fw::StringUtils::string_copy(const_cast<char*>(this->toChar()), other, this->getCapacity());
97 20728396 return *this;
98 }
99
100 276 void StringBase::appendBuff(const CHAR* buff, SizeType size) {
101 276 const SizeType capacity = this->getCapacity();
102 276 const SizeType length = this->length();
103 276 FW_ASSERT(capacity > length, static_cast<FwAssertArgType>(capacity), static_cast<FwAssertArgType>(length));
104 // Subtract 1 to leave space for null terminator
105 276 SizeType remaining = capacity - length - 1;
106
1/2
✓ Branch 0 taken 276 times.
✗ Branch 1 not taken.
276 if (size < remaining) {
107 276 remaining = size;
108 }
109 276 FW_ASSERT(remaining < capacity, static_cast<FwAssertArgType>(remaining), static_cast<FwAssertArgType>(capacity));
110
2/4
✗ Branch 10 not taken.
✓ Branch 11 taken 276 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 276 times.
276 (void)strncat(const_cast<CHAR*>(this->toChar()), buff, static_cast<size_t>(remaining));
111 276 }
112
113 42656 SerializeStatus StringBase::deserializeFrom(SerialBufferBase& buffer, Fw::Endianness mode) {
114 // Get the max size of the deserialized string
115
1/1
✓ Branch 5 taken 42656 times.
42656 const SizeType maxSize = this->maxLength();
116 // Initial estimate of actual size is max size
117 // This estimate is refined when calling the deserialize function below
118 42656 SizeType actualSize = maxSize;
119 // Public interface returns const char*, but implementation needs char*
120 // So use const_cast
121
1/1
✓ Branch 10 taken 42656 times.
42656 CHAR* raw = const_cast<CHAR*>(this->toChar());
122 // Deserialize length
123 // Fail if length exceeds max size (the initial value of actualSize)
124 // Otherwise deserialize length bytes and set actualSize to length
125
1/1
✓ Branch 7 taken 42656 times.
42656 SerializeStatus stat = buffer.deserializeTo(reinterpret_cast<U8*>(raw), actualSize, Serialization::INCLUDE_LENGTH);
126
2/2
✓ Branch 0 taken 42655 times.
✓ Branch 1 taken 1 times.
42656 if (stat == FW_SERIALIZE_OK) {
127 // Deserialization succeeded: null-terminate string at actual size
128 42655 FW_ASSERT(actualSize <= maxSize, static_cast<FwAssertArgType>(actualSize),
129 static_cast<FwAssertArgType>(maxSize));
130 42655 raw[actualSize] = 0;
131 } else {
132 // Deserialization failed: leave string unmodified, but ensure that it
133 // is null-terminated
134 1 raw[maxSize] = 0;
135 }
136 42656 return stat;
137 }
138
139 } // namespace Fw
140