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 
25  FwSizeType length = 0;
26  FW_ASSERT(source != nullptr);
27  for (length = 0; length < buffer_size; length++) {
28  if (source[length] == '\0') {
29  break;
30  }
31  }
32  return length;
33 }
34 
36  FwSizeType source_size,
37  const CHAR* sub_string,
38  FwSizeType sub_size) {
39  FW_ASSERT(source_string != nullptr);
40  FW_ASSERT(sub_string != nullptr);
41 
42  // zero size sub-strings should always match
43  if ((source_size > 0) && (0 == sub_size)) {
44  return 0;
45  }
46 
47  // Cannot find a substring larger than the source
48  if (source_size < sub_size) {
49  return -1;
50  }
51  // Confirm that the output type can hold the range of valid results
52  FW_ASSERT(source_size - sub_size <= static_cast<FwSizeType>(std::numeric_limits<FwSignedSizeType>::max()));
53 
54  // Loop from zero to source_size - sub_size (inclusive)
55  for (FwSizeType source_index = 0;
56  source_index < (source_size - sub_size + 1) &&
57  source_index < static_cast<FwSizeType>(std::numeric_limits<FwSignedSizeType>::max());
58  source_index++) {
59  // if the current character matches
60  for (FwSizeType sub_index = 0; sub_index < sub_size; sub_index++) {
61  // Prevent read overrun
62  FW_ASSERT((source_index + sub_index) < source_size);
63  // if there is a mismatch, go to next character
64  if (source_string[source_index + sub_index] != sub_string[sub_index]) {
65  break;
66  } else if (sub_index == (sub_size - 1)) {
67  // if we matched all the way to the end of the substring
68  return static_cast<FwSignedSizeType>(source_index);
69  }
70  }
71  }
72 
73  // if we make it here, no matches were found
74  return -1;
75 }
76 
78  FwSizeType source_size,
79  const CHAR* sub_string,
80  FwSizeType sub_size) {
81  FW_ASSERT(source_string != nullptr);
82  FW_ASSERT(sub_string != nullptr);
83 
84  FwSizeType match_index = 0;
85 
86  // zero size sub-strings should always match
87  if ((source_size > 0) && (0 == sub_size)) {
88  match_index = source_size - 1;
89 
90  // Ensure we can represent the match_index in a signed num
91  FW_ASSERT(static_cast<FwSizeType>(static_cast<FwSignedSizeType>(match_index)) == match_index);
92 
93  return static_cast<FwSignedSizeType>(match_index);
94  }
95 
96  // Cannot find a substring larger than the source
97  if (source_size < sub_size) {
98  return -1;
99  }
100  // Confirm that the output type can hold the range of valid results
101  FW_ASSERT(source_size - sub_size <= static_cast<FwSizeType>(std::numeric_limits<FwSignedSizeType>::max()));
102 
103  // Loop from source_size - sub_size to zero (inclusive)
104  for (FwSizeType ii = 0; ii <= (source_size - sub_size); ii++) {
105  const FwSizeType source_index = (source_size - sub_size) - ii;
106 
107  // if the current character matches
108  for (FwSizeType sub_index = 0; sub_index < sub_size; sub_index++) {
109  // Prevent read overrun
110  FW_ASSERT((source_index + sub_index) < source_size);
111  // if there is a mismatch, go to next character
112  if (source_string[source_index + sub_index] != sub_string[sub_index]) {
113  break;
114  } else if (sub_index == (sub_size - 1)) {
115  // if we matched all the way to the end of the substring
116  match_index = source_index;
117 
118  // Ensure the result converts properly
119  FW_ASSERT(static_cast<FwSizeType>(static_cast<FwSignedSizeType>(match_index)) == match_index);
120 
121  return static_cast<FwSignedSizeType>(match_index);
122  }
123  }
124  }
125 
126  // if we make it here, no matches were found
127  return -1;
128 }
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:35
PlatformSignedSizeType FwSignedSizeType
char CHAR
Definition: BasicTypes.h:59
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:77
#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:24