FastLED 3.9.7
Loading...
Searching...
No Matches
str.cpp
1#include <stdlib.h>
2
3#include "fl/str.h"
4#include "fl/namespace.h"
5
6
7namespace fl {
8
9namespace string_functions {
10
11static int itoa(int value, char *sp, int radix) {
12 char tmp[16]; // be careful with the length of the buffer
13 char *tp = tmp;
14 int i;
15 unsigned v;
16
17 int sign = (radix == 10 && value < 0);
18 if (sign)
19 v = -value;
20 else
21 v = (unsigned)value;
22
23 while (v || tp == tmp) {
24 i = v % radix;
25 v = radix ? v / radix : 0;
26 if (i < 10)
27 *tp++ = i + '0';
28 else
29 *tp++ = i + 'a' - 10;
30 }
31
32 int len = tp - tmp;
33
34 if (sign) {
35 *sp++ = '-';
36 len++;
37 }
38
39 while (tp > tmp)
40 *sp++ = *--tp;
41
42 return len;
43}
44
45static float atoff(const char *str, size_t len) {
46 float result = 0.0f; // The resulting number
47 float sign = 1.0f; // Positive or negative
48 float fraction = 0.0f; // Fractional part
49 float divisor = 1.0f; // Divisor for the fractional part
50 int isFractional = 0; // Whether the current part is fractional
51
52 size_t pos = 0; // Current position in the string
53
54 // Handle empty input
55 if (len == 0) {
56 return 0.0f;
57 }
58
59 // Skip leading whitespace (manual check instead of isspace)
60 while (pos < len && (str[pos] == ' ' || str[pos] == '\t' || str[pos] == '\n' || str[pos] == '\r' || str[pos] == '\f' || str[pos] == '\v')) {
61 pos++;
62 }
63
64 // Handle optional sign
65 if (pos < len && str[pos] == '-') {
66 sign = -1.0f;
67 pos++;
68 } else if (pos < len && str[pos] == '+') {
69 pos++;
70 }
71
72 // Main parsing loop
73 while (pos < len) {
74 if (str[pos] >= '0' && str[pos] <= '9') {
75 if (isFractional) {
76 divisor *= 10.0f;
77 fraction += (str[pos] - '0') / divisor;
78 } else {
79 result = result * 10.0f + (str[pos] - '0');
80 }
81 } else if (str[pos] == '.' && !isFractional) {
82 isFractional = 1;
83 } else {
84 // Stop parsing at invalid characters
85 break;
86 }
87 pos++;
88 }
89
90 // Combine integer and fractional parts
91 result = result + fraction;
92
93 // Apply the sign
94 return sign * result;
95}
96
97} // namespace string_functions
98
99void StringFormatter::append(int val, StrN<64> *dst) {
100 char buf[63] = {0};
101 string_functions::itoa(val, buf, 10);
102 dst->write(buf, strlen(buf));
103}
104
105StringHolder::StringHolder(const char *str) {
106 mLength = strlen(str);
107 mData = (char *)malloc(mLength + 1);
108 if (mData) {
109 memcpy(mData, str, mLength + 1);
110 } else {
111 mLength = 0;
112 }
113 mCapacity = mLength;
114}
115
116StringHolder::StringHolder(size_t length) {
117 mData = (char *)malloc(length + 1);
118 if (mData) {
119 mLength = length;
120 mData[mLength] = '\0';
121 } else {
122 mLength = 0;
123 }
124 mCapacity = mLength;
125}
126
127
128StringHolder::StringHolder(const char *str, size_t length) {
129 mData = (char *)malloc(length + 1);
130 if (mData) {
131 mLength = length;
132 memcpy(mData, str, mLength);
133 mData[mLength] = '\0';
134 } else {
135 mLength = 0;
136 }
137 mCapacity = mLength;
138}
139
140StringHolder::~StringHolder() {
141 free(mData); // Release the memory
142}
143
144void StringHolder::grow(size_t newLength) {
145 if (newLength <= mCapacity) {
146 // New length must be greater than current length
147 mLength = newLength;
148 return;
149 }
150 char *newData = (char *)realloc(mData, newLength + 1);
151 if (newData) {
152 mData = newData;
153 mLength = newLength;
154 mCapacity = newLength;
155 mData[mLength] = '\0'; // Ensure null-termination
156 } else {
157 // handle re-allocation failure.
158 char *newData = (char *)malloc(newLength + 1);
159 if (newData) {
160 memcpy(newData, mData, mLength + 1);
161 free(mData);
162 mData = newData;
163 mLength = newLength;
164 mCapacity = mLength;
165 } else {
166 // memory failure.
167 }
168 }
169}
170
171float StringFormatter::parseFloat(const char *str, size_t len) {
172 return string_functions::atoff(str, len);
173}
174
175
176}
Implements the FastLED namespace macros.
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16