F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
StringBase.cpp
Go to the documentation of this file.
1 
13 #include <Fw/Types/Assert.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) ==
36  "Format status and FPP shadow enum do not match");
37 
38 namespace Fw {
39 
41 
43 
44 const CHAR* StringBase::operator+=(const CHAR* src) {
45  this->appendBuff(src, static_cast<SizeType>(StringUtils::string_length(src, this->getCapacity())));
46  return this->toChar();
47 }
48 
50  this->appendBuff(src.toChar(), src.length());
51  return *this;
52 }
53 
55  return StringBase::operator+=(static_cast<const ConstStringBase&>(src));
56 }
57 
58 FormatStatus StringBase::format(const CHAR* formatString, ...) {
59  va_list args;
60  va_start(args, formatString);
61  FormatStatus status = this->vformat(formatString, args);
62  va_end(args);
63  return status;
64 }
65 
66 FormatStatus StringBase::vformat(const CHAR* formatString, va_list args) {
67  CHAR* us = const_cast<CHAR*>(this->toChar());
68  SizeType cap = this->getCapacity();
69  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  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 
83  if (this != &other) {
84  (void)Fw::StringUtils::string_copy(const_cast<char*>(this->toChar()), other.toChar(), this->getCapacity());
85  }
86  return *this;
87 }
88 
90  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 StringBase& StringBase::operator=(const CHAR* other) { // lgtm[cpp/rule-of-two]
96  (void)Fw::StringUtils::string_copy(const_cast<char*>(this->toChar()), other, this->getCapacity());
97  return *this;
98 }
99 
100 void StringBase::appendBuff(const CHAR* buff, SizeType size) {
101  const SizeType capacity = this->getCapacity();
102  const SizeType length = this->length();
103  FW_ASSERT(capacity > length, static_cast<FwAssertArgType>(capacity), static_cast<FwAssertArgType>(length));
104  // Subtract 1 to leave space for null terminator
105  SizeType remaining = capacity - length - 1;
106  if (size < remaining) {
107  remaining = size;
108  }
109  FW_ASSERT(remaining < capacity, static_cast<FwAssertArgType>(remaining), static_cast<FwAssertArgType>(capacity));
110  (void)strncat(const_cast<CHAR*>(this->toChar()), buff, static_cast<size_t>(remaining));
111 }
112 
114  // Get the max size of the deserialized string
115  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  SizeType actualSize = maxSize;
119  // Public interface returns const char*, but implementation needs char*
120  // So use const_cast
121  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  SerializeStatus stat = buffer.deserializeTo(reinterpret_cast<U8*>(raw), actualSize, Serialization::INCLUDE_LENGTH);
126  if (stat == FW_SERIALIZE_OK) {
127  // Deserialization succeeded: null-terminate string at actual size
128  FW_ASSERT(actualSize <= maxSize, static_cast<FwAssertArgType>(actualSize),
129  static_cast<FwAssertArgType>(maxSize));
130  raw[actualSize] = 0;
131  } else {
132  // Deserialization failed: leave string unmodified, but ensure that it
133  // is null-terminated
134  raw[maxSize] = 0;
135  }
136  return stat;
137 }
138 
139 } // namespace Fw
Serialization/Deserialization operation was successful.
SerializeStatus deserializeFrom(SerialBufferBase &buffer, Endianness mode=Endianness::BIG) override
Deserialize the contents of this object from a buffer.
Definition: StringBase.cpp:113
A catch-all for other errors. Have to look in implementation-specific code.
const CHAR * operator+=(const CHAR *src)
Concatenate a CHAR*.
Definition: StringBase.cpp:44
virtual const CHAR * toChar() const =0
Convert to a C-style char*.
Format overflowed.
FwSizeType overflowed the range of size_t.
FormatStatus vformat(const CHAR *formatString, va_list args)
write formatted string to buffer using va_list
Definition: StringBase.cpp:66
char CHAR
Definition: BasicTypes.h:60
SerializeStatus
forward declaration for string
virtual SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG)=0
Deserialize an 8-bit unsigned integer value.
virtual ~StringBase()
Definition: StringBase.cpp:42
char * string_copy(char *destination, const char *source, FwSizeType num)
copy string with null-termination guaranteed
Definition: StringUtils.cpp:7
virtual SizeType getCapacity() const =0
Return the size of the buffer.
Format provided invalid format string.
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:58
The number of enumerated constants.
SizeType maxLength() const
Get the maximum length of a string that the buffer can hold (which is capacity - 1) ...
A read-only abstract superclass for StringBase.
void appendBuff(const CHAR *buff, SizeType size)
Definition: StringBase.cpp:100
StringBase & operator=(const CHAR *src)
Assign CHAR*.
Definition: StringBase.cpp:95
An error was returned from an underlying call.
FormatStatus stringFormat(char *destination, const FwSizeType maximumSize, const char *formatString,...)
format a c-string
Include length as first token in serialization.
virtual SizeType length() const
Get the length of the string.
Implementation of malloc based allocator.
Endianness
#define FW_ASSERT(...)
Definition: Assert.hpp:14
FwSizeType string_length(const CHAR *source, FwSizeType buffer_size)
get the length of the source string
Definition: StringUtils.cpp:32
FormatStatus
status of string format calls
Definition: format.hpp:18