From a1069957913be33649c3a4111abbd161ac5e96ef Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 3 Apr 2026 10:55:34 +0200 Subject: [PATCH] Remove usage of Arduino constant emptyString and use our own instead --- .../ChunkRetryResponse/ChunkRetryResponse.ino | 4 +-- .../RequestContinuation.ino | 2 +- examples/Templates/Templates.ino | 8 ++--- src/AsyncEventSource.cpp | 2 +- src/ESPAsyncWebServer.h | 26 ++++++++-------- src/WebAuthentication.cpp | 20 ++++++------- src/WebHandlers.cpp | 2 +- src/WebRequest.cpp | 30 +++++++++---------- src/WebResponseImpl.h | 2 +- src/literals.h | 6 ++++ 10 files changed, 55 insertions(+), 47 deletions(-) diff --git a/examples/ChunkRetryResponse/ChunkRetryResponse.ino b/examples/ChunkRetryResponse/ChunkRetryResponse.ino index 0b0180002..8c379d602 100644 --- a/examples/ChunkRetryResponse/ChunkRetryResponse.ino +++ b/examples/ChunkRetryResponse/ChunkRetryResponse.ino @@ -177,7 +177,7 @@ void setup() { memcpy(buffer, answer.c_str(), answer.length()); // finish! - triggerUART = emptyString; + triggerUART = asyncsrv::emptyString; key = -1; return answer.length(); @@ -218,6 +218,6 @@ void loop() { key = Serial.read(); Serial.flush(); // async_ws_log_d("UART input: %c", key); - triggerUART = emptyString; + triggerUART = asyncsrv::emptyString; } } diff --git a/examples/RequestContinuation/RequestContinuation.ino b/examples/RequestContinuation/RequestContinuation.ino index 43d0fc51d..8fa8769b6 100644 --- a/examples/RequestContinuation/RequestContinuation.ino +++ b/examples/RequestContinuation/RequestContinuation.ino @@ -83,7 +83,7 @@ void loop() { Serial.setTimeout(10000); String response = Serial.readStringUntil('\n'); // waits for a key to be pressed Serial.println(); - message = emptyString; + message = asyncsrv::emptyString; if (auto request = serialRequest.lock()) { request->send(200, "text/plain", "Answer: " + response); } diff --git a/examples/Templates/Templates.ino b/examples/Templates/Templates.ino index 679188cc9..3415bcbf2 100644 --- a/examples/Templates/Templates.ino +++ b/examples/Templates/Templates.ino @@ -84,7 +84,7 @@ void setup() { if (var == "USER") { return String("Bob ") + millis(); } - return emptyString; + return asyncsrv::emptyString; }); // Serve a static template with a template processor @@ -100,7 +100,7 @@ void setup() { if (var == "USER") { return "Bob"; } - return emptyString; + return asyncsrv::emptyString; }) .setLastModified("Sun, 28 Sep 2025 01:02:03 GMT"); @@ -115,7 +115,7 @@ void setup() { if (var == "USER") { return String("Bob ") + uptimeInMinutes + " minutes"; } - return emptyString; + return asyncsrv::emptyString; }); // Serve a template with dynamic content based on user request @@ -132,7 +132,7 @@ void setup() { return param->value(); } } - return emptyString; + return asyncsrv::emptyString; }); }); diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 60fd92735..fb1d7ab71 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -27,7 +27,7 @@ static String generateEventMessage(const char *message, const char *event, uint3 if (!str.reserve(len)) { async_ws_log_e("Failed to allocate"); - return emptyString; + return asyncsrv::emptyString; } if (reconnect) { diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index f7e222d1b..5f57649ef 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -670,15 +670,17 @@ class AsyncWebServerRequest { AsyncWebServerResponse * beginResponse(FS &fs, const String &path, const char *contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse * - beginResponse(FS &fs, const String &path, const String &contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { + AsyncWebServerResponse *beginResponse( + FS &fs, const String &path, const String &contentType = asyncsrv::emptyString, bool download = false, AwsTemplateProcessor callback = nullptr + ) { return beginResponse(fs, path, contentType.c_str(), download, callback); } AsyncWebServerResponse * beginResponse(File content, const String &path, const char *contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse * - beginResponse(File content, const String &path, const String &contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { + AsyncWebServerResponse *beginResponse( + File content, const String &path, const String &contentType = asyncsrv::emptyString, bool download = false, AwsTemplateProcessor callback = nullptr + ) { return beginResponse(content, path, contentType.c_str(), download, callback); } @@ -783,11 +785,11 @@ class AsyncWebServerRequest { #endif const String &arg(size_t i) const; // get request argument value by number const String &arg(int i) const { - return i < 0 ? emptyString : arg((size_t)i); + return i < 0 ? asyncsrv::emptyString : arg((size_t)i); }; const String &argName(size_t i) const; // get request argument name by number const String &argName(int i) const { - return i < 0 ? emptyString : argName((size_t)i); + return i < 0 ? asyncsrv::emptyString : argName((size_t)i); }; bool hasArg(const char *name) const; // check if argument exists bool hasArg(const String &name) const { @@ -800,14 +802,14 @@ class AsyncWebServerRequest { #ifdef ASYNCWEBSERVER_REGEX const String &pathArg(size_t i) const { if (i >= _pathParams.size()) { - return emptyString; + return asyncsrv::emptyString; } auto it = _pathParams.begin(); std::advance(it, i); return *it; } const String &pathArg(int i) const { - return i < 0 ? emptyString : pathArg((size_t)i); + return i < 0 ? asyncsrv::emptyString : pathArg((size_t)i); } #else const String &pathArg(size_t i) const __attribute__((error("ERR: pathArg() requires -D ASYNCWEBSERVER_REGEX and only works on regex handlers"))); @@ -826,11 +828,11 @@ class AsyncWebServerRequest { const String &header(size_t i) const; // get request header value by number const String &header(int i) const { - return i < 0 ? emptyString : header((size_t)i); + return i < 0 ? asyncsrv::emptyString : header((size_t)i); }; const String &headerName(size_t i) const; // get request header name by number const String &headerName(int i) const { - return i < 0 ? emptyString : headerName((size_t)i); + return i < 0 ? asyncsrv::emptyString : headerName((size_t)i); }; size_t headers() const; // get header count @@ -888,7 +890,7 @@ class AsyncWebServerRequest { _attributes[name] = value; } void setAttribute(const char *name, bool value) { - _attributes[name] = value ? "1" : emptyString; + _attributes[name] = value ? "1" : asyncsrv::emptyString; } void setAttribute(const char *name, long value) { _attributes[name] = String(value); @@ -904,7 +906,7 @@ class AsyncWebServerRequest { return _attributes.find(name) != _attributes.end(); } - const String &getAttribute(const char *name, const String &defaultValue = emptyString) const; + const String &getAttribute(const char *name, const String &defaultValue = asyncsrv::emptyString) const; bool getAttribute(const char *name, bool defaultValue) const; long getAttribute(const char *name, long defaultValue) const; float getAttribute(const char *name, float defaultValue) const; diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 64509e07b..fff0c5c17 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -26,19 +26,19 @@ bool checkBasicAuthentication(const char *hash, const char *username, const char String generateBasicHash(const char *username, const char *password) { if (username == NULL || password == NULL) { - return emptyString; + return asyncsrv::emptyString; } size_t toencodeLen = strlen(username) + strlen(password) + 1; char *toencode = new char[toencodeLen + 1]; if (toencode == NULL) { - return emptyString; + return asyncsrv::emptyString; } char *encoded = new char[base64_encode_expected_len(toencodeLen) + 1]; if (encoded == NULL) { delete[] toencode; - return emptyString; + return asyncsrv::emptyString; } sprintf_P(toencode, PSTR("%s:%s"), username, password); if (base64_encode_chars(toencode, toencodeLen, encoded) > 0) { @@ -49,7 +49,7 @@ String generateBasicHash(const char *username, const char *password) { } delete[] toencode; delete[] encoded; - return emptyString; + return asyncsrv::emptyString; } static bool getMD5(uint8_t *data, uint16_t len, char *output) { // 33 bytes or more @@ -90,7 +90,7 @@ String genRandomMD5() { char *out = (char *)malloc(33); if (out == NULL || !getMD5((uint8_t *)(&r), 4, out)) { async_ws_log_e("Failed to allocate"); - return emptyString; + return asyncsrv::emptyString; } String res = String(out); free(out); @@ -101,7 +101,7 @@ static String stringMD5(const String &in) { char *out = (char *)malloc(33); if (out == NULL || !getMD5((uint8_t *)(in.c_str()), in.length(), out)) { async_ws_log_e("Failed to allocate"); - return emptyString; + return asyncsrv::emptyString; } String res = String(out); free(out); @@ -110,19 +110,19 @@ static String stringMD5(const String &in) { String generateDigestHash(const char *username, const char *password, const char *realm) { if (username == NULL || password == NULL || realm == NULL) { - return emptyString; + return asyncsrv::emptyString; } char *out = (char *)malloc(33); if (out == NULL) { async_ws_log_e("Failed to allocate"); - return emptyString; + return asyncsrv::emptyString; } String in; if (!in.reserve(strlen(username) + strlen(realm) + strlen(password) + 2)) { async_ws_log_e("Failed to allocate"); free(out); - return emptyString; + return asyncsrv::emptyString; } in.concat(username); @@ -134,7 +134,7 @@ String generateDigestHash(const char *username, const char *password, const char if (!getMD5((uint8_t *)(in.c_str()), in.length(), out)) { async_ws_log_e("Failed to allocate"); free(out); - return emptyString; + return asyncsrv::emptyString; } in = String(out); diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 698ab0064..ad3c1c1ee 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -260,7 +260,7 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) { request->_tempFile.close(); response = new AsyncBasicResponse(304); // Not modified } else { - response = new AsyncFileResponse(request->_tempFile, filename, emptyString, false, _callback); + response = new AsyncFileResponse(request->_tempFile, filename, asyncsrv::emptyString, false, _callback); } if (!response) { diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 87593bbdd..fa692057e 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -298,7 +298,7 @@ void AsyncWebServerRequest::_addGetParams(const String ¶ms) { equal = end; } String name = urlDecode(params.substring(start, equal)); - String value = urlDecode(equal + 1 < end ? params.substring(equal + 1, end) : emptyString); + String value = urlDecode(equal + 1 < end ? params.substring(equal + 1, end) : asyncsrv::emptyString); if (name.length()) { _params.emplace_back(name, value); } @@ -336,7 +336,7 @@ bool AsyncWebServerRequest::_parseReqHead() { _version = 1; } - _temp = emptyString; + _temp = asyncsrv::emptyString; return true; } @@ -545,7 +545,7 @@ bool AsyncWebServerRequest::_parseReqHeader() { } #if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) // Ancient PRI core does not have String::clear() method 8-() - _temp = emptyString; + _temp = asyncsrv::emptyString; #else _temp.clear(); #endif @@ -570,7 +570,7 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { #if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350) || defined(LIBRETINY) // Ancient PRI core does not have String::clear() method 8-() - _temp = emptyString; + _temp = asyncsrv::emptyString; #else _temp.clear(); #endif @@ -615,10 +615,10 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { if (!_parsedLength) { _multiParseState = EXPECT_BOUNDARY; - _temp = emptyString; - _itemName = emptyString; - _itemFilename = emptyString; - _itemType = emptyString; + _temp = asyncsrv::emptyString; + _itemName = asyncsrv::emptyString; + _itemFilename = asyncsrv::emptyString; + _itemType = asyncsrv::emptyString; } if (_multiParseState == WAIT_FOR_RETURN1) { @@ -686,13 +686,13 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { _params.emplace_back(T_filename, _itemFilename, true, true); } } - _temp = emptyString; + _temp = asyncsrv::emptyString; } else { _multiParseState = WAIT_FOR_RETURN1; // value starts from here _itemSize = 0; _itemStartIndex = _parsedLength; - _itemValue = emptyString; + _itemValue = asyncsrv::emptyString; if (_itemIsFile) { if (_itemBuffer) { free(_itemBuffer); @@ -1219,7 +1219,7 @@ const String &AsyncWebServerRequest::arg(const char *name) const { return arg.value(); } } - return emptyString; + return asyncsrv::emptyString; } #ifdef ESP8266 @@ -1238,7 +1238,7 @@ const String &AsyncWebServerRequest::argName(size_t i) const { const String &AsyncWebServerRequest::header(const char *name) const { const AsyncWebHeader *h = getHeader(name); - return h ? h->value() : emptyString; + return h ? h->value() : asyncsrv::emptyString; } #ifdef ESP8266 @@ -1249,12 +1249,12 @@ const String &AsyncWebServerRequest::header(const __FlashStringHelper *data) con const String &AsyncWebServerRequest::header(size_t i) const { const AsyncWebHeader *h = getHeader(i); - return h ? h->value() : emptyString; + return h ? h->value() : asyncsrv::emptyString; } const String &AsyncWebServerRequest::headerName(size_t i) const { const AsyncWebHeader *h = getHeader(i); - return h ? h->name() : emptyString; + return h ? h->name() : asyncsrv::emptyString; } String AsyncWebServerRequest::urlDecode(const String &text) const { @@ -1265,7 +1265,7 @@ String AsyncWebServerRequest::urlDecode(const String &text) const { // Allocate the string internal buffer - never longer from source text if (!decoded.reserve(len)) { async_ws_log_e("Failed to allocate"); - return emptyString; + return asyncsrv::emptyString; } while (i < len) { char decodedChar; diff --git a/src/WebResponseImpl.h b/src/WebResponseImpl.h index 747d4a2b1..7f0d25ac6 100644 --- a/src/WebResponseImpl.h +++ b/src/WebResponseImpl.h @@ -37,7 +37,7 @@ class AsyncBasicResponse : public AsyncWebServerResponse { public: explicit AsyncBasicResponse(int code, const char *contentType = asyncsrv::empty, const char *content = asyncsrv::empty); - AsyncBasicResponse(int code, const String &contentType, const String &content = emptyString) + AsyncBasicResponse(int code, const String &contentType, const String &content = asyncsrv::emptyString) : AsyncBasicResponse(code, contentType.c_str(), content.c_str()) {} void _respond(AsyncWebServerRequest *request) final; size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time) final { diff --git a/src/literals.h b/src/literals.h index 7244afcce..9872ed8a3 100644 --- a/src/literals.h +++ b/src/literals.h @@ -24,6 +24,12 @@ namespace asyncsrv { +#ifdef ARDUINO +using ::emptyString; +#else +inline const String emptyString{}; +#endif + static constexpr const char empty[] = ""; static constexpr const char T__opaque[] = "\", opaque=\"";