From cb84df0b44be688fa65ad3de45d4ab1fc67fe078 Mon Sep 17 00:00:00 2001 From: TD-er Date: Fri, 24 Oct 2025 00:06:30 +0200 Subject: [PATCH] [ESPEasy p2p] Cleanup use of std::unique_ptr + p2p data structs --- .../net/DataStructs/NetworkSettingsStruct.h | 13 +- src/_C001.cpp | 2 +- src/_C003.cpp | 2 +- src/_C004.cpp | 2 +- src/_C007.cpp | 2 +- src/_C008.cpp | 2 +- src/_C009.cpp | 2 +- src/_C010.cpp | 2 +- src/_C011.cpp | 8 +- src/_C012.cpp | 2 +- src/_C013.cpp | 139 +++++++++--------- src/_C015.cpp | 2 +- src/_C017.cpp | 2 +- src/_C018.cpp | 8 +- src/include/ESPEasy_config.h | 3 + .../ControllerDelayHandlerStruct.cpp | 2 +- .../ControllerDelayHandlerStruct.h | 4 +- src/src/ControllerQueue/DelayQueueElements.h | 4 + src/src/ControllerQueue/MQTT_queue_element.h | 2 + src/src/ControllerQueue/Queue_element_base.h | 2 + src/src/Controller_config/C018_config.h | 1 + .../DataStructs/C013_p2p_SensorDataStruct.cpp | 74 ++++++---- .../DataStructs/C013_p2p_SensorDataStruct.h | 15 +- .../DataStructs/C013_p2p_SensorInfoStruct.cpp | 88 ++++++----- .../DataStructs/C013_p2p_SensorInfoStruct.h | 16 +- .../DataStructs/ControllerSettingsStruct.h | 10 +- .../DataStructs/NotificationSettingsStruct.h | 4 +- src/src/DataStructs/ProvisioningStruct.h | 4 +- src/src/DataStructs/ValueStruct.h | 2 - src/src/ESPEasyCore/Controller.cpp | 4 +- src/src/Helpers/KeyValueWriter.h | 19 +-- src/src/Helpers/KeyValueWriter_JSON.cpp | 20 ++- src/src/Helpers/KeyValueWriter_JSON.h | 15 +- src/src/WebServer/Chart_JS.cpp | 8 +- src/src/WebServer/Chart_JS.h | 6 +- src/src/WebServer/KeyValueWriter_WebForm.cpp | 18 +-- src/src/WebServer/KeyValueWriter_WebForm.h | 13 +- src/src/WebServer/Markup.cpp | 2 +- 38 files changed, 293 insertions(+), 231 deletions(-) diff --git a/src/ESPEasy/net/DataStructs/NetworkSettingsStruct.h b/src/ESPEasy/net/DataStructs/NetworkSettingsStruct.h index 4c0c046fa..ea2a21577 100644 --- a/src/ESPEasy/net/DataStructs/NetworkSettingsStruct.h +++ b/src/ESPEasy/net/DataStructs/NetworkSettingsStruct.h @@ -49,18 +49,9 @@ private: }; - -typedef std::unique_ptr NetworkSettingsStruct_ptr_type; - -/* - # ifdef USE_SECOND_HEAP - #define MakeNetworkSettings(T) HeapSelectIram ephemeral; NetworkSettingsStruct_ptr_type T(new (std::nothrow) NetworkSettingsStruct()); - #else - */ +DEF_UP(NetworkSettingsStruct); #define MakeNetworkSettings(T) void *calloc_ptr = special_calloc(1, sizeof(NetworkSettingsStruct)); \ - NetworkSettingsStruct_ptr_type T(new (calloc_ptr) NetworkSettingsStruct()); - -// #endif + UP_NetworkSettingsStruct T(new (calloc_ptr) NetworkSettingsStruct()); // Check to see if MakeNetworkSettings was successful #define AllocatedNetworkSettings() (NetworkSettings.get() != nullptr) diff --git a/src/_C001.cpp b/src/_C001.cpp index 445177d35..024825a72 100644 --- a/src/_C001.cpp +++ b/src/_C001.cpp @@ -104,7 +104,7 @@ bool CPlugin_001(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element(new (ptr) C001_queue_element(event->ControllerIndex, event->TaskIndex, std::move(url))); + UP_C001_queue_element element(new (ptr) C001_queue_element(event->ControllerIndex, event->TaskIndex, std::move(url))); success = C001_DelayHandler->addToQueue(std::move(element)); } diff --git a/src/_C003.cpp b/src/_C003.cpp index 3a96f7678..b60773b8a 100644 --- a/src/_C003.cpp +++ b/src/_C003.cpp @@ -63,7 +63,7 @@ bool CPlugin_003(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element( + UP_C003_queue_element element( new (ptr) C003_queue_element( event->ControllerIndex, event->TaskIndex, diff --git a/src/_C004.cpp b/src/_C004.cpp index a450f0da9..314b76b46 100644 --- a/src/_C004.cpp +++ b/src/_C004.cpp @@ -77,7 +77,7 @@ bool CPlugin_004(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element(new (ptr) C004_queue_element(event)); + UP_C004_queue_element element(new (ptr) C004_queue_element(event)); success = C004_DelayHandler->addToQueue(std::move(element)); } diff --git a/src/_C007.cpp b/src/_C007.cpp index f4de2157d..09b6938f9 100644 --- a/src/_C007.cpp +++ b/src/_C007.cpp @@ -81,7 +81,7 @@ bool CPlugin_007(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element(new (ptr) C007_queue_element(event)); + UP_C007_queue_element element(new (ptr) C007_queue_element(event)); success = C007_DelayHandler->addToQueue(std::move(element)); } diff --git a/src/_C008.cpp b/src/_C008.cpp index 761850332..1046663b1 100644 --- a/src/_C008.cpp +++ b/src/_C008.cpp @@ -85,7 +85,7 @@ bool CPlugin_008(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element(new (ptr) C008_queue_element(event, valueCount)); + UP_C008_queue_element element(new (ptr) C008_queue_element(event, valueCount)); success = C008_DelayHandler->addToQueue(std::move(element)); } diff --git a/src/_C009.cpp b/src/_C009.cpp index b2b538bff..c5d139878 100644 --- a/src/_C009.cpp +++ b/src/_C009.cpp @@ -86,7 +86,7 @@ bool CPlugin_009(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element(new (ptr) C009_queue_element(event)); + UP_C009_queue_element element(new (ptr) C009_queue_element(event)); success = C009_DelayHandler->addToQueue(std::move(element)); } Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C009_DELAY_QUEUE, C009_DelayHandler->getNextScheduleTime()); diff --git a/src/_C010.cpp b/src/_C010.cpp index 7322233ef..6e632914d 100644 --- a/src/_C010.cpp +++ b/src/_C010.cpp @@ -74,7 +74,7 @@ bool CPlugin_010(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element(new (ptr) C010_queue_element(event, valueCount)); + UP_C010_queue_element element(new (ptr) C010_queue_element(event, valueCount)); { String pubname; { diff --git a/src/_C011.cpp b/src/_C011.cpp index b391cac3d..c687b67e0 100644 --- a/src/_C011.cpp +++ b/src/_C011.cpp @@ -34,6 +34,8 @@ struct C011_ConfigStruct }; +DEF_UP(C011_ConfigStruct); + // Forward declarations bool load_C011_ConfigStruct(controllerIndex_t ControllerIndex, @@ -153,7 +155,7 @@ bool CPlugin_011(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr customConfig(new (ptr) C011_ConfigStruct); + UP_C011_ConfigStruct customConfig(new (ptr) C011_ConfigStruct); if (customConfig) { uint8_t choice = 0; @@ -245,7 +247,7 @@ bool load_C011_ConfigStruct(controllerIndex_t ControllerIndex, String& HttpMetho return false; } - std::unique_ptrcustomConfig(new (ptr) C011_ConfigStruct); + UP_C011_ConfigStruct customConfig(new (ptr) C011_ConfigStruct); if (!customConfig) { return false; @@ -280,7 +282,7 @@ boolean Create_schedule_HTTP_C011(struct EventStruct *event) // Add a new element to the queue with the minimal payload - std::unique_ptrelement(new (ptr) C011_queue_element(event)); + UP_C011_queue_element element(new (ptr) C011_queue_element(event)); bool success = C011_DelayHandler->addToQueue(std::move(element)); if (success) { diff --git a/src/_C012.cpp b/src/_C012.cpp index d8c0edd6e..0be9339c6 100644 --- a/src/_C012.cpp +++ b/src/_C012.cpp @@ -67,7 +67,7 @@ bool CPlugin_012(CPlugin::Function function, struct EventStruct *event, String& break; } - std::unique_ptr element(new (ptr) C012_queue_element(event, valueCount)); + UP_C012_queue_element element(new (ptr) C012_queue_element(event, valueCount)); for (uint8_t x = 0; x < valueCount; x++) { diff --git a/src/_C013.cpp b/src/_C013.cpp index c707e89a7..0846b56a1 100644 --- a/src/_C013.cpp +++ b/src/_C013.cpp @@ -119,23 +119,25 @@ void C013_SendUDPTaskInfo(uint8_t destUnit, uint8_t sourceTaskIndex, uint8_t des return; } - struct C013_SensorInfoStruct infoReply; - infoReply.sourceUnit = Settings.Unit; - infoReply.sourceTaskIndex = sourceTaskIndex; - infoReply.destTaskIndex = destTaskIndex; - infoReply.deviceNumber = pluginID; - infoReply.destUnit = destUnit; + MakeC013_SensorInfo(infoReply); + if (!AllocatedC013_SensorInfo(infoReply)) return; + + infoReply->sourceUnit = Settings.Unit; + infoReply->sourceTaskIndex = sourceTaskIndex; + infoReply->destTaskIndex = destTaskIndex; + infoReply->deviceNumber = pluginID; + infoReply->destUnit = destUnit; if (destUnit == 0) { // Send to broadcast address - infoReply.destUnit = 255; + infoReply->destUnit = 255; } size_t sizeToSend{}; - if (infoReply.prepareForSend(sizeToSend)) { - C013_sendUDP(infoReply.destUnit, reinterpret_cast(&infoReply), sizeToSend); + if (infoReply->prepareForSend(sizeToSend)) { + C013_sendUDP(infoReply->destUnit, reinterpret_cast(infoReply.get()), sizeToSend); } } @@ -144,32 +146,33 @@ void C013_SendUDPTaskData(struct EventStruct *event, uint8_t destUnit, uint8_t d if (!NetworkConnected(10)) { return; } - struct C013_SensorDataStruct dataReply; + MakeC013_SensorData(dataReply); + if (!dataReply) return; - dataReply.sourceUnit = Settings.Unit; - dataReply.sourceTaskIndex = event->TaskIndex; - dataReply.destTaskIndex = destTaskIndex; - dataReply.deviceNumber = Settings.getPluginID_for_task(event->TaskIndex); + dataReply->sourceUnit = Settings.Unit; + dataReply->sourceTaskIndex = event->TaskIndex; + dataReply->destTaskIndex = destTaskIndex; + dataReply->deviceNumber = Settings.getPluginID_for_task(event->TaskIndex); // FIXME TD-er: We should check for sensorType and pluginID on both sides. // For example sending different sensor type data from one dummy to another is probably not going to work well - dataReply.sensorType = event->getSensorType(); + dataReply->sensorType = event->getSensorType(); const TaskValues_Data_t *taskValues = UserVar.getRawTaskValues_Data(event->TaskIndex); if (taskValues != nullptr) { - memcpy(dataReply.taskValues_Data, taskValues->binary, sizeof(dataReply.taskValues_Data)); + memcpy(dataReply->taskValues_Data, taskValues->binary, sizeof(dataReply->taskValues_Data)); } - dataReply.destUnit = destUnit; + dataReply->destUnit = destUnit; if (destUnit == 0) { // Send to broadcast address - dataReply.destUnit = 255; + dataReply->destUnit = 255; } - dataReply.prepareForSend(); - C013_sendUDP(dataReply.destUnit, reinterpret_cast(&dataReply), sizeof(C013_SensorDataStruct)); + dataReply->prepareForSend(); + C013_sendUDP(dataReply->destUnit, reinterpret_cast(dataReply.get()), sizeof(C013_SensorDataStruct)); } /*********************************************************************************************\ @@ -255,69 +258,71 @@ void C013_Receive(struct EventStruct *event) { { // Allocate this is a separate scope since C013_SensorInfoStruct is a HUGE object // Should not be left allocated on the stack when calling PLUGIN_INIT and save, etc. - struct C013_SensorInfoStruct infoReply; - if (infoReply.setData(event->Data, event->Par2)) { + auto infoReply = C013_SensorInfoStruct::create(event->Data, event->Par2); + if (!infoReply) return; + + { // to prevent flash wear out (bugs in communication?) we can only write to an empty task // so it will write only once and has to be cleared manually through webgui // Also check the receiving end does support the plugin ID. - const pluginID_t currentPluginID = Settings.getPluginID_for_task(infoReply.destTaskIndex); + const pluginID_t currentPluginID = Settings.getPluginID_for_task(infoReply->destTaskIndex); bool mustUpdateCurrentTask = false; - if (currentPluginID == infoReply.deviceNumber) { + if (currentPluginID == infoReply->deviceNumber) { // Check to see if task already is set to receive from this host - if ((Settings.TaskDeviceDataFeed[infoReply.destTaskIndex] == infoReply.sourceUnit) && - Settings.TaskDeviceEnabled[infoReply.destTaskIndex]) { + if ((Settings.TaskDeviceDataFeed[infoReply->destTaskIndex] == infoReply->sourceUnit) && + Settings.TaskDeviceEnabled[infoReply->destTaskIndex]) { mustUpdateCurrentTask = true; } } if ((mustUpdateCurrentTask || !validPluginID_fullcheck(currentPluginID)) && - supportedPluginID(infoReply.deviceNumber)) + supportedPluginID(infoReply->deviceNumber)) { - taskClear(infoReply.destTaskIndex, false); - Settings.TaskDeviceNumber[infoReply.destTaskIndex] = infoReply.deviceNumber.value; - Settings.TaskDeviceDataFeed[infoReply.destTaskIndex] = infoReply.sourceUnit; // remote feed store unit nr sending the data + taskClear(infoReply->destTaskIndex, false); + Settings.TaskDeviceNumber[infoReply->destTaskIndex] = infoReply->deviceNumber.value; + Settings.TaskDeviceDataFeed[infoReply->destTaskIndex] = infoReply->sourceUnit; // remote feed store unit nr sending the data if (mustUpdateCurrentTask) { - Settings.TaskDeviceEnabled[infoReply.destTaskIndex] = true; + Settings.TaskDeviceEnabled[infoReply->destTaskIndex] = true; } constexpr pluginID_t DUMMY_PLUGIN_ID{ 33 }; - if ((infoReply.deviceNumber == DUMMY_PLUGIN_ID) && (infoReply.sensorType != Sensor_VType::SENSOR_TYPE_NONE)) { + if ((infoReply->deviceNumber == DUMMY_PLUGIN_ID) && (infoReply->sensorType != Sensor_VType::SENSOR_TYPE_NONE)) { // Received a dummy device and the sensor type is actually set - Settings.TaskDevicePluginConfig[infoReply.destTaskIndex][0] = static_cast(infoReply.sensorType); + Settings.TaskDevicePluginConfig[infoReply->destTaskIndex][0] = static_cast(infoReply->sensorType); } for (controllerIndex_t x = 0; x < CONTROLLER_MAX; x++) { - Settings.TaskDeviceSendData[x][infoReply.destTaskIndex] = false; + Settings.TaskDeviceSendData[x][infoReply->destTaskIndex] = false; } - safe_strncpy(ExtraTaskSettings.TaskDeviceName, infoReply.taskName, sizeof(infoReply.taskName)); + safe_strncpy(ExtraTaskSettings.TaskDeviceName, infoReply->taskName, sizeof(infoReply->taskName)); for (uint8_t x = 0; x < VARS_PER_TASK; x++) { - safe_strncpy(ExtraTaskSettings.TaskDeviceValueNames[x], infoReply.ValueNames[x], sizeof(infoReply.ValueNames[x])); + safe_strncpy(ExtraTaskSettings.TaskDeviceValueNames[x], infoReply->ValueNames[x], sizeof(infoReply->ValueNames[x])); } - if (infoReply.sourceNodeBuild >= 20871) { - ExtraTaskSettings.version = infoReply.ExtraTaskSettings_version; + if (infoReply->sourceNodeBuild >= 20871) { + ExtraTaskSettings.version = infoReply->ExtraTaskSettings_version; for (uint8_t x = 0; x < VARS_PER_TASK; x++) { -// safe_strncpy(ExtraTaskSettings.TaskDeviceFormula[x], infoReply.TaskDeviceFormula[x], sizeof(infoReply.TaskDeviceFormula[x])); - ExtraTaskSettings.TaskDeviceValueDecimals[x] = infoReply.TaskDeviceValueDecimals[x]; - ExtraTaskSettings.TaskDeviceMinValue[x] = infoReply.TaskDeviceMinValue[x]; - ExtraTaskSettings.TaskDeviceMaxValue[x] = infoReply.TaskDeviceMaxValue[x]; - ExtraTaskSettings.TaskDeviceErrorValue[x] = infoReply.TaskDeviceErrorValue[x]; - ExtraTaskSettings.VariousBits[x] = infoReply.VariousBits[x]; +// safe_strncpy(ExtraTaskSettings.TaskDeviceFormula[x], infoReply->TaskDeviceFormula[x], sizeof(infoReply->TaskDeviceFormula[x])); + ExtraTaskSettings.TaskDeviceValueDecimals[x] = infoReply->TaskDeviceValueDecimals[x]; + ExtraTaskSettings.TaskDeviceMinValue[x] = infoReply->TaskDeviceMinValue[x]; + ExtraTaskSettings.TaskDeviceMaxValue[x] = infoReply->TaskDeviceMaxValue[x]; + ExtraTaskSettings.TaskDeviceErrorValue[x] = infoReply->TaskDeviceErrorValue[x]; + ExtraTaskSettings.VariousBits[x] = infoReply->VariousBits[x]; } for (uint8_t x = 0; x < PLUGIN_CONFIGVAR_MAX; ++x) { - Settings.TaskDevicePluginConfig[infoReply.destTaskIndex][x] = infoReply.TaskDevicePluginConfig[x]; + Settings.TaskDevicePluginConfig[infoReply->destTaskIndex][x] = infoReply->TaskDevicePluginConfig[x]; } } - ExtraTaskSettings.TaskIndex = infoReply.destTaskIndex; - taskIndex = infoReply.destTaskIndex; + ExtraTaskSettings.TaskIndex = infoReply->destTaskIndex; + taskIndex = infoReply->destTaskIndex; mustSave = true; } } @@ -346,16 +351,16 @@ void C013_Receive(struct EventStruct *event) { case 5: // sensor data { - struct C013_SensorDataStruct dataReply; + auto dataReply = C013_SensorDataStruct::create(event->Data, event->Par2); + if (!dataReply) return; // FIXME TD-er: We should check for sensorType and pluginID on both sides. // For example sending different sensor type data from one dummy to another is probably not going to work well - - if (dataReply.setData(event->Data, event->Par2)) { + { // only if this task has a remote feed, update values - const uint8_t remoteFeed = Settings.TaskDeviceDataFeed[dataReply.destTaskIndex]; + const uint8_t remoteFeed = Settings.TaskDeviceDataFeed[dataReply->destTaskIndex]; - if ((remoteFeed != 0) && (remoteFeed == dataReply.sourceUnit)) + if ((remoteFeed != 0) && (remoteFeed == dataReply->sourceUnit)) { // deviceNumber and sensorType were not present before build 2023-05-05. (build NR 20460) // See: @@ -365,45 +370,45 @@ void C013_Receive(struct EventStruct *event) { // If the node is not present in the nodes list (e.g. it had not announced itself in the last 10 minutes or announcement was // missed) // Then we cannot be sure about its build. - const bool mustMatch = dataReply.sourceNodeBuild >= 20460; + const bool mustMatch = dataReply->sourceNodeBuild >= 20460; - if (mustMatch && !dataReply.matchesPluginID(Settings.getPluginID_for_task(dataReply.destTaskIndex))) { + if (mustMatch && !dataReply->matchesPluginID(Settings.getPluginID_for_task(dataReply->destTaskIndex))) { // Mismatch in plugin ID from sending node if (loglevelActiveFor(LOG_LEVEL_ERROR)) { - String log = concat(F("P2P data : PluginID mismatch for task "), dataReply.destTaskIndex + 1); - log += concat(F(" from unit "), dataReply.sourceUnit); - log += concat(F(" remote: "), dataReply.deviceNumber.value); - log += concat(F(" local: "), Settings.getPluginID_for_task(dataReply.destTaskIndex).value); + String log = concat(F("P2P data : PluginID mismatch for task "), dataReply->destTaskIndex + 1); + log += concat(F(" from unit "), dataReply->sourceUnit); + log += concat(F(" remote: "), dataReply->deviceNumber.value); + log += concat(F(" local: "), Settings.getPluginID_for_task(dataReply->destTaskIndex).value); addLogMove(LOG_LEVEL_ERROR, log); } } else { - struct EventStruct TempEvent(dataReply.destTaskIndex); + struct EventStruct TempEvent(dataReply->destTaskIndex); TempEvent.Source = EventValueSource::Enum::VALUE_SOURCE_UDP; const Sensor_VType sensorType = TempEvent.getSensorType(); - if (!mustMatch || dataReply.matchesSensorType(sensorType)) { - TaskValues_Data_t *taskValues = UserVar.getRawTaskValues_Data(dataReply.destTaskIndex); + if (!mustMatch || dataReply->matchesSensorType(sensorType)) { + TaskValues_Data_t *taskValues = UserVar.getRawTaskValues_Data(dataReply->destTaskIndex); if (taskValues != nullptr) { - memcpy(taskValues->binary, dataReply.taskValues_Data, sizeof(dataReply.taskValues_Data)); + memcpy(taskValues->binary, dataReply->taskValues_Data, sizeof(dataReply->taskValues_Data)); } STOP_TIMER(C013_RECEIVE_SENSOR_DATA); - if (node_time.systemTimePresent() && (dataReply.timestamp_sec != 0)) { + if (node_time.systemTimePresent() && (dataReply->timestamp_sec != 0)) { // Only use timestamp of remote unit when we got a system time ourselves // If not, then the order of samples can get messed up. // timestamp_fraq is 16 bit, so need to scale it to 32 bit - TempEvent.timestamp_frac = static_cast(dataReply.timestamp_frac) << 16; - SensorSendTask(&TempEvent, dataReply.timestamp_sec); + TempEvent.timestamp_frac = static_cast(dataReply->timestamp_frac) << 16; + SensorSendTask(&TempEvent, dataReply->timestamp_sec); } else { SensorSendTask(&TempEvent); } } else { // Mismatch in sensor types if (loglevelActiveFor(LOG_LEVEL_ERROR)) { - String log = concat(F("P2P data : SensorType mismatch for task "), dataReply.destTaskIndex + 1); - log += concat(F(" from unit "), dataReply.sourceUnit); + String log = concat(F("P2P data : SensorType mismatch for task "), dataReply->destTaskIndex + 1); + log += concat(F(" from unit "), dataReply->sourceUnit); addLogMove(LOG_LEVEL_ERROR, log); } } diff --git a/src/_C015.cpp b/src/_C015.cpp index 73ce848f4..c9afedd2f 100644 --- a/src/_C015.cpp +++ b/src/_C015.cpp @@ -193,7 +193,7 @@ bool CPlugin_015(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element(new (ptr) C015_queue_element(event, valueCount)); + UP_C015_queue_element element(new (ptr) C015_queue_element(event, valueCount)); success = C015_DelayHandler->addToQueue(std::move(element)); } diff --git a/src/_C017.cpp b/src/_C017.cpp index be1180826..042725380 100644 --- a/src/_C017.cpp +++ b/src/_C017.cpp @@ -71,7 +71,7 @@ bool CPlugin_017(CPlugin::Function function, struct EventStruct *event, String& void *ptr = special_calloc(1, size); if (ptr != nullptr) { - std::unique_ptr element(new (ptr) C017_queue_element(event)); + UP_C017_queue_element element(new (ptr) C017_queue_element(event)); success = C017_DelayHandler->addToQueue(std::move(element)); } Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C017_DELAY_QUEUE, C017_DelayHandler->getNextScheduleTime()); diff --git a/src/_C018.cpp b/src/_C018.cpp index 947c1f1ab..064461434 100644 --- a/src/_C018.cpp +++ b/src/_C018.cpp @@ -134,7 +134,7 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& if (ptr == nullptr) { break; } - std::unique_ptr customConfig(new (ptr) C018_ConfigStruct); + UP_C018_ConfigStruct customConfig(new (ptr) C018_ConfigStruct); if (!customConfig) { break; @@ -153,7 +153,7 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& if (ptr == nullptr) { break; } - std::unique_ptr customConfig(new (ptr) C018_ConfigStruct); + UP_C018_ConfigStruct customConfig(new (ptr) C018_ConfigStruct); if (customConfig) { customConfig->webform_save(); @@ -206,7 +206,7 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& break; } - std::unique_ptr element(new (ptr) C018_queue_element(event, C018_data->getSampleSetCount(event->TaskIndex))); + UP_C018_queue_element element(new (ptr) C018_queue_element(event, C018_data->getSampleSetCount(event->TaskIndex))); success = C018_DelayHandler->addToQueue(std::move(element)); Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C018_DELAY_QUEUE, C018_DelayHandler->getNextScheduleTime()); @@ -329,7 +329,7 @@ bool C018_init(struct EventStruct *event) { if (ptr == nullptr) { return false; } - std::unique_ptr customConfig(new (ptr) C018_ConfigStruct); + UP_C018_ConfigStruct customConfig(new (ptr) C018_ConfigStruct); if (!customConfig) { return false; diff --git a/src/include/ESPEasy_config.h b/src/include/ESPEasy_config.h index 5230e53da..c9799c9cc 100644 --- a/src/include/ESPEasy_config.h +++ b/src/include/ESPEasy_config.h @@ -86,6 +86,9 @@ #define NR_ELEMENTS(ARR) (sizeof (ARR) / sizeof *(ARR)) //#define NR_ELEMENTS(ARR) sizeof(ARR) / sizeof(ARR[0]) +// Shortcut to typedef an unique pointer of a given type +#define DEF_UP(T) typedef std::unique_ptr UP_##T + constexpr unsigned FLOOR_LOG2(unsigned x) { diff --git a/src/src/ControllerQueue/ControllerDelayHandlerStruct.cpp b/src/src/ControllerQueue/ControllerDelayHandlerStruct.cpp index 9bdb7ac0f..6cd457785 100644 --- a/src/src/ControllerQueue/ControllerDelayHandlerStruct.cpp +++ b/src/src/ControllerQueue/ControllerDelayHandlerStruct.cpp @@ -146,7 +146,7 @@ bool ControllerDelayHandlerStruct::isDuplicate(const Queue_element_base& element // Try to add to the queue, if permitted by "delete_oldest" // Return true when item was added, or skipped as it was considered a duplicate -bool ControllerDelayHandlerStruct::addToQueue(std::unique_ptrelement) { +bool ControllerDelayHandlerStruct::addToQueue(UP_Queue_element_base element) { if (!element) { return false; } diff --git a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h index 6982f35c0..58fe0cc61 100644 --- a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h +++ b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h @@ -50,7 +50,7 @@ struct ControllerDelayHandlerStruct { // Try to add to the queue, if permitted by "delete_oldest" // Return true when item was added, or skipped as it was considered a duplicate - bool addToQueue(std::unique_ptrelement); + bool addToQueue(UP_Queue_element_base element); // Get the next element. // Remove front element when max_retries is reached. @@ -76,7 +76,7 @@ struct ControllerDelayHandlerStruct { TimingStatsElements timerstats_id, SchedulerIntervalTimer_e timerID); - std::list >sendQueue; + std::listsendQueue; mutable UnitLastMessageCount_map unitLastMessageCount; unsigned long lastSend = 0; unsigned int minTimeBetweenMessages = CONTROLLER_DELAY_QUEUE_DELAY_DFLT; diff --git a/src/src/ControllerQueue/DelayQueueElements.h b/src/src/ControllerQueue/DelayQueueElements.h index 3c44e89ed..a04029dc6 100644 --- a/src/src/ControllerQueue/DelayQueueElements.h +++ b/src/src/ControllerQueue/DelayQueueElements.h @@ -9,6 +9,9 @@ #include "../ControllerQueue/Queue_element_base.h" #include "../DataStructs/ControllerSettingsStruct.h" +#include // For std::unique_ptr +#include // for std::nothrow + // The most logical place to have these queue element handlers defined would be in their // respective _Cxxx.ino file. @@ -56,6 +59,7 @@ void process_c##NNN####M##_delay_queue(); \ bool init_c##NNN####M##_delay_queue(controllerIndex_t ControllerIndex); \ void exit_c##NNN####M##_delay_queue(); \ + typedef std::unique_ptr UP_C##NNN####M##_queue_element; # ifdef USE_SECOND_HEAP diff --git a/src/src/ControllerQueue/MQTT_queue_element.h b/src/src/ControllerQueue/MQTT_queue_element.h index 4e0436cb5..fef4383de 100644 --- a/src/src/ControllerQueue/MQTT_queue_element.h +++ b/src/src/ControllerQueue/MQTT_queue_element.h @@ -55,6 +55,8 @@ public: bool _retained = false; }; +DEF_UP(MQTT_queue_element); + #endif // if FEATURE_MQTT #endif // CONTROLLERQUEUE_MQTT_QUEUE_ELEMENT_H diff --git a/src/src/ControllerQueue/Queue_element_base.h b/src/src/ControllerQueue/Queue_element_base.h index 68e5f6a43..8c0181228 100644 --- a/src/src/ControllerQueue/Queue_element_base.h +++ b/src/src/ControllerQueue/Queue_element_base.h @@ -36,4 +36,6 @@ public: bool _processByController; }; +DEF_UP(Queue_element_base); + #endif // ifndef CONTROLLERQUEUE_QUEUE_ELEMENT_BASE_H diff --git a/src/src/Controller_config/C018_config.h b/src/src/Controller_config/C018_config.h index 0bc9f4fde..a27b50700 100644 --- a/src/src/Controller_config/C018_config.h +++ b/src/src/Controller_config/C018_config.h @@ -48,6 +48,7 @@ struct C018_ConfigStruct uint32_t rx2_freq = 0; }; +DEF_UP(C018_ConfigStruct); #endif // ifdef USES_C018 diff --git a/src/src/DataStructs/C013_p2p_SensorDataStruct.cpp b/src/src/DataStructs/C013_p2p_SensorDataStruct.cpp index 881a37823..218e65d1e 100644 --- a/src/src/DataStructs/C013_p2p_SensorDataStruct.cpp +++ b/src/src/DataStructs/C013_p2p_SensorDataStruct.cpp @@ -37,27 +37,40 @@ bool C013_SensorDataStruct::prepareForSend() validTaskIndex(destTaskIndex); } -bool C013_SensorDataStruct::setData(const uint8_t *data, size_t size) +UP_C013_SensorDataStruct C013_SensorDataStruct::create(const uint8_t *data, size_t size) { - // First clear entire struct - memset(this, 0, sizeof(C013_SensorDataStruct)); + { + UP_C013_SensorDataStruct invalid_res{}; - if (size < 6) { - return false; + if (size < 6) { + return invalid_res; + } + + if ((data[0] != 255) || // header + (data[1] != 5)) { // ID + return invalid_res; + } + + constexpr unsigned len_upto_checksum = offsetof(C013_SensorDataStruct, checksum); + const ShortChecksumType tmpChecksum( + data, + size, + len_upto_checksum); + + if (size >= (len_upto_checksum + 4)) { + // Data could have checksum, see if it is valid. + uint8_t buf[4]; + memcpy(buf, data + len_upto_checksum, sizeof(buf)); + const ShortChecksumType checksum_data(buf); + + if (checksum_data.isSet()) { + if (!(tmpChecksum == checksum_data)) { + return invalid_res; + } + } + } } - if ((data[0] != 255) || // header - (data[1] != 5)) { // ID - return false; - } - - constexpr unsigned len_upto_checksum = offsetof(C013_SensorDataStruct, checksum); - const ShortChecksumType tmpChecksum( - data, - size, - len_upto_checksum); - - // Need to keep track of different possible versions of data which still need to be supported. // Really old versions of ESPEasy might send upto 80 bytes of uninitialized data // meaning for sizes > 24 bytes we may need to check the version of ESPEasy running on the node. @@ -74,25 +87,28 @@ bool C013_SensorDataStruct::setData(const uint8_t *data, size_t size) } } + MakeC013_SensorData(res); + + if (!AllocatedC013_SensorData(res)) { return res; } + + memcpy((uint8_t*)res.get(), data, size); + + if (size <= 24) { - deviceNumber = INVALID_PLUGIN_ID; - sensorType = Sensor_VType::SENSOR_TYPE_NONE; + res->deviceNumber = INVALID_PLUGIN_ID; + res->sensorType = Sensor_VType::SENSOR_TYPE_NONE; if (sourceNode != nullptr) { - sourceNodeBuild = sourceNode->build; + res->sourceNodeBuild = sourceNode->build; } } - memcpy(this, data, size); - - if (checksum.isSet()) { - if (!(tmpChecksum == checksum)) { - return false; - } + if (!(validTaskIndex(res->sourceTaskIndex) && + validTaskIndex(res->destTaskIndex))) + { + res.reset(); } - - return validTaskIndex(sourceTaskIndex) && - validTaskIndex(destTaskIndex); + return res; } bool C013_SensorDataStruct::matchesPluginID(pluginID_t pluginID) const diff --git a/src/src/DataStructs/C013_p2p_SensorDataStruct.h b/src/src/DataStructs/C013_p2p_SensorDataStruct.h index 6c7ffebe6..e19214943 100644 --- a/src/src/DataStructs/C013_p2p_SensorDataStruct.h +++ b/src/src/DataStructs/C013_p2p_SensorDataStruct.h @@ -13,14 +13,15 @@ # include "../DataTypes/TaskValues_Data.h" # include "../DataTypes/PluginID.h" +struct __attribute__((__packed__)) C013_SensorDataStruct; +DEF_UP(C013_SensorDataStruct); // These structs are sent to other nodes, so make sure not to change order or offset in struct. struct __attribute__((__packed__)) C013_SensorDataStruct { C013_SensorDataStruct() = default; - bool setData(const uint8_t *data, - size_t size); + static UP_C013_SensorDataStruct create(const uint8_t *data, size_t size); bool prepareForSend(); @@ -54,6 +55,16 @@ struct __attribute__((__packed__)) C013_SensorDataStruct uint32_t IDX = 0; }; +#include "../Helpers/Memory.h" + + +#define MakeC013_SensorData(T) void * calloc_ptr = special_calloc(1,sizeof(C013_SensorDataStruct)); UP_C013_SensorDataStruct T(new (calloc_ptr) C013_SensorDataStruct()); + +// Check to see if MakeC013_SensorData was successful +#define AllocatedC013_SensorData(T) (T.get() != nullptr) + + + #endif // ifdef USES_C013 #endif // ifndef DATASTRUCTS_C013_P2P_SENSORDATASTRUCTS_H diff --git a/src/src/DataStructs/C013_p2p_SensorInfoStruct.cpp b/src/src/DataStructs/C013_p2p_SensorInfoStruct.cpp index d215bd07d..1c2c94d67 100644 --- a/src/src/DataStructs/C013_p2p_SensorInfoStruct.cpp +++ b/src/src/DataStructs/C013_p2p_SensorInfoStruct.cpp @@ -47,13 +47,13 @@ bool C013_SensorInfoStruct::prepareForSend(size_t& sizeToSend) TaskDeviceErrorValue[x] = ExtraTaskSettings.TaskDeviceErrorValue[x]; VariousBits[x] = ExtraTaskSettings.VariousBits[x]; -/* - ZERO_FILL(TaskDeviceFormula[x]); + /* + ZERO_FILL(TaskDeviceFormula[x]); - if (ExtraTaskSettings.TaskDeviceFormula[x][0] != 0) { - safe_strncpy(TaskDeviceFormula[x], ExtraTaskSettings.TaskDeviceFormula[x], sizeof(TaskDeviceFormula[x])); - } -*/ + if (ExtraTaskSettings.TaskDeviceFormula[x][0] != 0) { + safe_strncpy(TaskDeviceFormula[x], ExtraTaskSettings.TaskDeviceFormula[x], sizeof(TaskDeviceFormula[x])); + } + */ } for (uint8_t x = 0; x < PLUGIN_CONFIGVAR_MAX; ++x) { @@ -94,54 +94,70 @@ bool C013_SensorInfoStruct::prepareForSend(size_t& sizeToSend) return true; } -bool C013_SensorInfoStruct::setData(const uint8_t *data, size_t size) +UP_C013_SensorInfoStruct C013_SensorInfoStruct::create(const uint8_t *data, size_t size) { - // First clear entire struct - memset(this, 0, sizeof(C013_SensorInfoStruct)); + { + UP_C013_SensorInfoStruct invalid_res{}; - if (size < 6) { - return false; + if (size < 6) { + return invalid_res; + } + + if ((data[0] != 255) || // header + (data[1] != 3)) { // ID + return invalid_res; + } + + // Before copying the data, compute the checksum of the entire packet + constexpr unsigned len_upto_checksum = offsetof(C013_SensorInfoStruct, checksum); + const ShortChecksumType tmpChecksum( + data, + size, + len_upto_checksum); + + if (size >= (len_upto_checksum + 4)) { + // Data could have checksum, see if it is valid. + uint8_t buf[4]; + memcpy(buf, data + len_upto_checksum, sizeof(buf)); + const ShortChecksumType checksum_data(buf); + + if (checksum_data.isSet()) { + if (!(tmpChecksum == checksum_data)) { + return invalid_res; + } + } + } } - if ((data[0] != 255) || // header - (data[1] != 3)) { // ID - return false; - } - - // Before copying the data, compute the checksum of the entire packet - constexpr unsigned len_upto_checksum = offsetof(C013_SensorInfoStruct, checksum); - const ShortChecksumType tmpChecksum( - data, - size, - len_upto_checksum); - // Need to keep track of different possible versions of data which still need to be supported. if (size > sizeof(C013_SensorInfoStruct)) { size = sizeof(C013_SensorInfoStruct); } + MakeC013_SensorInfo(res); + + if (!AllocatedC013_SensorInfo(res)) { return res; } + + memcpy((uint8_t *)res.get(), data, size); + if (size <= 138) { - deviceNumber = INVALID_PLUGIN_ID; - sensorType = Sensor_VType::SENSOR_TYPE_NONE; + res->deviceNumber = INVALID_PLUGIN_ID; + res->sensorType = Sensor_VType::SENSOR_TYPE_NONE; NodeStruct *sourceNode = Nodes.getNode(data[2]); // sourceUnit if (sourceNode != nullptr) { - sourceNodeBuild = sourceNode->build; + res->sourceNodeBuild = sourceNode->build; } } - memcpy(this, data, size); - - if (checksum.isSet()) { - if (!(tmpChecksum == checksum)) { - return false; - } + if (!(validTaskIndex(res->sourceTaskIndex) && + validTaskIndex(res->destTaskIndex) && + validPluginID(res->deviceNumber))) + { + res.reset(); } - - return validTaskIndex(sourceTaskIndex) && - validTaskIndex(destTaskIndex) && - validPluginID(deviceNumber); + return res; } #endif // ifdef USES_C013 diff --git a/src/src/DataStructs/C013_p2p_SensorInfoStruct.h b/src/src/DataStructs/C013_p2p_SensorInfoStruct.h index 7f4650698..656833e09 100644 --- a/src/src/DataStructs/C013_p2p_SensorInfoStruct.h +++ b/src/src/DataStructs/C013_p2p_SensorInfoStruct.h @@ -14,13 +14,18 @@ # include "../DataTypes/PluginID.h" +#include "../Helpers/Memory.h" + +struct __attribute__((__packed__)) C013_SensorInfoStruct; +DEF_UP(C013_SensorInfoStruct); + // These structs are sent to other nodes, so make sure not to change order or offset in struct. struct __attribute__((__packed__)) C013_SensorInfoStruct { C013_SensorInfoStruct() = default; - bool setData(const uint8_t *data, - size_t size); + + static UP_C013_SensorInfoStruct create(const uint8_t *data, size_t size); bool prepareForSend(size_t& sizeToSend); @@ -60,6 +65,13 @@ struct __attribute__((__packed__)) C013_SensorInfoStruct }; +#define MakeC013_SensorInfo(T) void * calloc_ptr = special_calloc(1,sizeof(C013_SensorInfoStruct)); UP_C013_SensorInfoStruct T(new (calloc_ptr) C013_SensorInfoStruct()); + +// Check to see if MakeC013_SensorInfo was successful +#define AllocatedC013_SensorInfo(T) (T.get() != nullptr) + + + #endif // ifdef USES_C013 #endif // ifndef DATASTRUCTS_C013_P2P_SENSORINFOSTRUCTS_H diff --git a/src/src/DataStructs/ControllerSettingsStruct.h b/src/src/DataStructs/ControllerSettingsStruct.h index 471271dfe..c1ee5c112 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.h +++ b/src/src/DataStructs/ControllerSettingsStruct.h @@ -270,14 +270,8 @@ private: #include "../Helpers/Memory.h" -typedef std::unique_ptr ControllerSettingsStruct_ptr_type; -/* -# ifdef USE_SECOND_HEAP -#define MakeControllerSettings(T) HeapSelectIram ephemeral; ControllerSettingsStruct_ptr_type T(new (std::nothrow) ControllerSettingsStruct()); -#else -*/ -#define MakeControllerSettings(T) void * calloc_ptr = special_calloc(1,sizeof(ControllerSettingsStruct)); ControllerSettingsStruct_ptr_type T(new (calloc_ptr) ControllerSettingsStruct()); -//#endif +DEF_UP(ControllerSettingsStruct); +#define MakeControllerSettings(T) void * calloc_ptr = special_calloc(1,sizeof(ControllerSettingsStruct)); UP_ControllerSettingsStruct T(new (calloc_ptr) ControllerSettingsStruct()); // Check to see if MakeControllerSettings was successful #define AllocatedControllerSettings() (ControllerSettings.get() != nullptr) diff --git a/src/src/DataStructs/NotificationSettingsStruct.h b/src/src/DataStructs/NotificationSettingsStruct.h index 751053878..7dde6e843 100644 --- a/src/src/DataStructs/NotificationSettingsStruct.h +++ b/src/src/DataStructs/NotificationSettingsStruct.h @@ -35,9 +35,9 @@ struct NotificationSettingsStruct //its safe to extend this struct, up to 4096 bytes, default values in config are 0 }; -typedef std::unique_ptr NotificationSettingsStruct_ptr_type; +DEF_UP(NotificationSettingsStruct); -#define MakeNotificationSettings(T) void * calloc_ptr = special_calloc(1,sizeof(NotificationSettingsStruct)); NotificationSettingsStruct_ptr_type T(new (calloc_ptr) NotificationSettingsStruct()); +#define MakeNotificationSettings(T) void * calloc_ptr = special_calloc(1,sizeof(NotificationSettingsStruct)); UP_NotificationSettingsStruct T(new (calloc_ptr) NotificationSettingsStruct()); // Check to see if MakeNotificationSettings was successful #define AllocatedNotificationSettings() (NotificationSettings.get() != nullptr) diff --git a/src/src/DataStructs/ProvisioningStruct.h b/src/src/DataStructs/ProvisioningStruct.h index 536c53b06..a8d105f59 100644 --- a/src/src/DataStructs/ProvisioningStruct.h +++ b/src/src/DataStructs/ProvisioningStruct.h @@ -55,9 +55,9 @@ struct ProvisioningStruct }; }; -typedef std::unique_ptr ProvisioningStruct_ptr_type; +DEF_UP(ProvisioningStruct); -#define MakeProvisioningSettings(T) void * calloc_ptr = special_calloc(1,sizeof(ProvisioningStruct)); ProvisioningStruct_ptr_type T(new (calloc_ptr) ProvisioningStruct()); +#define MakeProvisioningSettings(T) void * calloc_ptr = special_calloc(1,sizeof(ProvisioningStruct)); UP_ProvisioningStruct T(new (calloc_ptr) ProvisioningStruct()); diff --git a/src/src/DataStructs/ValueStruct.h b/src/src/DataStructs/ValueStruct.h index dde95e03f..6e128ea1b 100644 --- a/src/src/DataStructs/ValueStruct.h +++ b/src/src/DataStructs/ValueStruct.h @@ -3,8 +3,6 @@ #include #include -#include - // ******************************************************************************** // ValueStruct // ******************************************************************************** diff --git a/src/src/ESPEasyCore/Controller.cpp b/src/src/ESPEasyCore/Controller.cpp index dfb9990fc..cba1a0498 100644 --- a/src/src/ESPEasyCore/Controller.cpp +++ b/src/src/ESPEasyCore/Controller.cpp @@ -1101,7 +1101,7 @@ bool MQTTpublish(controllerIndex_t controller_idx, if (ptr != nullptr) { success = MQTTDelayHandler->addToQueue( - std::unique_ptr( + UP_MQTT_queue_element ( new (ptr) MQTT_queue_element( controller_idx, taskIndex, std::move(topic_str), @@ -1135,7 +1135,7 @@ bool MQTTpublish(controllerIndex_t controller_idx, if (ptr != nullptr) { success = MQTTDelayHandler->addToQueue( - std::unique_ptr( + UP_MQTT_queue_element ( new (ptr) MQTT_queue_element( controller_idx, taskIndex, std::move(topic), diff --git a/src/src/Helpers/KeyValueWriter.h b/src/src/Helpers/KeyValueWriter.h index b3dcc25af..0e907c45b 100644 --- a/src/src/Helpers/KeyValueWriter.h +++ b/src/src/Helpers/KeyValueWriter.h @@ -10,7 +10,7 @@ class KeyValueWriter; -typedef std::unique_ptr Up_KeyValueWriter; +DEF_UP(KeyValueWriter); // ******************************************************************************** // KeyValueWriter @@ -44,7 +44,7 @@ public: virtual void setFooter(const String& footer) { _footer = footer; } - virtual void setIsArray() { _isArray = true; } + virtual void setIsArray() { _isArray = true; } virtual void clear(); @@ -53,14 +53,15 @@ public: virtual void write(const KeyValueStruct& kv) = 0; - void writeLabels(const LabelType::Enum labels[], bool extendedValues = false); + void writeLabels(const LabelType::Enum labels[], + bool extendedValues = false); virtual void writeNote(const String& note); virtual void writeNote(const __FlashStringHelper *note); // virtual void setParent(KeyValueWriter*parent) { _parent = parent; } - virtual int getLevel() const; + virtual int getLevel() const; // When set to 'plainText', the writer will not try to insert writer specific // markings, like
 or 
for example for HTML output @@ -83,13 +84,13 @@ public: virtual void setOutputToString(PrintToString*printToStr) { _toString = printToStr; } // Create writer of the same derived type, with this set as parent - virtual Up_KeyValueWriter createChild() = 0; - virtual Up_KeyValueWriter createChild(const String& header) = 0; - virtual Up_KeyValueWriter createChildArray(const String& header) = 0; + virtual UP_KeyValueWriter createChild() = 0; + virtual UP_KeyValueWriter createChild(const String& header) = 0; + virtual UP_KeyValueWriter createChildArray(const String& header) = 0; // Create new writer of the same derived type, without parent - virtual Up_KeyValueWriter createNew() = 0; - virtual Up_KeyValueWriter createNew(const String& header) = 0; + virtual UP_KeyValueWriter createNew() = 0; + virtual UP_KeyValueWriter createNew(const String& header) = 0; const String& get() const { if (_toString == nullptr) { return EMPTY_STRING; } diff --git a/src/src/Helpers/KeyValueWriter_JSON.cpp b/src/src/Helpers/KeyValueWriter_JSON.cpp index 9d7c4440f..61e93345e 100644 --- a/src/src/Helpers/KeyValueWriter_JSON.cpp +++ b/src/src/Helpers/KeyValueWriter_JSON.cpp @@ -5,8 +5,6 @@ #include "../WebServer/HTML_wrappers.h" -#include - KeyValueWriter_JSON::KeyValueWriter_JSON(bool emptyHeader, PrintToString *toStr) : KeyValueWriter(emptyHeader, toStr) @@ -197,9 +195,9 @@ void KeyValueWriter_JSON::writeValue(const ValueStruct& val) pr.print(to_json_value(str)); } -Up_KeyValueWriter KeyValueWriter_JSON::createChild() +UP_KeyValueWriter KeyValueWriter_JSON::createChild() { - std::unique_ptr child(new (std::nothrow) KeyValueWriter_JSON(this, _toString)); + UP_KeyValueWriter_JSON child(new (std::nothrow) KeyValueWriter_JSON(this, _toString)); child->_allowFormatOverrides = _allowFormatOverrides; @@ -208,9 +206,9 @@ Up_KeyValueWriter KeyValueWriter_JSON::createChild() // return std::make_unique(this, _toString); } -Up_KeyValueWriter KeyValueWriter_JSON::createChild(const String& header) +UP_KeyValueWriter KeyValueWriter_JSON::createChild(const String& header) { - std::unique_ptr child(new (std::nothrow) KeyValueWriter_JSON(header, this, _toString)); + UP_KeyValueWriter_JSON child(new (std::nothrow) KeyValueWriter_JSON(header, this, _toString)); child->_allowFormatOverrides = _allowFormatOverrides; @@ -219,7 +217,7 @@ Up_KeyValueWriter KeyValueWriter_JSON::createChild(const String& header) // return std::make_unique(header, this, _toString); } -Up_KeyValueWriter KeyValueWriter_JSON::createChildArray(const String& header) +UP_KeyValueWriter KeyValueWriter_JSON::createChildArray(const String& header) { auto child = createChild(header); @@ -230,9 +228,9 @@ Up_KeyValueWriter KeyValueWriter_JSON::createChildArray(const String& header) return child; } -Up_KeyValueWriter KeyValueWriter_JSON::createNew() +UP_KeyValueWriter KeyValueWriter_JSON::createNew() { - std::unique_ptr child(new (std::nothrow) KeyValueWriter_JSON(false, _toString)); + UP_KeyValueWriter_JSON child(new (std::nothrow) KeyValueWriter_JSON(false, _toString)); child->_allowFormatOverrides = _allowFormatOverrides; @@ -241,9 +239,9 @@ Up_KeyValueWriter KeyValueWriter_JSON::createNew() // return std::make_unique(false, _toString); } -Up_KeyValueWriter KeyValueWriter_JSON::createNew(const String& header) +UP_KeyValueWriter KeyValueWriter_JSON::createNew(const String& header) { - std::unique_ptr child(new (std::nothrow) KeyValueWriter_JSON(header, _toString)); + UP_KeyValueWriter_JSON child(new (std::nothrow) KeyValueWriter_JSON(header, _toString)); child->_allowFormatOverrides = _allowFormatOverrides; diff --git a/src/src/Helpers/KeyValueWriter_JSON.h b/src/src/Helpers/KeyValueWriter_JSON.h index cad189ce0..e32483d44 100644 --- a/src/src/Helpers/KeyValueWriter_JSON.h +++ b/src/src/Helpers/KeyValueWriter_JSON.h @@ -3,8 +3,9 @@ #include "../Helpers/KeyValueWriter.h" #ifndef BUILD_NO_DEBUG + // # define USE_KWH_JSON_PRETTY_PRINT -#endif +#endif // ifndef BUILD_NO_DEBUG class KeyValueWriter_JSON : public KeyValueWriter { @@ -47,13 +48,13 @@ public: virtual void write(const KeyValueStruct& kv); // Create writer of the same derived type, with this set as parent - virtual Up_KeyValueWriter createChild(); - virtual Up_KeyValueWriter createChild(const String& header); - virtual Up_KeyValueWriter createChildArray(const String& header); + virtual UP_KeyValueWriter createChild(); + virtual UP_KeyValueWriter createChild(const String& header); + virtual UP_KeyValueWriter createChildArray(const String& header); // Create new writer of the same derived type, without parent - virtual Up_KeyValueWriter createNew(); - virtual Up_KeyValueWriter createNew(const String& header); + virtual UP_KeyValueWriter createNew(); + virtual UP_KeyValueWriter createNew(const String& header); virtual bool dataOnlyOutput() const override { // JSON is not intended to be human readable @@ -83,3 +84,5 @@ protected: }; // class KeyValueWriter_JSON + +DEF_UP(KeyValueWriter_JSON); diff --git a/src/src/WebServer/Chart_JS.cpp b/src/src/WebServer/Chart_JS.cpp index 9930c79b9..a3bd845fc 100644 --- a/src/src/WebServer/Chart_JS.cpp +++ b/src/src/WebServer/Chart_JS.cpp @@ -35,7 +35,7 @@ void add_ChartJS_array(KeyValueWriter& parent, } } -Up_KeyValueWriter add_ChartJS_chart_header( +UP_KeyValueWriter add_ChartJS_chart_header( const __FlashStringHelper *chartType, const __FlashStringHelper *id, const ChartJS_title & chartTitle, @@ -54,7 +54,7 @@ Up_KeyValueWriter add_ChartJS_chart_header( onlyJSON); } -Up_KeyValueWriter add_ChartJS_chart_header( +UP_KeyValueWriter add_ChartJS_chart_header( const __FlashStringHelper *chartType, const String & id, const ChartJS_title & chartTitle, @@ -79,7 +79,7 @@ Up_KeyValueWriter add_ChartJS_chart_header( id_c_str, id_c_str)); } - std::unique_ptr chartJSON(new (std::nothrow) KeyValueWriter_JSON(true)); + UP_KeyValueWriter_JSON chartJSON(new (std::nothrow) KeyValueWriter_JSON(true)); if (chartJSON) { chartJSON->allowFormatOverrides(false); @@ -216,7 +216,7 @@ void add_ChartJS_dataset( } } -Up_KeyValueWriter add_ChartJS_dataset_header(KeyValueWriter& dataset, const ChartJS_dataset_config& config) +UP_KeyValueWriter add_ChartJS_dataset_header(KeyValueWriter& dataset, const ChartJS_dataset_config& config) { if (!config.label.isEmpty()) { dataset.write({ F("label"), config.label }); diff --git a/src/src/WebServer/Chart_JS.h b/src/src/WebServer/Chart_JS.h index 3e480b723..3cdf2902e 100644 --- a/src/src/WebServer/Chart_JS.h +++ b/src/src/WebServer/Chart_JS.h @@ -49,7 +49,7 @@ # include "../WebServer/Chart_JS_scale.h" # include "../DataStructs/ChartJS_dataset_config.h" -Up_KeyValueWriter add_ChartJS_chart_header( +UP_KeyValueWriter add_ChartJS_chart_header( const __FlashStringHelper *chartType, const __FlashStringHelper *id, const ChartJS_title & chartTitle, @@ -58,7 +58,7 @@ Up_KeyValueWriter add_ChartJS_chart_header( size_t nrSamples = 0, bool onlyJSON = false); -Up_KeyValueWriter add_ChartJS_chart_header( +UP_KeyValueWriter add_ChartJS_chart_header( const __FlashStringHelper *chartType, const String & id, const ChartJS_title & chartTitle, @@ -103,7 +103,7 @@ void add_ChartJS_dataset( const String & options = EMPTY_STRING); -Up_KeyValueWriter add_ChartJS_dataset_header( +UP_KeyValueWriter add_ChartJS_dataset_header( KeyValueWriter & dataset, const ChartJS_dataset_config& config); diff --git a/src/src/WebServer/KeyValueWriter_WebForm.cpp b/src/src/WebServer/KeyValueWriter_WebForm.cpp index 34a3dd55f..26a246de4 100644 --- a/src/src/WebServer/KeyValueWriter_WebForm.cpp +++ b/src/src/WebServer/KeyValueWriter_WebForm.cpp @@ -145,25 +145,25 @@ void KeyValueWriter_WebForm::write(const KeyValueStruct& kv) } } -Up_KeyValueWriter KeyValueWriter_WebForm::createChild() +UP_KeyValueWriter KeyValueWriter_WebForm::createChild() { - std::unique_ptr child(new (std::nothrow) KeyValueWriter_WebForm(this)); + UP_KeyValueWriter_WebForm child(new (std::nothrow) KeyValueWriter_WebForm(this)); return std::move(child); // return std::make_unique(this); } -Up_KeyValueWriter KeyValueWriter_WebForm::createChild(const String& header) +UP_KeyValueWriter KeyValueWriter_WebForm::createChild(const String& header) { - std::unique_ptr child(new (std::nothrow) KeyValueWriter_WebForm(header, this)); + UP_KeyValueWriter_WebForm child(new (std::nothrow) KeyValueWriter_WebForm(header, this)); return std::move(child); // return std::make_unique(header, this); } -Up_KeyValueWriter KeyValueWriter_WebForm::createChildArray(const String& header) +UP_KeyValueWriter KeyValueWriter_WebForm::createChildArray(const String& header) { auto child = createChild(header); @@ -175,18 +175,18 @@ Up_KeyValueWriter KeyValueWriter_WebForm::createChildArray(const String& header) return child; } -Up_KeyValueWriter KeyValueWriter_WebForm::createNew() +UP_KeyValueWriter KeyValueWriter_WebForm::createNew() { - std::unique_ptr child(new (std::nothrow) KeyValueWriter_WebForm()); + UP_KeyValueWriter_WebForm child(new (std::nothrow) KeyValueWriter_WebForm()); return std::move(child); // return std::make_unique(); } -Up_KeyValueWriter KeyValueWriter_WebForm::createNew(const String& header) +UP_KeyValueWriter KeyValueWriter_WebForm::createNew(const String& header) { - std::unique_ptr child(new (std::nothrow) KeyValueWriter_WebForm(header)); + UP_KeyValueWriter_WebForm child(new (std::nothrow) KeyValueWriter_WebForm(header)); return std::move(child); diff --git a/src/src/WebServer/KeyValueWriter_WebForm.h b/src/src/WebServer/KeyValueWriter_WebForm.h index 6ff77404a..9be055831 100644 --- a/src/src/WebServer/KeyValueWriter_WebForm.h +++ b/src/src/WebServer/KeyValueWriter_WebForm.h @@ -39,13 +39,16 @@ public: virtual void write(const KeyValueStruct& kv); // Create writer of the same derived type, with this set as parent - virtual Up_KeyValueWriter createChild(); - virtual Up_KeyValueWriter createChild(const String& header); - virtual Up_KeyValueWriter createChildArray(const String& header); + virtual UP_KeyValueWriter createChild(); + virtual UP_KeyValueWriter createChild(const String& header); + virtual UP_KeyValueWriter createChildArray(const String& header); // Create new writer of the same derived type, without parent - virtual Up_KeyValueWriter createNew(); - virtual Up_KeyValueWriter createNew(const String& header); + virtual UP_KeyValueWriter createNew(); + virtual UP_KeyValueWriter createNew(const String& header); }; // class KeyValueWriter_WebForm + + +DEF_UP(KeyValueWriter_WebForm); diff --git a/src/src/WebServer/Markup.cpp b/src/src/WebServer/Markup.cpp index 2908f1253..6648a71fb 100644 --- a/src/src/WebServer/Markup.cpp +++ b/src/src/WebServer/Markup.cpp @@ -606,7 +606,7 @@ void addRowLabelValue_copy(LabelType::Enum label) { void addRowColspan(int colspan) { addHtml(strformat( - F(""), + F(""), colspan)); }