From 02835d8f4e539931c46b16191a6b38f7c0a4b04e Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 27 May 2023 07:52:44 +0100 Subject: [PATCH] Improve code with `std::unique_ptr` (#2643) * **Memory management improvements** Switch to using `unique_ptr` instead of raw pointers to prevent memory leaks and ease resource management. * **Fix memory leaks in StreamTransformer.cpp** Address memory leaks, enhancing application stability and performance. * **Simplify and improve CommandOutput.cpp** Replace a code segment with a more efficient and straightforward approach. * **Refactor Basic_Audio sample application** Incorporate smart pointers and reorganize some code segments for better code quality and memory safety. --- .../Hosted/Transport/TcpClientTransport.h | 10 +-- .../Arch/Esp8266/Platform/AccessPointImpl.cpp | 39 +++++----- .../Arch/Esp8266/Platform/AccessPointImpl.h | 2 +- .../rboot/include/Network/RbootHttpUpdater.h | 18 ++--- Sming/Components/ssl/Axtls/AxConnection.h | 13 ++-- .../ssl/include/Network/Ssl/Session.h | 16 ++-- Sming/Components/ssl/src/Session.cpp | 43 +++++----- Sming/Core/Data/ObjectMap.h | 23 +++--- .../Core/Data/Stream/EndlessMemoryStream.cpp | 9 +-- Sming/Core/Data/Stream/EndlessMemoryStream.h | 8 +- .../Core/Data/Stream/IFS/DirectoryTemplate.h | 10 +-- Sming/Core/Data/StreamTransformer.cpp | 10 +-- Sming/Core/Data/StreamTransformer.h | 22 +++--- .../src/include/Ota/Network/HttpUpgrader.h | 17 ++-- .../OtaUpgradeMqtt/src/PayloadParser.cpp | 8 +- .../include/OtaUpgrade/Mqtt/PayloadParser.h | 8 +- .../Libraries/WebCam/src/Camera/FakeCamera.h | 33 ++------ Sming/Libraries/Yeelight/.cs | 0 Sming/Libraries/Yeelight/YeelightBulb.cpp | 78 +++++++++---------- .../Libraries/Yeelight/include/YeelightBulb.h | 22 +++--- .../CommandProcessing/CommandExecutor.cpp | 13 +--- .../CommandProcessing/CommandExecutor.h | 4 +- .../CommandProcessing/CommandOutput.cpp | 2 +- .../CommandProcessing/CommandOutput.h | 2 +- samples/Basic_Audio/app/application.cpp | 8 +- samples/Basic_Ota/app/application.cpp | 7 +- .../Basic_Serial/app/SerialTransmitDemo.cpp | 2 +- .../Basic_Serial/include/SerialTransmitDemo.h | 7 +- 28 files changed, 183 insertions(+), 251 deletions(-) create mode 100644 Sming/Libraries/Yeelight/.cs diff --git a/Sming/Components/Hosted/include/Hosted/Transport/TcpClientTransport.h b/Sming/Components/Hosted/include/Hosted/Transport/TcpClientTransport.h index d6cb1a5dca..4ab6e1c9ac 100644 --- a/Sming/Components/Hosted/include/Hosted/Transport/TcpClientTransport.h +++ b/Sming/Components/Hosted/include/Hosted/Transport/TcpClientTransport.h @@ -16,6 +16,7 @@ #include #include "TcpTransport.h" #include "TcpClientStream.h" +#include namespace Hosted { @@ -27,12 +28,7 @@ class TcpClientTransport : public TcpTransport TcpClientTransport(TcpClient& client) { client.setReceiveDelegate(TcpClientDataDelegate(&TcpClientTransport::process, this)); - stream = new TcpClientStream(client); - } - - ~TcpClientTransport() - { - delete stream; + stream.reset(new TcpClientStream(client)); } protected: @@ -46,7 +42,7 @@ class TcpClientTransport : public TcpTransport } private: - TcpClientStream* stream = nullptr; + std::unique_ptr stream; }; } // namespace Transport diff --git a/Sming/Components/Network/Arch/Esp8266/Platform/AccessPointImpl.cpp b/Sming/Components/Network/Arch/Esp8266/Platform/AccessPointImpl.cpp index 2a897c13c9..775dc07f70 100644 --- a/Sming/Components/Network/Arch/Esp8266/Platform/AccessPointImpl.cpp +++ b/Sming/Components/Network/Arch/Esp8266/Platform/AccessPointImpl.cpp @@ -82,11 +82,7 @@ bool AccessPointImpl::config(const String& ssid, String password, AUTH_MODE mode debugf("AP configuration was updated"); } else { debugf("Set AP configuration in background"); - if(runConfig != nullptr) { - delete runConfig; - } - runConfig = new softap_config(); - memcpy(runConfig, &config, sizeof(softap_config)); + runConfig.reset(new softap_config(config)); } } else { debugf("AP configuration loaded"); @@ -190,22 +186,23 @@ std::unique_ptr AccessPointImpl::getStations() const void AccessPointImpl::onSystemReady() { - if(runConfig != nullptr) { - noInterrupts(); - bool enabled = isEnabled(); - enable(true, false); - wifi_softap_dhcps_stop(); - - if(!wifi_softap_set_config(runConfig)) { - debugf("Can't set AP config on system ready event!"); - } else { - debugf("AP configuration was updated on system ready event"); - } - delete runConfig; - runConfig = nullptr; + if(!runConfig) { + return; + } + + noInterrupts(); + bool enabled = isEnabled(); + enable(true, false); + wifi_softap_dhcps_stop(); - wifi_softap_dhcps_start(); - enable(enabled, false); - interrupts(); + if(!wifi_softap_set_config(runConfig.get())) { + debugf("Can't set AP config on system ready event!"); + } else { + debugf("AP configuration was updated on system ready event"); } + runConfig.reset(); + + wifi_softap_dhcps_start(); + enable(enabled, false); + interrupts(); } diff --git a/Sming/Components/Network/Arch/Esp8266/Platform/AccessPointImpl.h b/Sming/Components/Network/Arch/Esp8266/Platform/AccessPointImpl.h index 8ce64e886e..a470795ca3 100644 --- a/Sming/Components/Network/Arch/Esp8266/Platform/AccessPointImpl.h +++ b/Sming/Components/Network/Arch/Esp8266/Platform/AccessPointImpl.h @@ -40,5 +40,5 @@ class AccessPointImpl : public AccessPointClass, protected ISystemReadyHandler void onSystemReady() override; private: - softap_config* runConfig = nullptr; + std::unique_ptr runConfig; }; diff --git a/Sming/Components/rboot/include/Network/RbootHttpUpdater.h b/Sming/Components/rboot/include/Network/RbootHttpUpdater.h index 3816d914b7..c17ba2db7b 100644 --- a/Sming/Components/rboot/include/Network/RbootHttpUpdater.h +++ b/Sming/Components/rboot/include/Network/RbootHttpUpdater.h @@ -33,25 +33,21 @@ class RbootHttpUpdater : protected HttpClient struct Item { String url; uint32_t targetOffset; - size_t size; // << max allowed size - RbootOutputStream* stream{nullptr}; // (optional) output stream to use. + size_t size; // << max allowed size + std::unique_ptr stream; // (optional) output stream to use. Item(String url, uint32_t targetOffset, size_t size, RbootOutputStream* stream) - : url(url), targetOffset(targetOffset), size(size), stream(stream) + : url(url), targetOffset(targetOffset), size(size) { - } - - ~Item() - { - delete stream; + this->stream.reset(stream); } RbootOutputStream* getStream() { - if(stream == nullptr) { - stream = new RbootOutputStream(targetOffset, size); + if(!stream) { + stream.reset(new RbootOutputStream(targetOffset, size)); } - return stream; + return stream.get(); } }; diff --git a/Sming/Components/ssl/Axtls/AxConnection.h b/Sming/Components/ssl/Axtls/AxConnection.h index d3cf7ef279..a73b7aedea 100644 --- a/Sming/Components/ssl/Axtls/AxConnection.h +++ b/Sming/Components/ssl/Axtls/AxConnection.h @@ -16,6 +16,7 @@ #include #include "AxCertificate.h" #include "AxError.h" +#include namespace Ssl { @@ -26,7 +27,6 @@ class AxConnection : public Connection ~AxConnection() { - delete certificate; // Typically sends out closing message ssl_free(ssl); } @@ -60,17 +60,16 @@ class AxConnection : public Connection const Certificate* getCertificate() const override { - if(certificate == nullptr && ssl->x509_ctx != nullptr) { - certificate = new AxCertificate(ssl); + if(!certificate && ssl->x509_ctx != nullptr) { + certificate.reset(new AxCertificate(ssl)); } - return certificate; + return certificate.get(); } void freeCertificate() override { - delete certificate; - certificate = nullptr; + certificate.reset(); } int read(InputBuffer& input, uint8_t*& output) override; @@ -93,7 +92,7 @@ class AxConnection : public Connection private: SSL* ssl{nullptr}; - mutable AxCertificate* certificate{nullptr}; + mutable std::unique_ptr certificate; InputBuffer* input{nullptr}; }; diff --git a/Sming/Components/ssl/include/Network/Ssl/Session.h b/Sming/Components/ssl/include/Network/Ssl/Session.h index efb5c01f8b..4f59127eb8 100644 --- a/Sming/Components/ssl/include/Network/Ssl/Session.h +++ b/Sming/Components/ssl/include/Network/Ssl/Session.h @@ -14,6 +14,7 @@ #include "KeyCertPair.h" #include "ValidatorList.h" #include +#include class TcpConnection; @@ -121,7 +122,6 @@ class Session ~Session() { close(); - delete sessionId; } /** @@ -130,7 +130,7 @@ class Session */ const SessionId* getSessionId() const { - return sessionId; + return sessionId.get(); } /** @@ -147,8 +147,8 @@ class Session */ void setConnection(Connection* connection) { - assert(this->connection == nullptr); - this->connection = connection; + assert(!this->connection); + this->connection.reset(connection); } /** @@ -157,7 +157,7 @@ class Session */ Connection* getConnection() { - return connection; + return connection.get(); } /** @@ -223,9 +223,9 @@ class Session void endHandshake(); private: - Context* context = nullptr; - Connection* connection = nullptr; - SessionId* sessionId = nullptr; + std::unique_ptr context; + std::unique_ptr connection; + std::unique_ptr sessionId; CpuFrequency curFreq = CpuFrequency(0); }; diff --git a/Sming/Components/ssl/src/Session.cpp b/Sming/Components/ssl/src/Session.cpp index aed3f1d1a4..c896799ce5 100644 --- a/Sming/Components/ssl/src/Session.cpp +++ b/Sming/Components/ssl/src/Session.cpp @@ -48,10 +48,10 @@ bool Session::onAccept(TcpConnection* client, tcp_pcb* tcp) return false; } - if(context == nullptr) { + if(!context) { assert(factory != nullptr); - context = factory->createContext(*this); - if(context == nullptr) { + context.reset(factory->createContext(*this)); + if(!context) { return false; } @@ -73,14 +73,14 @@ bool Session::onConnect(tcp_pcb* tcp) { debug_d("SSL %p: Starting connection...", this); - assert(connection == nullptr); - assert(context == nullptr); + assert(!connection); + assert(!context); // Client Session - delete context; + context.reset(); assert(factory != nullptr); - context = factory->createContext(*this); - if(context == nullptr) { + context.reset(factory->createContext(*this)); + if(!context) { return false; } @@ -90,7 +90,7 @@ bool Session::onConnect(tcp_pcb* tcp) return false; } - if(sessionId != nullptr && sessionId->isValid()) { + if(sessionId && sessionId->isValid()) { debug_d("-----BEGIN SSL SESSION PARAMETERS-----"); debug_d("SessionId: %s", toString(*sessionId).c_str()); debug_d("------END SSL SESSION PARAMETERS------"); @@ -98,8 +98,8 @@ bool Session::onConnect(tcp_pcb* tcp) beginHandshake(); - connection = context->createClient(tcp); - if(connection == nullptr) { + connection.reset(context->createClient(tcp)); + if(!connection) { endHandshake(); return false; } @@ -134,11 +134,8 @@ void Session::close() { debug_d("SSL %p: closing ...", this); - delete connection; - connection = nullptr; - - delete context; - context = nullptr; + connection.reset(); + context.reset(); hostName = nullptr; maxBufferSize = MaxBufferSize::Default; @@ -146,7 +143,7 @@ void Session::close() int Session::read(InputBuffer& input, uint8_t*& output) { - if(connection == nullptr) { + if(!connection) { debug_w("SSL: no connection"); return -1; } @@ -165,7 +162,7 @@ int Session::read(InputBuffer& input, uint8_t*& output) int Session::write(const uint8_t* data, size_t length) { - if(connection == nullptr) { + if(!connection) { debug_e("!! SSL Session connection is NULL"); return ERR_CONN; } @@ -181,7 +178,7 @@ int Session::write(const uint8_t* data, size_t length) bool Session::validateCertificate() { - if(connection == nullptr) { + if(!connection) { debug_w("SSL: connection not set, assuming cert. is OK"); return true; } @@ -202,8 +199,8 @@ void Session::handshakeComplete(bool success) if(success) { // If requested, take a copy of the session ID for later re-use if(options.sessionResume) { - if(sessionId == nullptr) { - sessionId = new SessionId; + if(!sessionId) { + sessionId.reset(new SessionId); } *sessionId = connection->getSessionId(); } @@ -211,7 +208,7 @@ void Session::handshakeComplete(bool success) debug_w("SSL Handshake failed"); } - if(options.freeKeyCertAfterHandshake && connection != nullptr) { + if(options.freeKeyCertAfterHandshake && connection) { connection->freeCertificate(); } } @@ -235,7 +232,7 @@ size_t Session::printTo(Print& p) const n += p.println(keyCert.getCertificateLength()); n += p.print(_F(" Cert PK Length: ")); n += p.println(keyCert.getKeyLength()); - if(connection != nullptr) { + if(connection) { n += connection->printTo(p); } diff --git a/Sming/Core/Data/ObjectMap.h b/Sming/Core/Data/ObjectMap.h index f3f6839575..af75a16870 100644 --- a/Sming/Core/Data/ObjectMap.h +++ b/Sming/Core/Data/ObjectMap.h @@ -13,6 +13,7 @@ #pragma once #include "WVector.h" +#include /** * @brief Implementation of a HashMap for owned objects, i.e. anything created with new(). @@ -209,8 +210,7 @@ template class ObjectMap { int i = indexOf(key); if(i >= 0) { - delete entries[i].value; - entries[i].value = value; + entries[i].value.reset(value); } else { entries.addElement(new Entry(key, value)); } @@ -225,7 +225,7 @@ template class ObjectMap V* find(const K& key) const { int index = indexOf(key); - return (index < 0) ? nullptr : entries[index].value; + return (index < 0) ? nullptr : entries[index].value.get(); } /** @@ -298,13 +298,12 @@ template class ObjectMap */ V* extractAt(unsigned index) { - V* value = nullptr; + std::unique_ptr value; if(index < entries.count()) { - value = entries[index].value; - entries[index].value = nullptr; + entries[index].value.swap(value); entries.remove(index); } - return value; + return value.release(); } /** @@ -321,15 +320,11 @@ template class ObjectMap */ struct Entry { K key; - V* value = nullptr; + std::unique_ptr value; - Entry(const K& key, V* value) : key(key), value(value) + Entry(const K& key, V* value) : key(key) { - } - - ~Entry() - { - delete value; + this->value.reset(value); } }; diff --git a/Sming/Core/Data/Stream/EndlessMemoryStream.cpp b/Sming/Core/Data/Stream/EndlessMemoryStream.cpp index bf1b83f693..50eb5e7f8a 100644 --- a/Sming/Core/Data/Stream/EndlessMemoryStream.cpp +++ b/Sming/Core/Data/Stream/EndlessMemoryStream.cpp @@ -12,14 +12,13 @@ bool EndlessMemoryStream::seek(int len) { - if(stream == nullptr) { + if(!stream) { return false; } int res = stream->seek(len); if(stream->isFinished()) { - delete stream; - stream = nullptr; + stream.reset(); } return res; @@ -27,8 +26,8 @@ bool EndlessMemoryStream::seek(int len) size_t EndlessMemoryStream::write(const uint8_t* buffer, size_t size) { - if(stream == nullptr) { - stream = new MemoryDataStream(); + if(!stream) { + stream.reset(new MemoryDataStream()); } return stream->write(buffer, size); diff --git a/Sming/Core/Data/Stream/EndlessMemoryStream.h b/Sming/Core/Data/Stream/EndlessMemoryStream.h index 99443673f3..e0c490c382 100644 --- a/Sming/Core/Data/Stream/EndlessMemoryStream.h +++ b/Sming/Core/Data/Stream/EndlessMemoryStream.h @@ -11,6 +11,7 @@ #pragma once #include "MemoryDataStream.h" +#include /** * @brief Memory stream that stores unlimited number of bytes. @@ -24,11 +25,6 @@ class EndlessMemoryStream : public ReadWriteStream { public: - ~EndlessMemoryStream() - { - delete stream; - } - StreamType getStreamType() const override { return eSST_Memory; @@ -54,5 +50,5 @@ class EndlessMemoryStream : public ReadWriteStream } private: - MemoryDataStream* stream = nullptr; + std::unique_ptr stream; }; diff --git a/Sming/Core/Data/Stream/IFS/DirectoryTemplate.h b/Sming/Core/Data/Stream/IFS/DirectoryTemplate.h index 287c70b422..7786233178 100644 --- a/Sming/Core/Data/Stream/IFS/DirectoryTemplate.h +++ b/Sming/Core/Data/Stream/IFS/DirectoryTemplate.h @@ -49,13 +49,9 @@ class DirectoryTemplate : public SectionTemplate #undef XX }; - DirectoryTemplate(IDataSourceStream* source, Directory* dir) : SectionTemplate(source), directory(dir) + DirectoryTemplate(IDataSourceStream* source, Directory* dir) : SectionTemplate(source) { - } - - ~DirectoryTemplate() - { - delete directory; + directory.reset(dir); } Directory& dir() @@ -76,7 +72,7 @@ class DirectoryTemplate : public SectionTemplate String getValue(const char* name) override; private: - Directory* directory; + std::unique_ptr directory; }; } // namespace IFS diff --git a/Sming/Core/Data/StreamTransformer.cpp b/Sming/Core/Data/StreamTransformer.cpp index 81f1ca1f2a..8014cbfd7c 100644 --- a/Sming/Core/Data/StreamTransformer.cpp +++ b/Sming/Core/Data/StreamTransformer.cpp @@ -21,7 +21,7 @@ uint16_t StreamTransformer::readMemoryBlock(char* data, int bufSize) } if(tempStream == nullptr) { - tempStream = new CircularBuffer(NETWORK_SEND_BUFFER_SIZE + 10); + tempStream.reset(new CircularBuffer(NETWORK_SEND_BUFFER_SIZE + 10)); } // Use provided buffer as a temporary store for this operation @@ -41,13 +41,13 @@ void StreamTransformer::fillTempStream(char* buffer, size_t bufSize) } saveState(); - size_t outLength = transform(reinterpret_cast(buffer), chunkSize, result, resultSize); + size_t outLength = transform(reinterpret_cast(buffer), chunkSize, result.get(), resultSize); if(outLength > room) { restoreState(); return; } - auto written = tempStream->write(result, outLength); + auto written = tempStream->write(result.get(), outLength); (void)written; assert(written == outLength); @@ -55,8 +55,8 @@ void StreamTransformer::fillTempStream(char* buffer, size_t bufSize) } if(sourceStream->isFinished()) { - auto outLength = transform(nullptr, 0, result, resultSize); - auto written = tempStream->write(result, outLength); + auto outLength = transform(nullptr, 0, result.get(), resultSize); + auto written = tempStream->write(result.get(), outLength); (void)written; assert(written == outLength); } diff --git a/Sming/Core/Data/StreamTransformer.h b/Sming/Core/Data/StreamTransformer.h index d8f1178660..48050577ee 100644 --- a/Sming/Core/Data/StreamTransformer.h +++ b/Sming/Core/Data/StreamTransformer.h @@ -13,6 +13,7 @@ #pragma once #include "Buffer/CircularBuffer.h" +#include /** * @brief Class that can be used to transform streams of data on the fly @@ -21,15 +22,10 @@ class StreamTransformer : public IDataSourceStream { public: StreamTransformer(IDataSourceStream* stream, size_t resultSize = 256, size_t blockSize = 64) - : sourceStream(stream), result(new uint8_t[resultSize]), resultSize(resultSize), blockSize(blockSize) + : resultSize(resultSize), blockSize(blockSize) { - } - - ~StreamTransformer() - { - delete[] result; - delete tempStream; - delete sourceStream; + sourceStream.reset(stream); + result.reset(new uint8_t[resultSize]); } //Use base class documentation @@ -49,7 +45,7 @@ class StreamTransformer : public IDataSourceStream bool isValid() const { - return sourceStream != nullptr && sourceStream->isValid(); + return sourceStream && sourceStream->isValid(); } uint16_t readMemoryBlock(char* data, int bufSize) override; @@ -60,7 +56,7 @@ class StreamTransformer : public IDataSourceStream String getName() const override { - return (sourceStream == nullptr) ? nullptr : sourceStream->getName(); + return sourceStream ? sourceStream->getName() : String::nullstr; } /** @@ -89,9 +85,9 @@ class StreamTransformer : public IDataSourceStream private: void fillTempStream(char* buffer, size_t bufSize); - IDataSourceStream* sourceStream{nullptr}; - CircularBuffer* tempStream{nullptr}; - uint8_t* result{nullptr}; + std::unique_ptr sourceStream; + std::unique_ptr tempStream; + std::unique_ptr result; size_t resultSize; size_t blockSize; }; diff --git a/Sming/Libraries/OtaNetwork/src/include/Ota/Network/HttpUpgrader.h b/Sming/Libraries/OtaNetwork/src/include/Ota/Network/HttpUpgrader.h index 9a93aa114f..957a19f148 100644 --- a/Sming/Libraries/OtaNetwork/src/include/Ota/Network/HttpUpgrader.h +++ b/Sming/Libraries/OtaNetwork/src/include/Ota/Network/HttpUpgrader.h @@ -35,25 +35,20 @@ class HttpUpgrader : protected HttpClient struct Item { String url; - Partition partition; // << partition to write the data to - size_t size{0}; // << actual size of written bytes - ReadWriteStream* stream{nullptr}; // (optional) output stream to use. + Partition partition; // << partition to write the data to + size_t size{0}; // << actual size of written bytes + std::unique_ptr stream; // (optional) output stream to use. Item(String url, Partition partition, ReadWriteStream* stream) : url(url), partition(partition), stream(stream) { } - ~Item() - { - delete stream; - } - ReadWriteStream* getStream() { - if(stream == nullptr) { - stream = new Ota::UpgradeOutputStream(partition); + if(!stream) { + stream.reset(new Ota::UpgradeOutputStream(partition)); } - return stream; + return stream.get(); } }; diff --git a/Sming/Libraries/OtaUpgradeMqtt/src/PayloadParser.cpp b/Sming/Libraries/OtaUpgradeMqtt/src/PayloadParser.cpp index 34b695b76b..a88c5cd439 100644 --- a/Sming/Libraries/OtaUpgradeMqtt/src/PayloadParser.cpp +++ b/Sming/Libraries/OtaUpgradeMqtt/src/PayloadParser.cpp @@ -35,7 +35,7 @@ int PayloadParser::parse(MqttPayloadParserState& state, mqtt_message_t* message, } if(length == MQTT_PAYLOAD_PARSER_END) { - bool skip = (updateState->stream == nullptr); + bool skip = !updateState->stream; if(!skip) { bool success = switchRom(*updateState); if(success) { @@ -78,11 +78,11 @@ int PayloadParser::parse(MqttPayloadParserState& state, mqtt_message_t* message, length -= offset; buffer += offset; - updateState->stream = getStorageStream(message->common.length - offset); + updateState->stream.reset(getStorageStream(message->common.length - offset)); } - auto stream = updateState->stream; - if(stream == nullptr) { + auto& stream = updateState->stream; + if(!stream) { return 0; } diff --git a/Sming/Libraries/OtaUpgradeMqtt/src/include/OtaUpgrade/Mqtt/PayloadParser.h b/Sming/Libraries/OtaUpgradeMqtt/src/include/OtaUpgrade/Mqtt/PayloadParser.h index f246e43292..be3b93e8a7 100644 --- a/Sming/Libraries/OtaUpgradeMqtt/src/include/OtaUpgrade/Mqtt/PayloadParser.h +++ b/Sming/Libraries/OtaUpgradeMqtt/src/include/OtaUpgrade/Mqtt/PayloadParser.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace OtaUpgrade { @@ -30,14 +31,9 @@ class PayloadParser { public: struct UpdateState { - ReadWriteStream* stream{nullptr}; + std::unique_ptr stream; bool started{false}; size_t version{0}; - - ~UpdateState() - { - delete stream; - } }; /** diff --git a/Sming/Libraries/WebCam/src/Camera/FakeCamera.h b/Sming/Libraries/WebCam/src/Camera/FakeCamera.h index 2f656398af..eff18f6873 100644 --- a/Sming/Libraries/WebCam/src/Camera/FakeCamera.h +++ b/Sming/Libraries/WebCam/src/Camera/FakeCamera.h @@ -27,15 +27,9 @@ class FakeCamera: public CameraInterface this->files = files; } - ~FakeCamera() - { - delete file; - file = nullptr; - } - const String getMimeType() const override { - return "image/jpeg"; + return toString(MIME_JPEG); } /** @@ -66,14 +60,11 @@ class FakeCamera: public CameraInterface } // go to the next picture. - delete file; - file = new FileStream(files[index++]); + auto& filename = files[index++]; if(index == files.count()) { index = 0; } - if(!file->isValid()) { - delete file; - file = nullptr; + if(!file.open(filename)) { return false; } state = eWCS_HAS_PICTURE; @@ -86,11 +77,7 @@ class FakeCamera: public CameraInterface */ size_t getSize() override { - if(file == nullptr) { - return 0; - } - - return file->getSize(); + return file.getSize(); } /** @@ -103,17 +90,13 @@ class FakeCamera: public CameraInterface */ size_t read(char* buffer, size_t size, size_t offset = 0) { - if(file == nullptr) { - return 0; - } - // get the current picture and read the desired data from it. - file->seekFrom(offset, SeekOrigin::Start); - return file->readMemoryBlock(buffer, size); + file.seekFrom(offset, SeekOrigin::Start); + return file.readMemoryBlock(buffer, size); } private: - size_t index = 0; - FileStream* file = nullptr; + size_t index{0}; + FileStream file; Vector files; }; diff --git a/Sming/Libraries/Yeelight/.cs b/Sming/Libraries/Yeelight/.cs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Sming/Libraries/Yeelight/YeelightBulb.cpp b/Sming/Libraries/Yeelight/YeelightBulb.cpp index f7aad50860..b7d23e77a0 100644 --- a/Sming/Libraries/Yeelight/YeelightBulb.cpp +++ b/Sming/Libraries/Yeelight/YeelightBulb.cpp @@ -11,40 +11,34 @@ #include #include "WCharacter.h" +namespace +{ +bool isNumeric(const String& str) +{ + for(auto c : str) { + if(!isDigit(c)) + return false; + } + return true; +} + +} // namespace + YeelightBulb::~YeelightBulb() { - if (connection != nullptr) - delete connection; - connection = nullptr; } bool YeelightBulb::connect() { - if (connection != nullptr) - { - if (connection->isProcessing()) - return true; - - //connection->close(); - delete connection; + if(connection && connection->isProcessing()) { + return true; } - connection = new TcpClient(TcpClientDataDelegate(&YeelightBulb::onResponse, this)); + connection.reset(new TcpClient(TcpClientDataDelegate(&YeelightBulb::onResponse, this))); connection->setTimeOut(USHRT_MAX); // Stay connected forever - bool result = connection->connect(lamp, port); - //if (result) updateState(); - return result; -} -bool isNumeric(String str) -{ - for (unsigned i = 0; i < str.length(); i++) - { - if (!isDigit(str[i])) - return false; - } - return true; + return connection->connect(lamp, port); } void YeelightBulb::sendCommand(const String& method, const Vector& params) @@ -55,12 +49,12 @@ void YeelightBulb::sendCommand(const String& method, const Vector& param doc["id"] = requestId++; doc["method"] = method; auto arr = doc.createNestedArray("params"); - for (unsigned i = 0; i < params.count(); i++) - { - if (isNumeric(params[i])) + for(unsigned i = 0; i < params.count(); i++) { + if(isNumeric(params[i])) { arr.add(params[i].toInt()); - else + } else { arr.add(params[i]); + } } String request = Json::serialize(doc); request += "\r\n"; @@ -87,10 +81,11 @@ void YeelightBulb::off() void YeelightBulb::setState(bool isOn) { - if (isOn) + if(isOn) { on(); - else + } else { off(); + } } void YeelightBulb::updateState() @@ -114,7 +109,7 @@ void YeelightBulb::setRGB(byte r, byte g, byte b) { ensureOn(); Vector params; - long val = (long)r*65536 + (long)g*256 + b; + uint32_t val = (r << 16) | (g << 8) | b; params.add(String(val)); sendCommand("set_rgb", params); } @@ -130,16 +125,18 @@ void YeelightBulb::setHSV(int hue, int sat) void YeelightBulb::ensureOn() { - if (state <= 0) + if(state <= 0) { on(); + } } void YeelightBulb::parsePower(const String& value) { - if (value == "on") + if(value == "on") { state = eYBS_On; - else if (value == "off") + } else if(value == "off") { state = eYBS_Off; + } debugf("LED state: %s", value.c_str()); } @@ -150,19 +147,17 @@ bool YeelightBulb::onResponse(TcpClient& client, char* data, int size) debugf("LED > %s", source.c_str()); unsigned p = 0; - while (p < source.length()) - { + while(p < source.length()) { int p2 = source.indexOf("\r\n", p); - if (p2 < 0) + if(p2 < 0) { p2 = source.length(); + } String buf = source.substring(p, p2); p = unsigned(p2) + 2; DynamicJsonDocument doc(1024); - if(Json::deserialize(doc, buf)) - { + if(Json::deserialize(doc, buf)) { long id = doc["id"] | -1; - if (id == propsId) - { + if(id == propsId) { JsonArray result = doc["result"]; const char* value = result[0]; if(value != nullptr) { @@ -172,8 +167,7 @@ bool YeelightBulb::onResponse(TcpClient& client, char* data, int size) const char* method = doc["method"]; debugf("LED method %s received", method); - if (strcmp(method,"props") == 0) - { + if(strcmp(method, "props") == 0) { JsonObject result = doc["params"]; const char* value = result["power"]; if(value != nullptr) { diff --git a/Sming/Libraries/Yeelight/include/YeelightBulb.h b/Sming/Libraries/Yeelight/include/YeelightBulb.h index 11fff0095b..99a2064809 100644 --- a/Sming/Libraries/Yeelight/include/YeelightBulb.h +++ b/Sming/Libraries/Yeelight/include/YeelightBulb.h @@ -6,16 +6,17 @@ ****/ #pragma once -#include "WVector.h" -#include "WString.h" -#include "IpAddress.h" +#include +#include +#include +#include + class TcpClient; -enum YeelightBulbState -{ +enum YeelightBulbState { eYBS_Unknown = -1, eYBS_Off = 0, - eYBS_On = 1 + eYBS_On = 1, }; /** @brief Yeelight wifi bulb controller class @@ -46,7 +47,10 @@ class YeelightBulb void updateState(); /** @brief Get current lamp state (should be called only after updateState) */ - YeelightBulbState currentState() { return state; } + YeelightBulbState currentState() + { + return state; + } void setBrightness(int percent); void setRGB(byte r, byte g, byte b); @@ -54,14 +58,14 @@ class YeelightBulb protected: void ensureOn(); - bool onResponse(TcpClient& client, char *data, int size); + bool onResponse(TcpClient& client, char* data, int size); void parsePower(const String& resp); private: IpAddress lamp; uint16_t port = 55443; - TcpClient* connection = nullptr; + std::unique_ptr connection; long requestId = 0; long propsId = 0; YeelightBulbState state = eYBS_Unknown; diff --git a/Sming/Services/CommandProcessing/CommandExecutor.cpp b/Sming/Services/CommandProcessing/CommandExecutor.cpp index c42dae5e45..4cb49e78ce 100644 --- a/Sming/Services/CommandProcessing/CommandExecutor.cpp +++ b/Sming/Services/CommandProcessing/CommandExecutor.cpp @@ -16,7 +16,7 @@ CommandExecutor::CommandExecutor() CommandExecutor::CommandExecutor(Stream* reqStream) : CommandExecutor() { - commandOutput = new CommandOutput(reqStream); + commandOutput.reset(new CommandOutput(reqStream)); if(commandHandler.getVerboseMode() != SILENT) { commandOutput->println(_F("Welcome to the Stream Command executor")); } @@ -25,7 +25,7 @@ CommandExecutor::CommandExecutor(Stream* reqStream) : CommandExecutor() #ifndef DISABLE_NETWORK CommandExecutor::CommandExecutor(TcpClient* cmdClient) : CommandExecutor() { - commandOutput = new CommandOutput(cmdClient); + commandOutput.reset(new CommandOutput(cmdClient)); if(commandHandler.getVerboseMode() != SILENT) { commandOutput->println(_F("Welcome to the Tcp Command executor")); } @@ -33,18 +33,13 @@ CommandExecutor::CommandExecutor(TcpClient* cmdClient) : CommandExecutor() CommandExecutor::CommandExecutor(WebsocketConnection* reqSocket) { - commandOutput = new CommandOutput(reqSocket); + commandOutput.reset(new CommandOutput(reqSocket)); if(commandHandler.getVerboseMode() != SILENT) { reqSocket->sendString(_F("Welcome to the Websocket Command Executor")); } } #endif -CommandExecutor::~CommandExecutor() -{ - delete commandOutput; -} - int CommandExecutor::executorReceive(char* recvData, int recvSize) { int receiveReturn = 0; @@ -117,7 +112,7 @@ void CommandExecutor::processCommandLine(const String& cmdString) commandOutput->print(cmdCommand); commandOutput->println('\''); } else { - cmdDelegate.commandFunction(cmdString, commandOutput); + cmdDelegate.commandFunction(cmdString, commandOutput.get()); } } diff --git a/Sming/Services/CommandProcessing/CommandExecutor.h b/Sming/Services/CommandProcessing/CommandExecutor.h index 2e74f548ba..a04ac0e6c4 100644 --- a/Sming/Services/CommandProcessing/CommandExecutor.h +++ b/Sming/Services/CommandProcessing/CommandExecutor.h @@ -10,6 +10,7 @@ #include "CommandHandler.h" #include "CommandOutput.h" #include +#include #ifndef DISABLE_NETWORK #include @@ -28,7 +29,6 @@ class CommandExecutor CommandExecutor(WebsocketConnection* reqSocket); #endif CommandExecutor(Stream* reqStream); - ~CommandExecutor(); int executorReceive(char* recvData, int recvSize); int executorReceive(char recvChar); @@ -39,5 +39,5 @@ class CommandExecutor CommandExecutor(); void processCommandLine(const String& cmdString); LineBuffer commandBuf; - CommandOutput* commandOutput = nullptr; + std::unique_ptr commandOutput; }; diff --git a/Sming/Services/CommandProcessing/CommandOutput.cpp b/Sming/Services/CommandProcessing/CommandOutput.cpp index 604ce4a3ed..a8bf385103 100644 --- a/Sming/Services/CommandProcessing/CommandOutput.cpp +++ b/Sming/Services/CommandProcessing/CommandOutput.cpp @@ -33,7 +33,7 @@ size_t CommandOutput::write(uint8_t outChar) outputSocket->sendString(tempSocket); tempSocket = ""; } else { - tempSocket = tempSocket + String(char(outChar)); + tempSocket += char(outChar); } return 1; diff --git a/Sming/Services/CommandProcessing/CommandOutput.h b/Sming/Services/CommandProcessing/CommandOutput.h index 774c672e7e..9ae25228e0 100644 --- a/Sming/Services/CommandProcessing/CommandOutput.h +++ b/Sming/Services/CommandProcessing/CommandOutput.h @@ -30,7 +30,7 @@ class CommandOutput : public Print #endif CommandOutput(Stream* reqStream); - virtual ~CommandOutput(); + ~CommandOutput(); size_t write(uint8_t outChar); diff --git a/samples/Basic_Audio/app/application.cpp b/samples/Basic_Audio/app/application.cpp index 695b236d38..d0a2f3e1be 100644 --- a/samples/Basic_Audio/app/application.cpp +++ b/samples/Basic_Audio/app/application.cpp @@ -41,13 +41,13 @@ static constexpr unsigned statusIntervalMs = 5000; // One full sine-wave cycle static struct { - uint16_t* samples = nullptr; + std::unique_ptr samples; unsigned sampleCount = 0; unsigned readPos = 0; bool generate(float sampleRate, float frequency) { - delete samples; + samples.reset(); readPos = 0; sampleCount = round(sampleRate / frequency); @@ -57,8 +57,8 @@ static struct { Serial << _F("Generating sine wave table @ ") << frequency << _F(" Hz, ") << sampleCount << _F(" samples") << endl; - samples = new uint16_t[sampleCount]; - if(samples == nullptr) { + samples.reset(new uint16_t[sampleCount]); + if(!samples) { debug_e("Memory allocation failed"); return false; } diff --git a/samples/Basic_Ota/app/application.cpp b/samples/Basic_Ota/app/application.cpp index 53e8a3a0b0..8b446c70b6 100644 --- a/samples/Basic_Ota/app/application.cpp +++ b/samples/Basic_Ota/app/application.cpp @@ -10,7 +10,7 @@ #define WIFI_PWD "PleaseEnterPass" #endif -Ota::Network::HttpUpgrader* otaUpdater; +std::unique_ptr otaUpdater; Storage::Partition spiffsPartition; OtaUpgrader ota; @@ -49,10 +49,7 @@ void doUpgrade() Serial.println(F("Updating...")); // need a clean object, otherwise if run before and failed will not run again - if(otaUpdater) { - delete otaUpdater; - } - otaUpdater = new Ota::Network::HttpUpgrader(); + otaUpdater.reset(new Ota::Network::HttpUpgrader); // select rom slot to flash auto part = ota.getNextBootPartition(); diff --git a/samples/Basic_Serial/app/SerialTransmitDemo.cpp b/samples/Basic_Serial/app/SerialTransmitDemo.cpp index f3186556ac..f4bf25eac6 100644 --- a/samples/Basic_Serial/app/SerialTransmitDemo.cpp +++ b/samples/Basic_Serial/app/SerialTransmitDemo.cpp @@ -6,7 +6,7 @@ void SerialTransmitDemo::sendDataChunk() { - if(serial.copyFrom(stream, chunkSize) == 0) { + if(serial.copyFrom(stream.get(), chunkSize) == 0) { Serial.println(_F("Finished sending stream to serial port")); // All done, delete ourselves diff --git a/samples/Basic_Serial/include/SerialTransmitDemo.h b/samples/Basic_Serial/include/SerialTransmitDemo.h index c3b626e6e2..2e9d032cb7 100644 --- a/samples/Basic_Serial/include/SerialTransmitDemo.h +++ b/samples/Basic_Serial/include/SerialTransmitDemo.h @@ -3,12 +3,14 @@ #include #include +#include class SerialTransmitDemo { public: - SerialTransmitDemo(HardwareSerial& serial, IDataSourceStream* stream) : serial(serial), stream(stream) + SerialTransmitDemo(HardwareSerial& serial, IDataSourceStream* stream) : serial(serial) { + this->stream.reset(stream); serial.onTransmitComplete(TransmitCompleteDelegate(&SerialTransmitDemo::onTransmitComplete, this)); } @@ -16,7 +18,6 @@ class SerialTransmitDemo { // Disconnect callback from serial port serial.onTransmitComplete(nullptr); - delete stream; } void begin() @@ -35,7 +36,7 @@ class SerialTransmitDemo private: HardwareSerial& serial; - IDataSourceStream* stream = nullptr; + std::unique_ptr stream; const size_t chunkSize = 32; };