F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
StringUtils.cpp
Go to the documentation of this file.
1 #include "StringUtils.hpp"
2 #include <Fw/Types/Assert.hpp>
4 #include <cstring>
5 #include <limits>
6 
7 char* Fw::StringUtils::string_copy(char* destination, const char* source, FwSizeType num) {
8  // Handle self-copy and 0 bytes copy
9  if (destination == source || num == 0) {
10  return destination;
11  }
12  FW_ASSERT(source != nullptr);
13  FW_ASSERT(destination != nullptr);
14 
15  // Copying an overlapping range is undefined
16  FwSizeType source_len = string_length(source, num) + 1;
17  FW_ASSERT(source + source_len <= destination || destination + num <= source);
18 
19  char* returned = strncpy(destination, source, static_cast<size_t>(num));
20  destination[num - 1] = '\0';
21  return returned;
22 }
23 
24 const char* Fw::StringUtils::string_last_n(const char* source, const FwSizeType n, const FwSizeType buffer_size) {
25  FW_ASSERT(source != nullptr);
26  FwSizeType length = Fw::StringUtils::string_length(source, buffer_size);
27 
28  // Calculate start index. If string is shorter than N, keep whole string.
29  return (length > n) ? source + (length - n) : source;
30 }
31 
33  FwSizeType length = 0;
34  FW_ASSERT(source != nullptr);
35  for (length = 0; length < buffer_size; length++) {
36  if (source[length] == '\0') {
37  break;
38  }
39  }
40  return length;
41 }
42 
44  FwSizeType source_size,
45  const CHAR* sub_string,
46  FwSizeType sub_size) {
47  FW_ASSERT(source_string != nullptr);
48  FW_ASSERT(sub_string != nullptr);
49 
50  // zero size sub-strings should always match
51  if ((source_size > 0) && (0 == sub_size)) {
52  return 0;
53  }
54 
55  // Cannot find a substring larger than the source
56  if (source_size < sub_size) {
57  return -1;
58  }
59  // Confirm that the output type can hold the range of valid results
60  FW_ASSERT(source_size - sub_size <= static_cast<FwSizeType>(std::numeric_limits<FwSignedSizeType>::max()));
61 
62  // Loop from zero to source_size - sub_size (inclusive)
63  for (FwSizeType source_index = 0;
64  source_index < (source_size - sub_size + 1) &&
65  source_index < static_cast<FwSizeType>(std::numeric_limits<FwSignedSizeType>::max());
66  source_index++) {
67  // if the current character matches
68  for (FwSizeType sub_index = 0; sub_index < sub_size; sub_index++) {
69  // Prevent read overrun
70  FW_ASSERT((source_index + sub_index) < source_size);
71  // if there is a mismatch, go to next character
72  if (source_string[source_index + sub_index] != sub_string[sub_index]) {
73  break;
74  } else if (sub_index == (sub_size - 1)) {
75  // if we matched all the way to the end of the substring
76  return static_cast<FwSignedSizeType>(source_index);
77  }
78  }
79  }
80 
81  // if we make it here, no matches were found
82  return -1;
83 }
84 
86  FwSizeType source_size,
87  const CHAR* sub_string,
88  FwSizeType sub_size) {
89  FW_ASSERT(source_string != nullptr);
90  FW_ASSERT(sub_string != nullptr);
91 
92  FwSizeType match_index = 0;
93 
94  // zero size sub-strings should always match
95  if ((source_size > 0) && (0 == sub_size)) {
96  match_index = source_size - 1;
97 
98  // Ensure we can represent the match_index in a signed num
99  FW_ASSERT(static_cast<FwSizeType>(static_cast<FwSignedSizeType>(match_index)) == match_index);
100 
101  return static_cast<FwSignedSizeType>(match_index);
102  }
103 
104  // Cannot find a substring larger than the source
105  if (source_size < sub_size) {
106  return -1;
107  }
108  // Confirm that the output type can hold the range of valid results
109  FW_ASSERT(source_size - sub_size <= static_cast<FwSizeType>(std::numeric_limits<FwSignedSizeType>::max()));
110 
111  // Loop from source_size - sub_size to zero (inclusive)
112  for (FwSizeType ii = 0; ii <= (source_size - sub_size); ii++) {
113  const FwSizeType source_index = (source_size - sub_size) - ii;
114 
115  // if the current character matches
116  for (FwSizeType sub_index = 0; sub_index < sub_size; sub_index++) {
117  // Prevent read overrun
118  FW_ASSERT((source_index + sub_index) < source_size);
119  // if there is a mismatch, go to next character
120  if (source_string[source_index + sub_index] != sub_string[sub_index]) {
121  break;
122  } else if (sub_index == (sub_size - 1)) {
123  // if we matched all the way to the end of the substring
124  match_index = source_index;
125 
126  // Ensure the result converts properly
127  FW_ASSERT(static_cast<FwSizeType>(static_cast<FwSignedSizeType>(match_index)) == match_index);
128 
129  return static_cast<FwSignedSizeType>(match_index);
130  }
131  }
132  }
133 
134  // if we make it here, no matches were found
135  return -1;
136 }
PlatformSizeType FwSizeType
FwSignedSizeType substring_find(const CHAR *source_string, FwSizeType source_size, const CHAR *sub_string, FwSizeType sub_size)
find the first occurrence of a substring
Definition: StringUtils.cpp:43
PlatformSignedSizeType FwSignedSizeType
char CHAR
Definition: BasicTypes.h:59
const char * string_last_n(const char *source, const FwSizeType n, const FwSizeType buffer_size)
get a pointer to the last N characters of a string
Definition: StringUtils.cpp:24
char * string_copy(char *destination, const char *source, FwSizeType num)
copy string with null-termination guaranteed
Definition: StringUtils.cpp:7
FwSignedSizeType substring_find_last(const CHAR *source_string, FwSizeType source_size, const CHAR *sub_string, FwSizeType sub_size)
find the last occurrence of a substring
Definition: StringUtils.cpp:85
#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