F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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