F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
StringToNumber.cpp
Go to the documentation of this file.
2 #include <cstdlib>
3 #include <cerrno>
4 
7  // Check for null input string
8  if (input == nullptr) {
10  }
11  // Invalid base e.g. not 0, 2-36
12  else if (base == 1 || base > 36) {
14  } else {
15  // Check the string is bounded within the specified length
16  FwSizeType length = Fw::StringUtils::string_length(input, buffer_size);
17  if (length == buffer_size) {
19  }
20  }
21  errno = 0;
22  return status;
23 }
24 
25 Fw::StringUtils::StringToNumberStatus string_to_helper_output_check(Fw::StringUtils::StringToNumberStatus status, const char* original_input, char*& internal_next, char** external_next) {
26  // Check range, if error then
27  if (errno == ERANGE) {
29  }
30  // Invalid number conversion
31  else if ((internal_next == original_input) || (internal_next == nullptr)) {
32  internal_next = nullptr;
34  }
35  // Set output pointer in all cases
36  if (external_next != nullptr) {
37  *external_next = internal_next;
38  }
39  errno = 0;
40  return status;
41 }
42 
43 // Template for internal implementation only
44 // \tparam T: input type (U8, I8, U64, I64)
45 // \tparam Tinternal: function api type
46 // \tparam F: conversion function to use
47 template <typename T, typename Tinternal, Tinternal (*F)(const char*, char**, int)>
48 Fw::StringUtils::StringToNumberStatus string_to_number_as_template(const CHAR* input, FwSizeType buffer_size, T& output, char** next, U8 base) {
49  static_assert(std::numeric_limits<T>::is_integer, "Type must be integer");
50  static_assert(std::numeric_limits<Tinternal>::is_integer, "Type must be integer");
51  static_assert(std::numeric_limits<T>::is_signed == std::numeric_limits<Tinternal>::is_signed, "Signedness must match");
52  static_assert(std::numeric_limits<T>::max() <= std::numeric_limits<Tinternal>::max(), "Invalid internal type chosen");
53  static_assert(std::numeric_limits<T>::min() >= std::numeric_limits<Tinternal>::min(), "Invalid internal type chosen");
54 
55  char* output_next = nullptr;
58  Tinternal output_api = F(input, &output_next, base);
59  if (output_api > std::numeric_limits<T>::max()) {
61  output_api = std::numeric_limits<T>::max();
62  }
63  if (output_api < std::numeric_limits<T>::min()) {
65  output_api = std::numeric_limits<T>::min();
66  }
67  output = static_cast<T>(output_api);
68  }
69  status = string_to_helper_output_check(status, input, output_next, next);
70  return status;
71 }
72 
73 #if FW_HAS_64_BIT
74 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, U64& output, char** next, U8 base) {
75  return string_to_number_as_template<U64, unsigned long long, strtoull>(input, buffer_size, output, next, base);
76 }
77 
78 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, I64& output, char** next, U8 base) {
79  return string_to_number_as_template<I64, long long, strtoll>(input, buffer_size, output, next, base);
80 }
81 #endif
82 #if FW_HAS_32_BIT
83 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, U32& output, char** next, U8 base) {
84  return string_to_number_as_template<U32, unsigned long long, strtoull>(input, buffer_size, output, next, base);
85 }
86 
87 
88 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, I32& output, char** next, U8 base) {
89  return string_to_number_as_template<I32, long long, strtoll>(input, buffer_size, output, next, base);
90 }
91 #endif
92 #if FW_HAS_16_BIT
93 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, U16& output, char** next, U8 base) {
94  return string_to_number_as_template<U16, unsigned long long, strtoull>(input, buffer_size, output, next, base);
95 }
96 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, I16& output, char** next, U8 base) {
97  return string_to_number_as_template<I16, long long, strtoll>(input, buffer_size, output, next, base);
98 }
99 #endif
100 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, U8& output, char** next, U8 base) {
101  return string_to_number_as_template<U8, unsigned long long, strtoull>(input, buffer_size, output, next, base);
102 }
103 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, I8& output, char** next, U8 base) {
104  return string_to_number_as_template<I8, long long, strtoll>(input, buffer_size, output, next, base);
105 }
106 #if FW_HAS_F64
107 Fw::StringUtils::StringToNumberStatus Fw::StringUtils::string_to_number(const CHAR* input, FwSizeType buffer_size, F64& output, char** next) {
108  char* output_next = nullptr;
110  if (status == SUCCESSFUL_CONVERSION) {
111  output = strtod(input, &output_next);
112  }
113  status = string_to_helper_output_check(status, input, output_next, next);
114  return status;
115 }
116 #endif
117 
119  char* output_next = nullptr;
121  if (status == SUCCESSFUL_CONVERSION) {
122  output = strtof(input, &output_next);
123  }
124  status = string_to_helper_output_check(status, input, output_next, next);
125  return status;
126 }
int8_t I8
8-bit signed integer
Definition: BasicTypes.h:29
float F32
32-bit floating point
Definition: BasicTypes.h:49
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:30
char CHAR
Definition: BasicTypes.h:32
static U32 min(const U32 a, const U32 b)
Definition: Checksum.cpp:16
PlatformSizeType FwSizeType
Definition: FpConfig.h:35
Fw::StringUtils::StringToNumberStatus string_to_helper_output_check(Fw::StringUtils::StringToNumberStatus status, const char *original_input, char *&internal_next, char **external_next)
Fw::StringUtils::StringToNumberStatus string_to_helper_input_check(const CHAR *input, FwSizeType buffer_size, U8 base)
Fw::StringUtils::StringToNumberStatus string_to_number_as_template(const CHAR *input, FwSizeType buffer_size, T &output, char **next, U8 base)
FwSizeType string_length(const CHAR *source, FwSizeType buffer_size)
get the length of the source string
Definition: StringUtils.cpp:23
@ INVALID_BASE
Base was not supplied as 0, or 2-36.
Definition: StringUtils.hpp:51
@ SUCCESSFUL_CONVERSION
Output should be valid.
Definition: StringUtils.hpp:48
@ NULL_INPUT
A null string was supplied.
Definition: StringUtils.hpp:49
@ INVALID_NUMBER
String did not contain a valid number matching supplied base.
Definition: StringUtils.hpp:52
@ INVALID_STRING
No \0 detected within the supplied length.
Definition: StringUtils.hpp:50
StringToNumberStatus string_to_number(const CHAR *input, FwSizeType buffer_size, U8 &output, char **next, U8 base=0)
converts a string to a U8
#define U64(C)
Definition: sha.h:176