ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
alloc_helpers.cpp
Go to the documentation of this file.
2
4
5#include <algorithm>
6#include <cctype>
7#include <cstdarg>
8#include <cstdio>
9#include <cstring>
10#include <string>
11
12namespace esphome {
13
14// --- String helpers ---
15
16std::string str_truncate(const std::string &str, size_t length) {
17 return str.length() > length ? str.substr(0, length) : str;
18}
19
20std::string str_until(const char *str, char ch) {
21 const char *pos = strchr(str, ch);
22 return pos == nullptr ? std::string(str) : std::string(str, pos - str);
23}
24std::string str_until(const std::string &str, char ch) { return str.substr(0, str.find(ch)); }
25
26// wrapper around std::transform to run safely on functions from the ctype.h header
27// see https://en.cppreference.com/w/cpp/string/byte/toupper#Notes
28template<int (*fn)(int)> std::string str_ctype_transform(const std::string &str) {
29 std::string result;
30 result.resize(str.length());
31 std::transform(str.begin(), str.end(), result.begin(), [](unsigned char ch) { return fn(ch); });
32 return result;
33}
34std::string str_lower_case(const std::string &str) { return str_ctype_transform<std::tolower>(str); }
35
36std::string str_upper_case(const std::string &str) {
37 std::string result;
38 result.resize(str.length());
39 std::transform(str.begin(), str.end(), result.begin(), [](unsigned char ch) { return std::toupper(ch); });
40 return result;
41}
42
43std::string str_snake_case(const std::string &str) {
44 std::string result = str;
45 for (char &c : result) {
46 c = to_snake_case_char(c);
47 }
48 return result;
49}
50
51std::string str_sanitize(const std::string &str) {
52 std::string result;
53 result.resize(str.size());
54 str_sanitize_to(&result[0], str.size() + 1, str.c_str());
55 return result;
56}
57
58std::string str_snprintf(const char *fmt, size_t len, ...) {
59 std::string str;
60 va_list args;
61
62 str.resize(len);
64 size_t out_length = vsnprintf(&str[0], len + 1, fmt, args);
65 va_end(args);
66
67 if (out_length < len)
68 str.resize(out_length);
69
70 return str;
71}
72
73std::string str_sprintf(const char *fmt, ...) {
74 std::string str;
75 va_list args;
76
78 size_t length = vsnprintf(nullptr, 0, fmt, args);
79 va_end(args);
80
81 str.resize(length);
83 vsnprintf(&str[0], length + 1, fmt, args);
84 va_end(args);
85
86 return str;
87}
88
89// --- Value formatting helpers ---
90
91std::string value_accuracy_to_string(float value, int8_t accuracy_decimals) {
92 char buf[VALUE_ACCURACY_MAX_LEN];
93 value_accuracy_to_buf(buf, value, accuracy_decimals);
94 return std::string(buf);
95}
96
97// --- Base64 helpers ---
98
99static constexpr const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
100 "abcdefghijklmnopqrstuvwxyz"
101 "0123456789+/";
102
103// Encode 3 input bytes to 4 base64 characters, append 'count' to ret.
104static inline void base64_encode_triple(const char *char_array_3, int count, std::string &ret) {
105 char char_array_4[4];
106 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
107 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
108 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
109 char_array_4[3] = char_array_3[2] & 0x3f;
110
111 for (int j = 0; j < count; j++)
112 ret += BASE64_CHARS[static_cast<uint8_t>(char_array_4[j])];
113}
114
115std::string base64_encode(const std::vector<uint8_t> &buf) { return base64_encode(buf.data(), buf.size()); }
116
117std::string base64_encode(const uint8_t *buf, size_t buf_len) {
118 std::string ret;
119 int i = 0;
120 char char_array_3[3];
121
122 while (buf_len--) {
123 char_array_3[i++] = *(buf++);
124 if (i == 3) {
125 base64_encode_triple(char_array_3, 4, ret);
126 i = 0;
127 }
128 }
129
130 if (i) {
131 for (int j = i; j < 3; j++)
132 char_array_3[j] = '\0';
133
134 base64_encode_triple(char_array_3, i + 1, ret);
135
136 while ((i++ < 3))
137 ret += '=';
138 }
139
140 return ret;
141}
142
143std::vector<uint8_t> base64_decode(const std::string &encoded_string) {
144 // Calculate maximum decoded size: every 4 base64 chars = 3 bytes
145 size_t max_len = ((encoded_string.size() + 3) / 4) * 3;
146 std::vector<uint8_t> ret(max_len);
147 size_t actual_len = base64_decode(encoded_string, ret.data(), max_len);
148 ret.resize(actual_len);
149 return ret;
150}
151
152// --- Hex/binary formatting helpers ---
153
154std::string format_mac_address_pretty(const uint8_t *mac) {
155 char buf[18];
156 format_mac_addr_upper(mac, buf);
157 return std::string(buf);
158}
159
160std::string format_hex(const uint8_t *data, size_t length) {
161 std::string ret;
162 ret.resize(length * 2);
163 format_hex_to(&ret[0], length * 2 + 1, data, length);
164 return ret;
165}
166
167std::string format_hex(const std::vector<uint8_t> &data) { return format_hex(data.data(), data.size()); }
168
169// Shared implementation for uint8_t and string hex pretty formatting
170static std::string format_hex_pretty_uint8(const uint8_t *data, size_t length, char separator, bool show_length) {
171 if (data == nullptr || length == 0)
172 return "";
173 std::string ret;
174 size_t hex_len = separator ? (length * 3 - 1) : (length * 2);
175 ret.resize(hex_len);
176 format_hex_pretty_to(&ret[0], hex_len + 1, data, length, separator);
177 if (show_length && length > 4)
178 return ret + " (" + std::to_string(length) + ")";
179 return ret;
180}
181
182std::string format_hex_pretty(const uint8_t *data, size_t length, char separator, bool show_length) {
183 return format_hex_pretty_uint8(data, length, separator, show_length);
184}
185std::string format_hex_pretty(const std::vector<uint8_t> &data, char separator, bool show_length) {
186 return format_hex_pretty(data.data(), data.size(), separator, show_length);
187}
188
189std::string format_hex_pretty(const uint16_t *data, size_t length, char separator, bool show_length) {
190 if (data == nullptr || length == 0)
191 return "";
192 std::string ret;
193 size_t hex_len = separator ? (length * 5 - 1) : (length * 4);
194 ret.resize(hex_len);
195 format_hex_pretty_to(&ret[0], hex_len + 1, data, length, separator);
196 if (show_length && length > 4)
197 return ret + " (" + std::to_string(length) + ")";
198 return ret;
199}
200std::string format_hex_pretty(const std::vector<uint16_t> &data, char separator, bool show_length) {
201 return format_hex_pretty(data.data(), data.size(), separator, show_length);
202}
203std::string format_hex_pretty(const std::string &data, char separator, bool show_length) {
204 return format_hex_pretty_uint8(reinterpret_cast<const uint8_t *>(data.data()), data.length(), separator, show_length);
205}
206
207std::string format_bin(const uint8_t *data, size_t length) {
208 std::string result;
209 result.resize(length * 8);
210 format_bin_to(&result[0], length * 8 + 1, data, length);
211 return result;
212}
213
214// --- MAC address helpers ---
215
216std::string get_mac_address() {
217 uint8_t mac[6];
219 char buf[13];
221 return std::string(buf);
222}
223
225 char buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
226 return std::string(get_mac_address_pretty_into_buffer(buf));
227}
228
229} // namespace esphome
Heap-allocating helper functions.
std::string value_accuracy_to_string(float value, int8_t accuracy_decimals)
void format_mac_addr_lower_no_sep(const uint8_t *mac, char *output)
Format MAC address as xxxxxxxxxxxxxx (lowercase, no separators)
Definition helpers.h:1458
std::string format_hex(const uint8_t *data, size_t length)
Format the byte array data of length len in lowercased hex.
size_t value_accuracy_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals)
Format value with accuracy to buffer, returns chars written (excluding null)
Definition helpers.cpp:474
std::string str_lower_case(const std::string &str)
Convert the string to lower case.
const char int const __FlashStringHelper va_list args
Definition log.h:74
std::string format_bin(const uint8_t *data, size_t length)
Format the byte array data of length len in binary.
std::string str_sanitize(const std::string &str)
Sanitizes the input string by removing all characters but alphanumerics, dashes and underscores.
va_end(args)
std::string size_t len
std::vector< uint8_t > base64_decode(const std::string &encoded_string)
Decode a base64 string to a byte vector.
char * format_hex_pretty_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator)
Format byte array as uppercase hex to buffer (base implementation).
Definition helpers.cpp:341
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
std::string str_snprintf(const char *fmt, size_t len,...)
size_t size_t pos
Definition helpers.h:1038
const char * get_mac_address_pretty_into_buffer(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > buf)
Get the device MAC address into the given buffer, in colon-separated uppercase hex notation.
Definition helpers.cpp:751
std::string str_upper_case(const std::string &str)
Convert the string to upper case.
std::string format_hex_pretty(const uint8_t *data, size_t length, char separator, bool show_length)
Format a byte array in pretty-printed, human-readable hex format.
std::string str_until(const char *str, char ch)
Extract the part of the string until either the first occurrence of the specified character,...
char * str_sanitize_to(char *buffer, size_t buffer_size, const char *str)
Sanitize a string to buffer, keeping only alphanumerics, dashes, and underscores.
Definition helpers.cpp:225
std::string format_mac_address_pretty(const uint8_t *mac)
std::string base64_encode(const std::vector< uint8_t > &buf)
Encode a byte vector to base64 string.
std::string str_sprintf(const char *fmt,...)
size_t size_t const char va_start(args, fmt)
void get_mac_address_raw(uint8_t *mac)
Get the device MAC address as raw bytes, written into the provided byte array (6 bytes).
Definition helpers.cpp:74
size_t size_t const char * fmt
Definition helpers.h:1039
std::string get_mac_address()
Get the device MAC address as a string, in lowercase hex notation.
constexpr char to_snake_case_char(char c)
Convert a single char to snake_case: lowercase and space to underscore.
Definition helpers.h:965
char * format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length)
Format byte array as lowercase hex to buffer (base implementation).
Definition helpers.cpp:335
std::string str_snake_case(const std::string &str)
Convert the string to snake case (lowercase with underscores).
std::string str_ctype_transform(const std::string &str)
char * format_bin_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length)
Format byte array as binary string to buffer.
Definition helpers.cpp:378
char * format_mac_addr_upper(const uint8_t *mac, char *output)
Format MAC address as XX:XX:XX:XX:XX:XX (uppercase, colon separators)
Definition helpers.h:1453
std::string str_truncate(const std::string &str, size_t length)
Truncate a string to a specific length.
uint16_t length
Definition tt21100.cpp:0