/* WebSocketIncommingBuffer Code by Hermann Kraus (https://bitbucket.org/hermr2d2/) and slightly modified. */ #pragma once #define MAX_WS_MSG_SIZE 4000 typedef std::function AwsMessageHandler; class WebSocketIncommingBuffer { public: WebSocketIncommingBuffer(AwsMessageHandler cb, bool terminate_string = true, bool cb_on_fragments = false) : _cb(cb), _terminate_string(terminate_string), _cb_on_fragments(cb_on_fragments), _buffer(0) {} ~WebSocketIncommingBuffer() { if (_buffer) delete _buffer; } void data_event(AsyncWebSocketClient *client, AwsFrameInfo *info, uint8_t *data, size_t len) { if ((info->final || _cb_on_fragments) && !_terminate_string && info->index == 0 && info->len == len) { /* The whole message is in a single frame and we got all of it's data therefore we can parse it without copying the data first.*/ _cb(client, data, len); } else { if (info->len > MAX_WS_MSG_SIZE) return; /* Check if previous fragment was discarded because it was too long. */ //if (!_cb_on_fragments && info->num > 0 && !_buffer) return; if (!_buffer) _buffer = new std::vector(); if (info->index == 0) { //New frame => preallocate memory if (_cb_on_fragments) { _buffer->reserve(info->len + 1); } else { /* The current fragment would lead to a message which is too long. So discard everything received so far. */ if (info->len + _buffer->size() > MAX_WS_MSG_SIZE) { delete _buffer; _buffer = 0; return; } else { _buffer->reserve(info->len + _buffer->size() + 1); } } } //assert(_buffer->size() == info->index); _buffer->insert(_buffer->end(), data, data+len); if (info->index + len == info->len && (info->final || _cb_on_fragments)) { // Frame/message complete if (_terminate_string) _buffer->push_back(0); _cb(client, _buffer->data(), _buffer->size()); _buffer->clear(); } } } private: AwsMessageHandler _cb; bool _terminate_string; bool _cb_on_fragments; std::vector *_buffer; };