F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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
25Fw::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
47template <typename T, typename Tinternal, Tinternal (*F)(const char*, char**, int)>
48Fw::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
74Fw::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
78Fw::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
83Fw::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
88Fw::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
93Fw::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}
96Fw::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
100Fw::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}
103Fw::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
107Fw::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
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
@ INVALID_BASE
Base was not supplied as 0, or 2-36.
@ SUCCESSFUL_CONVERSION
Output should be valid.
@ NULL_INPUT
A null string was supplied.
@ INVALID_NUMBER
String did not contain a valid number matching supplied base.
@ INVALID_STRING
No \0 detected within the supplied length.
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