diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 4b14c25..1d165c7 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -140,8 +140,6 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() :_data(nullptr) ,_len(0) - ,_lock(false) - ,_count(0) { } @@ -149,106 +147,36 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t * data, size_t size) :_data(nullptr) ,_len(size) - ,_lock(false) - ,_count(0) { + if (!data) + return; - if (!data) { - return; - } - - _data = new uint8_t[_len + 1]; - - if (_data) { - // Serial.println("BUFF alloc"); - memcpy(_data, data, _len); + _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); + memcpy(_data.get(), data, _len); _data[_len] = 0; - } } AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) :_data(nullptr) ,_len(size) - ,_lock(false) - ,_count(0) { - _data = new uint8_t[_len + 1]; - - if (_data) { - // Serial.println("BUFF alloc"); + _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); _data[_len] = 0; - } - -} - -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer & copy) - :_data(nullptr) - ,_len(0) - ,_lock(false) - ,_count(0) -{ - _len = copy._len; - _lock = copy._lock; - _count = 0; - - if (_len) { - _data = new uint8_t[_len + 1]; - _data[_len] = 0; - } - - if (_data) { - // Serial.println("BUFF alloc"); - memcpy(_data, copy._data, _len); - _data[_len] = 0; - } - -} - -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer && copy) - :_data(nullptr) - ,_len(0) - ,_lock(false) - ,_count(0) -{ - _len = copy._len; - _lock = copy._lock; - _count = 0; - - if (copy._data) { - // Serial.println("BUFF alloc"); - _data = copy._data; - copy._data = nullptr; - } - } AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() { - if (_data) { - // Serial.println("BUFF free"); - delete[] _data; - } } bool AsyncWebSocketMessageBuffer::reserve(size_t size) { _len = size; - if (_data) { - delete[] _data; - _data = nullptr; - } - - _data = new uint8_t[_len + 1]; - - if (_data) { - _data[_len] = 0; - return true; - } else { - return false; - } + _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); + _data[_len] = 0; + return true; } @@ -416,7 +344,7 @@ AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { */ -AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) +AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(std::shared_ptr buffer, uint8_t opcode, bool mask) :_len(0) ,_sent(0) ,_ack(0) @@ -428,8 +356,6 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff if (buffer) { _WSbuffer = buffer; - (*_WSbuffer)++; - // Serial.printf("INC WSbuffer == %u\n", _WSbuffer->count()); _data = buffer->get(); _len = buffer->length(); _status = WS_MSG_SENDING; @@ -443,10 +369,6 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { - if (_WSbuffer) { - (*_WSbuffer)--; // decreases the counter. - // Serial.printf("DEC WSbuffer == %u\n", _WSbuffer->count()); - } } void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) { @@ -680,7 +602,7 @@ void AsyncWebSocketClient::_queueMessage(const char *data, size_t len, uint8_t o _runQueue(); } -void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) +void AsyncWebSocketClient::_queueMessage(std::shared_ptr buffer, uint8_t opcode, bool mask) { if(_status != WS_CONNECTED) return; @@ -922,49 +844,56 @@ void AsyncWebSocketClient::text(const String &message){ void AsyncWebSocketClient::text(const __FlashStringHelper *data){ text(String(data)); } -void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocketClient::text(std::shared_ptr buffer) { - _queueMessage(buffer); + _queueMessage(buffer); } -void AsyncWebSocketClient::binary(const char * message, size_t len){ - _queueMessage(message, len, WS_BINARY); -} -void AsyncWebSocketClient::binary(const char * message){ - binary(message, strlen(message)); -} -void AsyncWebSocketClient::binary(uint8_t * message, size_t len){ - binary((const char *)message, len); -} -void AsyncWebSocketClient::binary(char * message){ - binary(message, strlen(message)); -} -void AsyncWebSocketClient::binary(const String &message){ - binary(message.c_str(), message.length()); -} -void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len){ - PGM_P p = reinterpret_cast(data); - char * message = (char*) malloc(len); - if(message){ - memcpy_P(message, p, len); - binary(message, len); - free(message); - } - -} -void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocketClient::binary(const char * message, size_t len) { - _queueMessage(buffer, WS_BINARY); + _queueMessage(message, len, WS_BINARY); +} +void AsyncWebSocketClient::binary(const char * message) +{ + binary(message, strlen(message)); +} +void AsyncWebSocketClient::binary(uint8_t * message, size_t len) +{ + binary((const char *)message, len); +} +void AsyncWebSocketClient::binary(char * message) +{ + binary(message, strlen(message)); +} +void AsyncWebSocketClient::binary(const String &message) +{ + binary(message.c_str(), message.length()); +} +void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) +{ + PGM_P p = reinterpret_cast(data); + char * message = (char*) malloc(len); + if(message) { + memcpy_P(message, p, len); + binary(message, len); + free(message); + } +} +void AsyncWebSocketClient::binary(std::shared_ptr buffer) +{ + _queueMessage(buffer, WS_BINARY); } -IPAddress AsyncWebSocketClient::remoteIP() const { - if(!_client) { +IPAddress AsyncWebSocketClient::remoteIP() const +{ + if (!_client) { return IPAddress(0U); } return _client->remoteIP(); } -uint16_t AsyncWebSocketClient::remotePort() const { +uint16_t AsyncWebSocketClient::remotePort() const +{ if(!_client) { return 0; } @@ -1041,8 +970,10 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){ c->close(code, message); } -void AsyncWebSocket::closeAll(uint16_t code, const char * message){ - for(auto& c: _clients){ +void AsyncWebSocket::closeAll(uint16_t code, const char * message) +{ + for(auto& c: _clients) + { if(c.status() == WS_CONNECTED) c.close(code, message); } @@ -1055,72 +986,68 @@ void AsyncWebSocket::cleanupClients(uint16_t maxClients) } } -void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){ +void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len) +{ AsyncWebSocketClient * c = client(id); if(c) c->ping(data, len); } -void AsyncWebSocket::pingAll(uint8_t *data, size_t len){ +void AsyncWebSocket::pingAll(uint8_t *data, size_t len) +{ for(auto& c: _clients){ if(c.status() == WS_CONNECTED) c.ping(data, len); } } -void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){ +void AsyncWebSocket::text(uint32_t id, const char * message, size_t len) +{ AsyncWebSocketClient *c = client(id); if(c) c->text(message, len); } -void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocket::textAll(std::shared_ptr buffer) { if (!buffer) return; - buffer->lock(); - for(auto &c : _clients) if (c.status() == WS_CONNECTED) c.text(buffer); - buffer->unlock(); - _cleanBuffers(); } -void AsyncWebSocket::textAll(const char * message, size_t len){ - //if (_buffers.length()) return; - AsyncWebSocketMessageBuffer * WSBuffer = makeBuffer((uint8_t *)message, len); +void AsyncWebSocket::textAll(const char * message, size_t len) +{ + std::shared_ptr WSBuffer = makeBuffer((uint8_t *)message, len); textAll(WSBuffer); } -void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len){ - AsyncWebSocketClient * c = client(id); - if(c) - c->binary(message, len); +void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len) +{ + AsyncWebSocketClient * c = client(id); + if(c) + c->binary(message, len); } void AsyncWebSocket::binaryAll(const char * message, size_t len){ - AsyncWebSocketMessageBuffer * buffer = makeBuffer((uint8_t *)message, len); + std::shared_ptr buffer = makeBuffer((uint8_t *)message, len); binaryAll(buffer); } -void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocket::binaryAll(std::shared_ptr buffer) { if (!buffer) return; - buffer->lock(); - for (auto &c : _clients) if (c.status() == WS_CONNECTED) c.binary(buffer); - buffer->unlock(); - _cleanBuffers(); } @@ -1131,18 +1058,19 @@ void AsyncWebSocket::message(uint32_t id, const char *data, size_t len, uint8_t c->message(data, len, opcode, mask); } -void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) +void AsyncWebSocket::message(uint32_t id, std::shared_ptr buffer, uint8_t opcode, bool mask) { AsyncWebSocketClient *c = client(id); if (c) c->message(buffer, opcode, mask); } -void AsyncWebSocket::messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask){ - for (auto &c : _clients){ +void AsyncWebSocket::messageAll(std::shared_ptr buffer, uint8_t opcode, bool mask) +{ + for (auto &c : _clients) if (c.status() == WS_CONNECTED) c.message(buffer, opcode, mask); - } + _cleanBuffers(); } @@ -1158,28 +1086,26 @@ size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){ return 0; } -size_t AsyncWebSocket::printfAll(const char *format, ...) { - va_list arg; - char* temp = new char[MAX_PRINTF_LEN]; - if(!temp){ - return 0; - } - va_start(arg, format); - size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); - va_end(arg); - delete[] temp; +size_t AsyncWebSocket::printfAll(const char *format, ...) +{ + va_list arg; + char* temp = new char[MAX_PRINTF_LEN]; + if(!temp){ + return 0; + } + va_start(arg, format); + size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); + va_end(arg); + delete[] temp; - AsyncWebSocketMessageBuffer * buffer = makeBuffer(len); - if (!buffer) { - return 0; - } + std::shared_ptr buffer = makeBuffer(len); - va_start(arg, format); - vsnprintf( (char *)buffer->get(), len + 1, format, arg); - va_end(arg); + va_start(arg, format); + vsnprintf( (char *)buffer->get(), len + 1, format, arg); + va_end(arg); - textAll(buffer); - return len; + textAll(buffer); + return len; } #ifndef ESP32 @@ -1197,99 +1123,115 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...){ #endif size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { - va_list arg; - char* temp = new char[MAX_PRINTF_LEN]; - if(!temp){ - return 0; - } - va_start(arg, formatP); - size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); - va_end(arg); - delete[] temp; + va_list arg; + char* temp = new char[MAX_PRINTF_LEN]; + if(!temp){ + return 0; + } + va_start(arg, formatP); + size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); + va_end(arg); + delete[] temp; - AsyncWebSocketMessageBuffer * buffer = makeBuffer(len + 1); - if (!buffer) { - return 0; - } + std::shared_ptr buffer = makeBuffer(len + 1); - va_start(arg, formatP); - vsnprintf_P((char *)buffer->get(), len + 1, formatP, arg); - va_end(arg); + va_start(arg, formatP); + vsnprintf_P((char *)buffer->get(), len + 1, formatP, arg); + va_end(arg); - textAll(buffer); - return len; + textAll(buffer); + return len; } -void AsyncWebSocket::text(uint32_t id, const char * message){ - text(id, message, strlen(message)); +void AsyncWebSocket::text(uint32_t id, const char * message) +{ + text(id, message, strlen(message)); } -void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len){ - text(id, (const char *)message, len); +void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len) +{ + text(id, (const char *)message, len); } -void AsyncWebSocket::text(uint32_t id, char * message){ - text(id, message, strlen(message)); +void AsyncWebSocket::text(uint32_t id, char * message) +{ + text(id, message, strlen(message)); } -void AsyncWebSocket::text(uint32_t id, const String &message){ - text(id, message.c_str(), message.length()); +void AsyncWebSocket::text(uint32_t id, const String &message) +{ + text(id, message.c_str(), message.length()); } -void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message){ - AsyncWebSocketClient * c = client(id); - if(c != NULL) - c->text(message); +void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message) +{ + AsyncWebSocketClient * c = client(id); + if(c != NULL) + c->text(message); } -void AsyncWebSocket::textAll(const char * message){ - textAll(message, strlen(message)); +void AsyncWebSocket::textAll(const char * message) +{ + textAll(message, strlen(message)); } -void AsyncWebSocket::textAll(uint8_t * message, size_t len){ - textAll((const char *)message, len); +void AsyncWebSocket::textAll(uint8_t * message, size_t len) +{ + textAll((const char *)message, len); } -void AsyncWebSocket::textAll(char * message){ - textAll(message, strlen(message)); +void AsyncWebSocket::textAll(char * message) +{ + textAll(message, strlen(message)); } -void AsyncWebSocket::textAll(const String &message){ - textAll(message.c_str(), message.length()); +void AsyncWebSocket::textAll(const String &message) +{ + textAll(message.c_str(), message.length()); } -void AsyncWebSocket::textAll(const __FlashStringHelper *message){ - for(auto& c: _clients){ - if(c.status() == WS_CONNECTED) - c.text(message); - } +void AsyncWebSocket::textAll(const __FlashStringHelper *message) +{ + for (auto& c : _clients) + if (c.status() == WS_CONNECTED) + c.text(message); } -void AsyncWebSocket::binary(uint32_t id, const char * message){ - binary(id, message, strlen(message)); +void AsyncWebSocket::binary(uint32_t id, const char * message) +{ + binary(id, message, strlen(message)); } -void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len){ - binary(id, (const char *)message, len); +void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len) +{ + binary(id, (const char *)message, len); } -void AsyncWebSocket::binary(uint32_t id, char * message){ - binary(id, message, strlen(message)); +void AsyncWebSocket::binary(uint32_t id, char * message) +{ + binary(id, message, strlen(message)); } -void AsyncWebSocket::binary(uint32_t id, const String &message){ - binary(id, message.c_str(), message.length()); +void AsyncWebSocket::binary(uint32_t id, const String &message) +{ + binary(id, message.c_str(), message.length()); } -void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len){ - AsyncWebSocketClient * c = client(id); - if(c != NULL) - c-> binary(message, len); +void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len) +{ + AsyncWebSocketClient * c = client(id); + if (c != NULL) + c-> binary(message, len); } -void AsyncWebSocket::binaryAll(const char * message){ - binaryAll(message, strlen(message)); +void AsyncWebSocket::binaryAll(const char * message) +{ + binaryAll(message, strlen(message)); } -void AsyncWebSocket::binaryAll(uint8_t * message, size_t len){ - binaryAll((const char *)message, len); +void AsyncWebSocket::binaryAll(uint8_t * message, size_t len) +{ + binaryAll((const char *)message, len); } -void AsyncWebSocket::binaryAll(char * message){ - binaryAll(message, strlen(message)); +void AsyncWebSocket::binaryAll(char * message) +{ + binaryAll(message, strlen(message)); } -void AsyncWebSocket::binaryAll(const String &message){ - binaryAll(message.c_str(), message.length()); +void AsyncWebSocket::binaryAll(const String &message) +{ + binaryAll(message.c_str(), message.length()); +} +void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len) +{ + for (auto& c : _clients) { + if (c.status() == WS_CONNECTED) + c.binary(message, len); + } } -void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){ - for(auto& c: _clients){ - if(c.status() == WS_CONNECTED) - c.binary(message, len); - } - } const char __WS_STR_CONNECTION[] PROGMEM = { "Connection" }; const char __WS_STR_UPGRADE[] PROGMEM = { "Upgrade" }; @@ -1312,76 +1254,73 @@ const char __WS_STR_UUID[] PROGMEM = { "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" }; #define WS_STR_UUID FPSTR(__WS_STR_UUID) bool AsyncWebSocket::canHandle(AsyncWebServerRequest *request){ - if(!_enabled) - return false; + if(!_enabled) + return false; - if(request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS)) - return false; + if(request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS)) + return false; - request->addInterestingHeader(WS_STR_CONNECTION); - request->addInterestingHeader(WS_STR_UPGRADE); - request->addInterestingHeader(WS_STR_ORIGIN); - request->addInterestingHeader(WS_STR_COOKIE); - request->addInterestingHeader(WS_STR_VERSION); - request->addInterestingHeader(WS_STR_KEY); - request->addInterestingHeader(WS_STR_PROTOCOL); - return true; + request->addInterestingHeader(WS_STR_CONNECTION); + request->addInterestingHeader(WS_STR_UPGRADE); + request->addInterestingHeader(WS_STR_ORIGIN); + request->addInterestingHeader(WS_STR_COOKIE); + request->addInterestingHeader(WS_STR_VERSION); + request->addInterestingHeader(WS_STR_KEY); + request->addInterestingHeader(WS_STR_PROTOCOL); + return true; } -void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){ - if(!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){ - request->send(400); - return; - } - if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())){ - return request->requestAuthentication(); - } -////////////////////////////////////////// - if(_handshakeHandler != nullptr){ - if(!_handshakeHandler(request)){ - request->send(401); - return; - } - } -////////////////////////////////////////// - AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); - if(version->value().toInt() != 13){ - AsyncWebServerResponse *response = request->beginResponse(400); - response->addHeader(WS_STR_VERSION, F("13")); - request->send(response); - return; - } - AsyncWebHeader* key = request->getHeader(WS_STR_KEY); - AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this); - if(request->hasHeader(WS_STR_PROTOCOL)){ - AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); - //ToDo: check protocol - response->addHeader(WS_STR_PROTOCOL, protocol->value()); - } - request->send(response); -} - -AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(size_t size) +void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) { - AsyncWebSocketMessageBuffer * buffer{}; + if (!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){ + request->send(400); + return; + } + if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())){ + return request->requestAuthentication(); + } + if (_handshakeHandler != nullptr){ + if(!_handshakeHandler(request)){ + request->send(401); + return; + } + } + AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); + if (version->value().toInt() != 13){ + AsyncWebServerResponse *response = request->beginResponse(400); + response->addHeader(WS_STR_VERSION, F("13")); + request->send(response); + return; + } + AsyncWebHeader* key = request->getHeader(WS_STR_KEY); + AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this); + if (request->hasHeader(WS_STR_PROTOCOL)){ + AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); + //ToDo: check protocol + response->addHeader(WS_STR_PROTOCOL, protocol->value()); + } + request->send(response); +} + +std::shared_ptr AsyncWebSocket::makeBuffer(size_t size) +{ + std::shared_ptr buffer = std::make_shared(size); { AsyncWebLockGuard l(_lock); - _buffers.emplace_back(size); - buffer = &_buffers.back(); + _buffers.emplace_back(buffer); } return buffer; } -AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) +std::shared_ptr AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) { - AsyncWebSocketMessageBuffer * buffer{}; + std::shared_ptr buffer = std::make_shared(data, size); { AsyncWebLockGuard l(_lock); - _buffers.emplace_back(data, size); - buffer = &_buffers.back(); + _buffers.emplace_back(buffer); } return buffer; @@ -1390,12 +1329,11 @@ AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(uint8_t * data, size_t s void AsyncWebSocket::_cleanBuffers() { AsyncWebLockGuard l(_lock); - for (auto iter = std::begin(_buffers); iter != std::end(_buffers);){ - if(iter->canDelete()){ - iter = _buffers.erase(iter); - } else + if(iter->lock()) iter++; + else + iter = _buffers.erase(iter); } } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 30a8cf6..3d24e23 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -35,6 +35,7 @@ #include #include +#include #ifdef ESP8266 #include @@ -85,30 +86,17 @@ typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_ class AsyncWebSocketMessageBuffer { private: - uint8_t * _data; - size_t _len; - bool _lock; - uint32_t _count; + std::unique_ptr _data; + size_t _len{}; public: AsyncWebSocketMessageBuffer(); AsyncWebSocketMessageBuffer(size_t size); - AsyncWebSocketMessageBuffer(uint8_t * data, size_t size); - AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &); - AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&); + AsyncWebSocketMessageBuffer(uint8_t *data, size_t size); ~AsyncWebSocketMessageBuffer(); - void operator ++(int i) { (void)i; _count++; } - void operator --(int i) { (void)i; if (_count > 0) { _count--; } ; } bool reserve(size_t size); - void lock() { _lock = true; } - void unlock() { _lock = false; } - uint8_t * get() { return _data; } + uint8_t *get() { return _data.get(); } size_t length() { return _len; } - uint32_t count() { return _count; } - bool canDelete() { return (!_count && !_lock); } - - friend AsyncWebSocket; - }; class AsyncWebSocketMessage { @@ -148,9 +136,9 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage { size_t _sent; size_t _ack; size_t _acked; - AsyncWebSocketMessageBuffer *_WSbuffer; + std::shared_ptr _WSbuffer; public: - AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false); + AsyncWebSocketMultiMessage(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); virtual ~AsyncWebSocketMultiMessage() override; virtual bool betweenFrames() const override { return _acked == _ack; } virtual void ack(size_t len, uint32_t time) override ; @@ -178,7 +166,7 @@ public: new (&basicMessage) AsyncWebSocketBasicMessage{data, len, opcode, mask}; } - PolymorphMessageContainer(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) : + PolymorphMessageContainer(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false) : type{Type::Multi} { new (&multiMessage) AsyncWebSocketMultiMessage{buffer, opcode, mask}; @@ -234,7 +222,7 @@ class AsyncWebSocketClient { void _queueControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false); void _queueMessage(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); - void _queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void _queueMessage(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); void _runQueue(); void _clearQueue(); @@ -270,7 +258,7 @@ class AsyncWebSocketClient { //data packets void message(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(data, len, opcode, mask); } - void message(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } + void message(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } bool queueIsFull() const; size_t queueLen() const; @@ -284,7 +272,7 @@ class AsyncWebSocketClient { void text(char * message); void text(const String &message); void text(const __FlashStringHelper *data); - void text(AsyncWebSocketMessageBuffer *buffer); + void text(std::shared_ptr buffer); void binary(const char * message, size_t len); void binary(const char * message); @@ -292,7 +280,7 @@ class AsyncWebSocketClient { void binary(char * message); void binary(const String &message); void binary(const __FlashStringHelper *data, size_t len); - void binary(AsyncWebSocketMessageBuffer *buffer); + void binary(std::shared_ptr buffer); bool canSend() const; @@ -352,7 +340,7 @@ class AsyncWebSocket: public AsyncWebHandler { void textAll(char * message); void textAll(const String &message); void textAll(const __FlashStringHelper *message); // need to convert - void textAll(AsyncWebSocketMessageBuffer *buffer); + void textAll(std::shared_ptr buffer); void binary(uint32_t id, const char * message, size_t len); void binary(uint32_t id, const char * message); @@ -367,11 +355,11 @@ class AsyncWebSocket: public AsyncWebHandler { void binaryAll(char * message); void binaryAll(const String &message); void binaryAll(const __FlashStringHelper *message, size_t len); - void binaryAll(AsyncWebSocketMessageBuffer *buffer); + void binaryAll(std::shared_ptr buffer); void message(uint32_t id, const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); - void message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); - void messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void message(uint32_t id, std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void messageAll(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); @@ -400,9 +388,9 @@ class AsyncWebSocket: public AsyncWebHandler { // messagebuffer functions/objects. - AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); - AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); - std::list _buffers; + std::shared_ptr makeBuffer(size_t size = 0); + std::shared_ptr makeBuffer(uint8_t * data, size_t size); + std::list> _buffers; void _cleanBuffers(); const std::list &getClients() const { return _clients; }