FastLED 3.10.8
Loading...
Searching...
No Matches
cstring.cpp.hpp
Go to the documentation of this file.
1
2// FastLED C String Functions (cstring.cpp)
3//
4// Implementations of fl:: string and memory functions wrapping C library calls.
5// This separation from the header reduces compilation overhead while maintaining
6// a clean API in the fl:: namespace.
8
9#include "fl/stl/cstring.h"
10#include "fl/stl/bit_cast.h"
11#include "platforms/is_platform.h"
12// Include C string headers for standard C library functions
13// IWYU pragma: begin_keep
14#include <string.h> // okay banned header (STL wrapper implementation requires standard header)
15#include <stdlib.h> // okay banned header (STL wrapper implementation requires standard header)
16
17// IWYU pragma: end_keep
18// Include Arduino PROGMEM headers if on AVR
19#if defined(ARDUINO) && defined(FL_IS_AVR)
20// IWYU pragma: begin_keep
21#include <avr/pgmspace.h>
22#include "fl/stl/noexcept.h"
23// IWYU pragma: end_keep
24#endif
25
26// C library string functions are available through the global namespace
27
28namespace fl {
29
30// ============================================================================
31// Standard String Functions
32// ============================================================================
33
34size_t libc_impl::strlen(const char* s) FL_NO_EXCEPT {
35 return ::strlen(s);
36}
37
38int libc_impl::strcmp(const char* s1, const char* s2) FL_NO_EXCEPT {
39 return ::strcmp(s1, s2);
40}
41
42int libc_impl::strncmp(const char* s1, const char* s2, size_t n) FL_NO_EXCEPT {
43 return ::strncmp(s1, s2, n);
44}
45
46char* libc_impl::strcpy(char* dest, const char* src) FL_NO_EXCEPT {
47 return ::strcpy(dest, src);
48}
49
50char* libc_impl::strncpy(char* dest, const char* src, size_t n) FL_NO_EXCEPT {
51 // Unlike ::strncpy, this ALWAYS null-terminates: it copies at most n
52 // characters from src, then writes a terminator at dest[copied]
53 // (copied <= n). Callers pass n = capacity - 1 (dest sized >= n+1),
54 // so the terminator is always in bounds. This closes the classic
55 // strncpy hazard where a source of length >= n leaves dest
56 // unterminated and downstream string walks run off the buffer
57 // (FastLED#3588: an unterminated HTTP request URI let a query-strip
58 // loop write a stray null byte one past a heap allocation).
59 size_t i = 0;
60 for (; i < n && src[i] != '\0'; ++i) {
61 dest[i] = src[i];
62 }
63 dest[i] = '\0';
64 // Preserve ::strncpy's zero-padding of the remaining destination
65 // bytes so callers relying on that behavior are unaffected.
66 for (size_t j = i + 1; j < n; ++j) {
67 dest[j] = '\0';
68 }
69 return dest;
70}
71
72char* libc_impl::strcat(char* dest, const char* src) FL_NO_EXCEPT {
73 return ::strcat(dest, src);
74}
75
76char* libc_impl::strncat(char* dest, const char* src, size_t n) FL_NO_EXCEPT {
77 return ::strncat(dest, src, n);
78}
79
80const char* libc_impl::strstr(const char* haystack, const char* needle) FL_NO_EXCEPT {
81 return ::strstr(haystack, needle);
82}
83
84char* libc_impl::strchr(char* s, int c) FL_NO_EXCEPT {
85 return ::strchr(s, c);
86}
87
88const char* libc_impl::strchr(const char* s, int c) FL_NO_EXCEPT {
89 return ::strchr(s, c);
90}
91
92char* libc_impl::strrchr(char* s, int c) FL_NO_EXCEPT {
93 return ::strrchr(s, c);
94}
95
96const char* libc_impl::strrchr(const char* s, int c) FL_NO_EXCEPT {
97 return ::strrchr(s, c);
98}
99
100size_t libc_impl::strspn(const char* s1, const char* s2) FL_NO_EXCEPT {
101 return ::strspn(s1, s2);
102}
103
104size_t libc_impl::strcspn(const char* s1, const char* s2) FL_NO_EXCEPT {
105 return ::strcspn(s1, s2);
106}
107
108char* libc_impl::strpbrk(char* s1, const char* s2) FL_NO_EXCEPT {
109 return ::strpbrk(s1, s2);
110}
111
112const char* libc_impl::strpbrk(const char* s1, const char* s2) FL_NO_EXCEPT {
113 return ::strpbrk(s1, s2);
114}
115
116char* libc_impl::strtok(char* s1, const char* s2) FL_NO_EXCEPT {
117 return ::strtok(s1, s2);
118}
119
121 return ::strerror(errnum);
122}
123
124// ============================================================================
125// Memory Functions
126// ============================================================================
127
128void* libc_impl::memcpy(void* dest, const void* src, size_t n) FL_NO_EXCEPT {
129 if (n == 0) return dest;
130 return ::memcpy(dest, src, n);
131}
132
133int libc_impl::memcmp(const void* s1, const void* s2, size_t n) FL_NO_EXCEPT {
134 if (n == 0) return 0;
135 return ::memcmp(s1, s2, n);
136}
137
138void* libc_impl::memmove(void* dest, const void* src, size_t n) FL_NO_EXCEPT {
139 if (n == 0) return dest;
140 return ::memmove(dest, src, n);
141}
142
143void* libc_impl::memset(void* s, int c, size_t n) FL_NO_EXCEPT {
144 if (n == 0) return s;
145 return ::memset(s, c, n);
146}
147
148void* libc_impl::memchr(void* s, int c, size_t n) FL_NO_EXCEPT {
149 if (n == 0) return nullptr;
150 return ::memchr(s, c, n);
151}
152
153const void* libc_impl::memchr(const void* s, int c, size_t n) FL_NO_EXCEPT {
154 if (n == 0) return nullptr;
155 return ::memchr(s, c, n);
156}
157
158// ============================================================================
159// Arduino PROGMEM String Functions (platform-specific _P variants)
160// ============================================================================
161// Only available on platforms that support PROGMEM (AVR, some ARM boards)
162
163#if defined(ARDUINO) && defined(FL_IS_AVR)
164
165size_t strlen_P(detail::pgm_p s) FL_NO_EXCEPT {
166 return ::strlen_P(fl::bit_cast<const char*>(s));
167}
168
169int strcmp_P(const char* a, detail::pgm_p b) FL_NO_EXCEPT {
170 return ::strcmp_P(a, fl::bit_cast<const char*>(b));
171}
172
173int memcmp_P(const void* a, detail::pgm_p b, size_t n) FL_NO_EXCEPT {
174 return ::memcmp_P(a, b, n);
175}
176
177void* memcpy_P(void* dest, detail::pgm_p src, size_t n) FL_NO_EXCEPT {
178 return ::memcpy_P(dest, src, n);
179}
180
181#endif // defined(ARDUINO) && defined(FL_IS_AVR)
182
183} // namespace fl
const void * pgm_p
Definition cstring.h:174
char * strncat(char *dest, const char *src, size_t n) FL_NO_EXCEPT
void * memset(void *s, int c, size_t n) FL_NO_EXCEPT
int strncmp(const char *s1, const char *s2, size_t n) FL_NO_EXCEPT
char * strchr(char *s, int c) FL_NO_EXCEPT
void * memcpy(void *dest, const void *src, size_t n) FL_NO_EXCEPT
char * strtok(char *s1, const char *s2) FL_NO_EXCEPT
char * strpbrk(char *s1, const char *s2) FL_NO_EXCEPT
size_t strcspn(const char *s1, const char *s2) FL_NO_EXCEPT
void * memchr(void *s, int c, size_t n) FL_NO_EXCEPT
size_t strlen(const char *s) FL_NO_EXCEPT
size_t strspn(const char *s1, const char *s2) FL_NO_EXCEPT
char * strcpy(char *dest, const char *src) FL_NO_EXCEPT
char * strrchr(char *s, int c) FL_NO_EXCEPT
int memcmp(const void *s1, const void *s2, size_t n) FL_NO_EXCEPT
char * strncpy(char *dest, const char *src, size_t n) FL_NO_EXCEPT
void * memmove(void *dest, const void *src, size_t n) FL_NO_EXCEPT
char * strerror(int errnum) FL_NO_EXCEPT
const char * strstr(const char *haystack, const char *needle) FL_NO_EXCEPT
char * strcat(char *dest, const char *src) FL_NO_EXCEPT
int strcmp(const char *s1, const char *s2) FL_NO_EXCEPT
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
To bit_cast(const From &from) FL_NO_EXCEPT
Definition bit_cast.h:48
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NO_EXCEPT