ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
progmem.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstddef>
5#include <cstdint>
6
7#include "esphome/core/hal.h" // For PROGMEM definition
8
9// Platform-agnostic macros for PROGMEM string handling
10// On ESP8266/Arduino: Use Arduino's F() macro for PROGMEM strings
11// On other platforms: Use plain strings (no PROGMEM)
12
13#ifdef USE_ESP8266
14// ESP8266 uses Arduino macros
15#define ESPHOME_F(string_literal) F(string_literal)
16#define ESPHOME_PGM_P PGM_P
17#define ESPHOME_PSTR(s) PSTR(s)
18#define ESPHOME_strncpy_P strncpy_P
19#define ESPHOME_strncat_P strncat_P
20#define ESPHOME_snprintf_P snprintf_P
21#define ESPHOME_strcmp_P strcmp_P
22#define ESPHOME_strcasecmp_P strcasecmp_P
23#define ESPHOME_strncmp_P strncmp_P
24#define ESPHOME_strncasecmp_P strncasecmp_P
25// Type for pointers to PROGMEM strings (for use with ESPHOME_F return values)
26using ProgmemStr = const __FlashStringHelper *;
27#else
28#define ESPHOME_F(string_literal) (string_literal)
29#define ESPHOME_PGM_P const char *
30#define ESPHOME_PSTR(s) (s)
31#define ESPHOME_strncpy_P strncpy
32#define ESPHOME_strncat_P strncat
33#define ESPHOME_snprintf_P snprintf
34#define ESPHOME_strcmp_P strcmp
35#define ESPHOME_strcasecmp_P strcasecmp
36#define ESPHOME_strncmp_P strncmp
37#define ESPHOME_strncasecmp_P strncasecmp
38// Type for pointers to strings (no PROGMEM on non-ESP8266 platforms)
39using ProgmemStr = const char *;
40#endif
41
42namespace esphome {
43
45template<size_t N> struct FixedString {
46 char data[N]{};
47 constexpr FixedString(const char (&str)[N]) {
48 for (size_t i = 0; i < N; ++i)
49 data[i] = str[i];
50 }
51 constexpr size_t size() const { return N - 1; } // exclude null terminator
52};
53
62template<FixedString... Strs> struct ProgmemStringTable {
63 static constexpr size_t COUNT = sizeof...(Strs);
64 static constexpr size_t BLOB_SIZE = (0 + ... + (Strs.size() + 1));
65
67 static constexpr auto make_blob() {
68 std::array<char, BLOB_SIZE> result{};
69 size_t pos = 0;
70 auto copy = [&](const auto &str) {
71 for (size_t i = 0; i <= str.size(); ++i)
72 result[pos++] = str.data[i];
73 };
74 (copy(Strs), ...);
75 return result;
76 }
77
79 static constexpr auto make_offsets() {
80 static_assert(COUNT > 0, "PROGMEM_STRING_TABLE must contain at least one string");
81 static_assert(COUNT <= 255, "PROGMEM_STRING_TABLE supports at most 255 strings with uint8_t indices");
82 static_assert(BLOB_SIZE <= 255, "PROGMEM_STRING_TABLE blob exceeds 255 bytes; use fewer/shorter strings");
83 std::array<uint8_t, COUNT> result{};
84 size_t pos = 0, idx = 0;
85 ((result[idx++] = static_cast<uint8_t>(pos), pos += Strs.size() + 1), ...);
86 return result;
87 }
88};
89
90// Forward declaration for LogString (defined in log.h)
91struct LogString;
92
96#define PROGMEM_STRING_TABLE(Name, ...) \
97 struct Name { \
98 using Table = ::esphome::ProgmemStringTable<__VA_ARGS__>; \
99 static constexpr size_t COUNT = Table::COUNT; \
100 static constexpr uint8_t LAST_INDEX = COUNT - 1; \
101 static constexpr size_t BLOB_SIZE = Table::BLOB_SIZE; \
102 static constexpr auto BLOB PROGMEM = Table::make_blob(); \
103 static constexpr auto OFFSETS PROGMEM = Table::make_offsets(); \
104 static const char *get_(uint8_t idx, uint8_t fallback) { \
105 if (idx >= COUNT) \
106 idx = fallback; \
107 return &BLOB[::esphome::progmem_read_byte(&OFFSETS[idx])]; \
108 } \
109 static ::ProgmemStr get_progmem_str(uint8_t idx, uint8_t fallback) { \
110 return reinterpret_cast<::ProgmemStr>(get_(idx, fallback)); \
111 } \
112 static const ::esphome::LogString *get_log_str(uint8_t idx, uint8_t fallback) { \
113 return reinterpret_cast<const ::esphome::LogString *>(get_(idx, fallback)); \
114 } \
115 }
116
117} // namespace esphome
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
size_t size_t pos
Definition helpers.h:729
const __FlashStringHelper * ProgmemStr
Definition progmem.h:26
Helper for C++20 string literal template arguments.
Definition progmem.h:45
constexpr size_t size() const
Definition progmem.h:51
constexpr FixedString(const char(&str)[N])
Definition progmem.h:47
Compile-time string table that packs strings into a single blob with offset lookup.
Definition progmem.h:62
static constexpr size_t COUNT
Definition progmem.h:63
static constexpr size_t BLOB_SIZE
Definition progmem.h:64
static constexpr auto make_blob()
Generate packed string blob at compile time.
Definition progmem.h:67
static constexpr auto make_offsets()
Generate offset table at compile time (uint8_t limits blob to 255 bytes)
Definition progmem.h:79