mirror of
https://github.com/esphome/esphome.git
synced 2026-10-06 10:56:43 +00:00
[web_server] Avoid temporary std::string allocations in request parameter parsing (#14366)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
00242443e1
commit
54f410901f
@@ -969,7 +969,9 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa
|
||||
parse_light_param_uint_(request, ESPHOME_F("transition"), call, &decltype(call)::set_transition_length, 1000);
|
||||
|
||||
if (is_on) {
|
||||
parse_string_param_(request, ESPHOME_F("effect"), call, &decltype(call)::set_effect);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("effect"), call,
|
||||
static_cast<light::LightCall &(light::LightCall::*) (const char *, size_t)>(&decltype(call)::set_effect));
|
||||
}
|
||||
|
||||
DEFER_ACTION(call, call.perform());
|
||||
@@ -1368,7 +1370,9 @@ void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMat
|
||||
}
|
||||
|
||||
auto call = obj->make_call();
|
||||
parse_string_param_(request, ESPHOME_F("value"), call, &decltype(call)::set_value);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("value"), call,
|
||||
static_cast<text::TextCall &(text::TextCall::*) (const char *, size_t)>(&decltype(call)::set_value));
|
||||
|
||||
DEFER_ACTION(call, call.perform());
|
||||
request->send(200);
|
||||
@@ -1426,7 +1430,9 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM
|
||||
}
|
||||
|
||||
auto call = obj->make_call();
|
||||
parse_string_param_(request, ESPHOME_F("option"), call, &decltype(call)::set_option);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("option"), call,
|
||||
static_cast<select::SelectCall &(select::SelectCall::*) (const char *, size_t)>(&decltype(call)::set_option));
|
||||
|
||||
DEFER_ACTION(call, call.perform());
|
||||
request->send(200);
|
||||
@@ -1487,10 +1493,18 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url
|
||||
auto call = obj->make_call();
|
||||
|
||||
// Parse string mode parameters
|
||||
parse_string_param_(request, ESPHOME_F("mode"), call, &decltype(call)::set_mode);
|
||||
parse_string_param_(request, ESPHOME_F("fan_mode"), call, &decltype(call)::set_fan_mode);
|
||||
parse_string_param_(request, ESPHOME_F("swing_mode"), call, &decltype(call)::set_swing_mode);
|
||||
parse_string_param_(request, ESPHOME_F("preset"), call, &decltype(call)::set_preset);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("mode"), call,
|
||||
static_cast<climate::ClimateCall &(climate::ClimateCall::*) (const char *, size_t)>(&decltype(call)::set_mode));
|
||||
parse_cstr_param_(request, ESPHOME_F("fan_mode"), call,
|
||||
static_cast<climate::ClimateCall &(climate::ClimateCall::*) (const char *, size_t)>(
|
||||
&decltype(call)::set_fan_mode));
|
||||
parse_cstr_param_(request, ESPHOME_F("swing_mode"), call,
|
||||
static_cast<climate::ClimateCall &(climate::ClimateCall::*) (const char *, size_t)>(
|
||||
&decltype(call)::set_swing_mode));
|
||||
parse_cstr_param_(request, ESPHOME_F("preset"), call,
|
||||
static_cast<climate::ClimateCall &(climate::ClimateCall::*) (const char *, size_t)>(
|
||||
&decltype(call)::set_preset));
|
||||
|
||||
// Parse temperature parameters
|
||||
// static_cast needed to disambiguate overloaded setters (float vs optional<float>)
|
||||
@@ -1804,7 +1818,10 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques
|
||||
}
|
||||
|
||||
auto call = obj->make_call();
|
||||
parse_string_param_(request, ESPHOME_F("code"), call, &decltype(call)::set_code);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("code"), call,
|
||||
static_cast<alarm_control_panel::AlarmControlPanelCall &(
|
||||
alarm_control_panel::AlarmControlPanelCall::*) (const char *, size_t)>(&decltype(call)::set_code));
|
||||
|
||||
// Lookup table for alarm control panel methods
|
||||
static const struct {
|
||||
@@ -1892,7 +1909,10 @@ void WebServer::handle_water_heater_request(AsyncWebServerRequest *request, cons
|
||||
water_heater::WaterHeaterCall &base_call = call;
|
||||
|
||||
// Parse mode parameter
|
||||
parse_string_param_(request, ESPHOME_F("mode"), base_call, &water_heater::WaterHeaterCall::set_mode);
|
||||
parse_cstr_param_(
|
||||
request, ESPHOME_F("mode"), base_call,
|
||||
static_cast<water_heater::WaterHeaterCall &(water_heater::WaterHeaterCall::*) (const char *, size_t)>(
|
||||
&water_heater::WaterHeaterCall::set_mode));
|
||||
|
||||
// Parse temperature parameters
|
||||
parse_num_param_(request, ESPHOME_F("target_temperature"), base_call,
|
||||
|
||||
@@ -533,13 +533,13 @@ class WebServer final : public Controller, public Component, public AsyncWebHand
|
||||
}
|
||||
}
|
||||
|
||||
// Generic helper to parse and apply a string parameter
|
||||
// Generic helper to parse and apply a string parameter using const char* setter (avoids std::string allocation)
|
||||
template<typename T, typename Ret>
|
||||
void parse_string_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call,
|
||||
Ret (T::*setter)(const std::string &)) {
|
||||
void parse_cstr_param_(AsyncWebServerRequest *request, ParamNameType param_name, T &call,
|
||||
Ret (T::*setter)(const char *, size_t)) {
|
||||
if (request->hasArg(param_name)) {
|
||||
const auto &value = request->arg(param_name);
|
||||
(call.*setter)(std::string(value.c_str(), value.length()));
|
||||
(call.*setter)(value.c_str(), value.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user