From 661f4c346325d8471baf2476c4725743cc516a68 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Sat, 29 Dec 2018 07:05:08 +0900 Subject: [PATCH] Fixed memory leaking --- examples/mqttRSSI/mqttRSSI.ino | 33 +++++++----- examples/mqttRSSI_FS/data/mqtt_setting.json | 8 +-- examples/mqttRSSI_FS/data/param.json | 27 ++++++++++ examples/mqttRSSI_FS/mqttRSSI_FS.ino | 2 + src/AutoConnect.cpp | 4 +- src/AutoConnectAux.cpp | 6 +-- src/AutoConnectDefs.h | 3 +- src/AutoConnectElement.h | 2 +- src/AutoConnectElementBasis.h | 27 ++++------ src/AutoConnectElementBasisImpl.h | 60 ++++++++++++++------- src/AutoConnectElementJson.h | 3 -- src/AutoConnectElementJsonImpl.h | 4 -- 12 files changed, 114 insertions(+), 65 deletions(-) create mode 100644 examples/mqttRSSI_FS/data/param.json diff --git a/examples/mqttRSSI/mqttRSSI.ino b/examples/mqttRSSI/mqttRSSI.ino index 766216a..f8bac9e 100644 --- a/examples/mqttRSSI/mqttRSSI.ino +++ b/examples/mqttRSSI/mqttRSSI.ino @@ -57,6 +57,7 @@ static const char AUX_mqtt_setting[] PROGMEM = R"raw( { "name": "mqttserver", "type": "ACInput", + "value": "", "placeholder": "MQTT broker server", "label": "Server" }, @@ -75,13 +76,26 @@ static const char AUX_mqtt_setting[] PROGMEM = R"raw( "type": "ACInput", "label": "API Key" }, + { + "name": "newline", + "type": "ACElement", + "value": "
" + }, + { + "name": "uniqueid", + "type": "ACCheckbox", + "value": "unique", + "label": "Use APID unique", + "checked": false + }, { "name": "period", "type": "ACRadio", "label": "Update period", "value": [ "30 sec.", - "60 sec." + "60 sec.", + "180 sec." ], "arrange": "vertical", "checked": 1 @@ -91,13 +105,6 @@ static const char AUX_mqtt_setting[] PROGMEM = R"raw( "type": "ACElement", "value": "
" }, - { - "name": "uniqueid", - "type": "ACCheckbox", - "value": "unique", - "label": "Use APID unique", - "checked": true - }, { "name": "hostname", "type": "ACInput", @@ -223,10 +230,10 @@ String loadParams(AutoConnectAux& aux, PageArgument& args) { SPIFFS.begin(); File param = SPIFFS.open(PARAM_FILE, "r"); if (param) { - // if (aux.loadElement(param)) - // Serial.println(PARAM_FILE " loaded"); - // else - // Serial.println(PARAM_FILE " failed to load"); + if (aux.loadElement(param)) + Serial.println(PARAM_FILE " loaded"); + else + Serial.println(PARAM_FILE " failed to load"); param.close(); } else @@ -341,9 +348,11 @@ void setup() { AutoConnectInput& hostnameElm = setting->getElement("hostname"); if (uniqueidElm.checked) { config.apid = String("ESP") + "_" + String(ESP.getChipId(), HEX); + Serial.println("apid set to " + config.apid); } if (hostnameElm.value.length()) { config.hostName = hostnameElm.value; + Serial.println("hostname set to " + config.hostName); } config.bootUri = AC_ONBOOTURI_HOME; config.homeUri = "/"; diff --git a/examples/mqttRSSI_FS/data/mqtt_setting.json b/examples/mqttRSSI_FS/data/mqtt_setting.json index 2778428..acba2fa 100644 --- a/examples/mqttRSSI_FS/data/mqtt_setting.json +++ b/examples/mqttRSSI_FS/data/mqtt_setting.json @@ -18,14 +18,14 @@ { "name": "mqttserver", "type": "ACInput", - "value": "mqtt.thingspeak.com", + "value": "", "placeholder": "MQTT broker server", "label": "Server" }, { "name": "channelid", "type": "ACInput", - "value": "454951", + "value": "", "label": "Channel ID" }, { @@ -37,7 +37,7 @@ { "name": "apikey", "type": "ACInput", - "value": "HBVQ2XV6VYBI4582", + "value": "", "label": "API Key" }, { @@ -62,7 +62,7 @@ "type": "ACCheckbox", "value": "unique", "label": "Use APID unique", - "checked": true + "checked": false }, { "name": "hostname", diff --git a/examples/mqttRSSI_FS/data/param.json b/examples/mqttRSSI_FS/data/param.json new file mode 100644 index 0000000..a73599b --- /dev/null +++ b/examples/mqttRSSI_FS/data/param.json @@ -0,0 +1,27 @@ +[ + { + "name": "mqttserver", + "type": "ACInput", + "value": "mqtt.thingspeak.com", + "placeholder": "MQTT broker server", + "label": "Server" + }, + { + "name": "channelid", + "type": "ACInput", + "value": "454951", + "label": "Channel ID" + }, + { + "name": "userkey", + "type": "ACInput", + "value": "NRTFYGJ6TJFGX4RC", + "label": "User Key" + }, + { + "name": "apikey", + "type": "ACInput", + "value": "HBVQ2XV6VYBI4582", + "label": "API Key" + } +] diff --git a/examples/mqttRSSI_FS/mqttRSSI_FS.ino b/examples/mqttRSSI_FS/mqttRSSI_FS.ino index 4a5b1bf..c4c6778 100644 --- a/examples/mqttRSSI_FS/mqttRSSI_FS.ino +++ b/examples/mqttRSSI_FS/mqttRSSI_FS.ino @@ -236,9 +236,11 @@ void setup() { AutoConnectInput& hostnameElm = setting->getElement("hostname"); if (uniqueidElm.checked) { config.apid = String("ESP") + "_" + String(ESP.getChipId(), HEX); + Serial.println("apid set to " + config.apid); } if (hostnameElm.value.length()) { config.hostName = hostnameElm.value; + Serial.println("hostname set to " + config.hostName); } config.bootUri = AC_ONBOOTURI_HOME; config.homeUri = "/"; diff --git a/src/AutoConnect.cpp b/src/AutoConnect.cpp index 671f81d..d81840b 100644 --- a/src/AutoConnect.cpp +++ b/src/AutoConnect.cpp @@ -662,9 +662,9 @@ bool AutoConnect::_classifyHandle(HTTPMethod method, String uri) { // If the current request argument contains AutoConnectElement, it is // the form data of the AutoConnectAux page and with this timing save // the value of each element. - if (_webServer->hasArg(String(AUTOCONNECT_AUXURI_PARAM))) { + if (_webServer->hasArg(AUTOCONNECT_AUXURI_PARAM)) { String auxUri = _webServer->arg(AUTOCONNECT_AUXURI_PARAM); - auxUri.replace(String("/"), String("/")); + auxUri.replace("/", "/"); AutoConnectAux* aux = _aux.get(); while (aux) { if (aux->_uriStr == auxUri) { diff --git a/src/AutoConnectAux.cpp b/src/AutoConnectAux.cpp index f5a2116..6f355c5 100644 --- a/src/AutoConnectAux.cpp +++ b/src/AutoConnectAux.cpp @@ -263,7 +263,7 @@ const String AutoConnectAux::_injectMenu(PageArgument& args) { const String AutoConnectAux::_indicateUri(PageArgument& args) { AC_UNUSED(args); String lastUri = _uriStr; - lastUri.replace(String("/"), String("/")); + lastUri.replace("/", "/"); return lastUri; } @@ -1118,8 +1118,8 @@ size_t AutoConnectAux::_resultJsonBufferSize() { return -1; } else { - AC_DBG("json buffer size:%d\n", _jbSize + _jbByte + 200); - return static_cast(_jbSize + _jbByte + 200); + AC_DBG("json buffer size:%d\n", _jbSize + _jbByte); + return static_cast(_jbSize + _jbByte); } } diff --git a/src/AutoConnectDefs.h b/src/AutoConnectDefs.h index f564942..cb9ee53 100644 --- a/src/AutoConnectDefs.h +++ b/src/AutoConnectDefs.h @@ -11,7 +11,7 @@ #define _AUTOCONNECTDEFS_H_ // Uncomment the following AC_DEBUG to enable debug output. -#define AC_DEBUG +//#define AC_DEBUG // Debug output destination can be defined externally with AC_DEBUG_PORT #ifndef AC_DEBUG_PORT @@ -22,6 +22,7 @@ #define AC_DBG(...) do {AC_DEBUG_PORT.print("[AC] "); AC_DEBUG_PORT.printf( __VA_ARGS__ );} while (0) #else #define AC_DBG(...) +#define AC_DBG_DUMB(...) #endif // !AC_DEBUG // Indicator to specify that AutoConnectAux handles elements with JSON. diff --git a/src/AutoConnectElement.h b/src/AutoConnectElement.h index e123a9f..f171aee 100644 --- a/src/AutoConnectElement.h +++ b/src/AutoConnectElement.h @@ -22,7 +22,7 @@ using AutoConnectRadio = AutoConnectRadioJson; using AutoConnectSelect = AutoConnectSelectJson; using AutoConnectSubmit = AutoConnectSubmitJson; using AutoConnectText = AutoConnectTextJson; -#define AUTOCONNECT_JSON_BUFFER_SIZE 3000 +#define AUTOCONNECT_JSON_BUFFER_SIZE 512 #else using AutoConnectElement = AutoConnectElementBasis; using AutoConnectButton = AutoConnectButtonBasis; diff --git a/src/AutoConnectElementBasis.h b/src/AutoConnectElementBasis.h index 5e3be3b..7e5ba4a 100644 --- a/src/AutoConnectElementBasis.h +++ b/src/AutoConnectElementBasis.h @@ -3,7 +3,7 @@ * @file AutoConnectElementBasis.h * @author hieromon@gmail.com * @version 0.9.7 - * @date 2018-11-17 + * @date 2018-12-29 * @copyright MIT license. */ @@ -121,23 +121,15 @@ class AutoConnectInputBasis : virtual public AutoConnectElementBasis { class AutoConnectRadioBasis : virtual public AutoConnectElementBasis { public: explicit AutoConnectRadioBasis(const char* name = "", std::vector const& values = {}, const char* label = "", const ACArrange_t order = AC_Vertical, const uint8_t checked = 0) : AutoConnectElementBasis(name, ""), label(label), order(order), checked(checked), _values(values) { - _type = AC_Radio; -// _values = values; -// for (String v : values) { -// add(v); -// const std::string sv = v.c_str(); -// _values.push_back(sv); -// } + _type = AC_Radio; } virtual ~AutoConnectRadioBasis() {} const String toHTML(void) const override; - void add(const String& value) { _values.push_back(value); } - //void add(const String& value) { - // std::string sv = value.c_str(); - // _values.push_back(sv); - //} - void empty(const size_t reserve = 0) { _values.reserve(reserve); _values.clear(); std::vector().swap(_values); } + const String& operator [] (const std::size_t n) const { return at(n); } + void add(const String& value) { _values.push_back(String(value)); } + const String& at(const std::size_t n) const { return _values.at(n); } void check(const String& value); + void empty(const size_t reserve = 0); String label; /**< A label for a subsequent radio buttons */ ACArrange_t order; /**< layout order */ @@ -145,7 +137,6 @@ class AutoConnectRadioBasis : virtual public AutoConnectElementBasis { protected: std::vector _values; /**< Items in a group */ -// std::vector _values; /**< Items in a group */ }; /** @@ -163,8 +154,10 @@ class AutoConnectSelectBasis : virtual public AutoConnectElementBasis { } virtual ~AutoConnectSelectBasis() {} const String toHTML(void) const override; - void add(const String& option) { _options.push_back(option); } - void empty(const size_t reserve = 0) { _options.reserve(reserve); _options.clear(); std::vector().swap(_options); } + const String& operator [] (const std::size_t n) const { return at(n); } + void add(const String& option) { _options.push_back(String(option)); } + const String& at(const std::size_t n) const { return _options.at(n); } + void empty(const size_t reserve = 0); String label; /**< A label for a subsequent input box */ diff --git a/src/AutoConnectElementBasisImpl.h b/src/AutoConnectElementBasisImpl.h index a81172b..fa126c4 100644 --- a/src/AutoConnectElementBasisImpl.h +++ b/src/AutoConnectElementBasisImpl.h @@ -3,7 +3,7 @@ * @file AutoConnectElementImpl.h * @author hieromon@gmail.com * @version 0.9.7 - * @date 2018-11-17 + * @date 2018-12-29 * @copyright MIT license. */ @@ -64,12 +64,38 @@ const String AutoConnectInputBasis::toHTML(void) const { return html; } +/** +* Indicate an entry with the specified value in the value's collection. +* @param value The value to indicates in the collection. +*/ +void AutoConnectRadioBasis::check(const String& value) { + for (std::size_t n = 0; n < _values.size(); n++) { + if (at(n).equalsIgnoreCase(value)) { + checked = n + 1; + break; + } + } +} + +/** + * Clear value items of AutoConnetRadio and reallocate new storage. + * All hold items are released. + * @param reserve If 'reserve' is greater than 0, this function + * allocates new holding storage with the value. + */ +void AutoConnectRadioBasis::empty(const size_t reserve) { + _values.clear(); + std::vector().swap(_values); + if (reserve) + _values.reserve(reserve); +} + /** * Generate an HTML element with an