Skip to content

Commit 0897c48

Browse files
authored
Merge pull request Aircoookie#12 from willmmiles/first-fixes
First round of fixes on v2.1.0 code
2 parents 6bf93e9 + 71a4104 commit 0897c48

File tree

7 files changed

+86
-51
lines changed

7 files changed

+86
-51
lines changed

src/AsyncWebSocket.cpp

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#endif
3131

3232
#ifdef ASYNCWEBSERVER_DEBUG_TRACE
33-
#define DEBUG_PRINTFP(fmt, ...) Serial.printf_P(PSTR("[%d]{%d}" fmt "\n"), millis(), ESP.getFreeHeap(), ##__VA_ARGS__)
33+
#define DEBUG_PRINTFP(fmt, ...) Serial.printf_P(PSTR("[%u]{%d}" fmt "\n"), (unsigned) millis(), ESP.getFreeHeap(), ##__VA_ARGS__)
3434
#else
3535
#define DEBUG_PRINTFP(...)
3636
#endif
@@ -778,7 +778,7 @@ void AsyncWebSocketClient::text(const __FlashStringHelper *data){
778778
free(message);
779779
}
780780
}
781-
void AsyncWebSocketClient::text(AsyncWebSocketSharedBuffer buffer)
781+
void AsyncWebSocketClient::text(AsyncWebSocketBuffer buffer)
782782
{
783783
_queueMessage(new AsyncWebSocketMultiMessage(std::move(buffer)));
784784
}
@@ -815,7 +815,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len){
815815
}
816816

817817
}
818-
void AsyncWebSocketClient::binary(AsyncWebSocketSharedBuffer buffer)
818+
void AsyncWebSocketClient::binary(AsyncWebSocketBuffer buffer)
819819
{
820820
_queueMessage(new AsyncWebSocketMultiMessage(std::move(buffer), WS_BINARY));
821821
}
@@ -944,22 +944,19 @@ void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){
944944
c->text(message, len);
945945
}
946946

947-
void AsyncWebSocket::textAll(const AsyncWebSocketSharedBuffer& buffer){
947+
void AsyncWebSocket::textAll(AsyncWebSocketBuffer buffer){
948948
if (!buffer) return;
949-
for(const auto& c: _clients){
950-
if(c->status() == WS_CONNECTED){
951-
c->text(buffer);
952-
}
953-
}
949+
messageAll(AsyncWebSocketMultiMessage(std::move(buffer)));
954950
}
955951

956952
void AsyncWebSocket::textAll(const char * message, size_t len){
957-
textAll(AsyncWebSocketSharedBuffer(message, len));
953+
if ((!message) || (len ==0)) return;
954+
messageAll(AsyncWebSocketMultiMessage(SharedBuffer{message, len}));
958955
}
959956

960957
void AsyncWebSocket::textAll(const AsyncWebSocketMessageBuffer* buffer){
961958
if (!buffer) return;
962-
textAll(buffer->_buf);
959+
textAll(std::move(buffer->_buf));
963960
delete buffer;
964961
}
965962

@@ -970,20 +967,17 @@ void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len){
970967
}
971968

972969
void AsyncWebSocket::binaryAll(const char * message, size_t len){
973-
binaryAll(SharedBuffer(message, len));
970+
binaryAll(DynamicBuffer(message, len));
974971
}
975972

976-
void AsyncWebSocket::binaryAll(const AsyncWebSocketSharedBuffer &buffer)
973+
void AsyncWebSocket::binaryAll(AsyncWebSocketBuffer buffer)
977974
{
978-
for(const auto& c: _clients){
979-
if(c->status() == WS_CONNECTED)
980-
c->binary(buffer);
981-
}
975+
messageAll(AsyncWebSocketMultiMessage(std::move(buffer), WS_BINARY));
982976
}
983977

984978
void AsyncWebSocket::binaryAll(const AsyncWebSocketMessageBuffer* buffer){
985979
if (!buffer) return;
986-
binaryAll(buffer->_buf);
980+
binaryAll(std::move(buffer->_buf));
987981
delete buffer;
988982
}
989983

@@ -1023,7 +1017,7 @@ size_t AsyncWebSocket::printfAll(const char *format, ...) {
10231017
va_end(arg);
10241018
delete[] temp;
10251019

1026-
AsyncWebSocketSharedBuffer buffer(len);
1020+
AsyncWebSocketBuffer buffer(len);
10271021
if (!buffer) {
10281022
return 0;
10291023
}
@@ -1061,7 +1055,7 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) {
10611055
va_end(arg);
10621056
delete[] temp;
10631057

1064-
AsyncWebSocketSharedBuffer buffer(len);
1058+
AsyncWebSocketBuffer buffer(len);
10651059
if (!buffer) {
10661060
return 0;
10671061
}
@@ -1198,7 +1192,7 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){
11981192
// Deprecated API
11991193
AsyncWebSocketMessageBuffer* AsyncWebSocket::makeBuffer(size_t size)
12001194
{
1201-
AsyncWebSocketSharedBuffer buffer(size);
1195+
AsyncWebSocketBuffer buffer(size);
12021196
if (buffer.size() == 0) {
12031197
return nullptr;
12041198
}
@@ -1207,7 +1201,7 @@ AsyncWebSocketMessageBuffer* AsyncWebSocket::makeBuffer(size_t size)
12071201

12081202
AsyncWebSocketMessageBuffer* AsyncWebSocket::makeBuffer(const uint8_t * data, size_t size)
12091203
{
1210-
AsyncWebSocketSharedBuffer buffer((const char*) data, size);
1204+
AsyncWebSocketBuffer buffer((const char*) data, size);
12111205
if (buffer.size() == 0) {
12121206
return nullptr;
12131207
}

src/AsyncWebSocket.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,22 @@ typedef enum { WS_CONTINUATION, WS_TEXT, WS_BINARY, WS_DISCONNECT = 0x08, WS_PIN
8989
typedef enum { WS_MSG_SENDING, WS_MSG_SENT, WS_MSG_ERROR } AwsMessageStatus;
9090
typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_EVT_DATA } AwsEventType;
9191

92+
typedef DynamicBuffer AsyncWebSocketBuffer;
9293
typedef SharedBuffer AsyncWebSocketSharedBuffer;
9394

94-
// API compatibility class - use AsyncWebSocketSharedBuffer directly
95+
// API compatibility class.
96+
// Use AsyncWebSocketBuffer directly instead of this where possible.
9597
class AsyncWebSocketMessageBuffer {
9698
private:
97-
AsyncWebSocketSharedBuffer _buf;
99+
DynamicBuffer _buf;
98100

99101
public:
100102
AsyncWebSocketMessageBuffer() {};
101103
AsyncWebSocketMessageBuffer(size_t size) : _buf(size) {};
102104
AsyncWebSocketMessageBuffer(uint8_t * data, size_t size) : _buf(reinterpret_cast<char*>(data), size) {};
103-
AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &r) { if (r._buf) _buf = SharedBuffer(r._buf.copy()); }
105+
AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &r) { if (r._buf) _buf = r._buf; }
104106
AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&) = default;
105-
AsyncWebSocketMessageBuffer(AsyncWebSocketSharedBuffer b) : _buf(std::move(b)) {};
107+
AsyncWebSocketMessageBuffer(DynamicBuffer b) : _buf(std::move(b)) {};
106108
~AsyncWebSocketMessageBuffer() {};
107109

108110
void operator ++(int i) {};
@@ -160,6 +162,7 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage {
160162
AsyncWebSocketSharedBuffer _WSbuffer;
161163
public:
162164
AsyncWebSocketMultiMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false);
165+
AsyncWebSocketMultiMessage(AsyncWebSocketBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false) : AsyncWebSocketMultiMessage(AsyncWebSocketSharedBuffer(std::move(buffer)), opcode, mask){};
163166
virtual ~AsyncWebSocketMultiMessage() override;
164167
virtual bool betweenFrames() const override { return _acked == _ack; }
165168
virtual void ack(size_t len, uint32_t time) override ;
@@ -233,7 +236,7 @@ class AsyncWebSocketClient {
233236
void text(char * message);
234237
void text(const String &message);
235238
void text(const __FlashStringHelper *data);
236-
void text(AsyncWebSocketSharedBuffer buffer);
239+
void text(AsyncWebSocketBuffer buffer);
237240
void text(AsyncWebSocketMessageBuffer* buffer) __attribute__((deprecated)); // frees buffer
238241

239242
void binary(const char * message, size_t len);
@@ -242,7 +245,7 @@ class AsyncWebSocketClient {
242245
void binary(char * message);
243246
void binary(const String &message);
244247
void binary(const __FlashStringHelper *data, size_t len);
245-
void binary(AsyncWebSocketSharedBuffer buffer);
248+
void binary(AsyncWebSocketBuffer buffer);
246249
void binary(AsyncWebSocketMessageBuffer* buffer) __attribute__((deprecated)); // frees buffer
247250

248251
bool canSend() { return _messageQueue.length() < WS_MAX_QUEUED_MESSAGES; }
@@ -295,14 +298,15 @@ class AsyncWebSocket: public AsyncWebHandler {
295298
void text(uint32_t id, char * message);
296299
void text(uint32_t id, const String &message);
297300
void text(uint32_t id, const __FlashStringHelper *message);
301+
void text(uint32_t id, AsyncWebSocketBuffer buffer);
298302

299303
void textAll(const char * message, size_t len);
300304
void textAll(const char * message);
301305
void textAll(uint8_t * message, size_t len);
302306
void textAll(char * message);
303307
void textAll(const String &message);
304308
void textAll(const __FlashStringHelper *message); // need to convert
305-
void textAll(const AsyncWebSocketSharedBuffer& buffer);
309+
void textAll(AsyncWebSocketBuffer buffer); // must be moved, or will be copied
306310
void textAll(const AsyncWebSocketMessageBuffer* buffer) __attribute__((deprecated)); // frees buffer
307311

308312
void binary(uint32_t id, const char * message, size_t len);
@@ -318,7 +322,7 @@ class AsyncWebSocket: public AsyncWebHandler {
318322
void binaryAll(char * message);
319323
void binaryAll(const String &message);
320324
void binaryAll(const __FlashStringHelper *message, size_t len);
321-
void binaryAll(const AsyncWebSocketSharedBuffer& buffer);
325+
void binaryAll(AsyncWebSocketBuffer buffer);
322326
void binaryAll(const AsyncWebSocketMessageBuffer* buffer) __attribute__((deprecated)); // frees buffer
323327

324328
void message(uint32_t id, AsyncWebSocketMessage *message);

src/ContentTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ static inline bool matches_p(const char* str, const char* progmem_str) {
77
const __FlashStringHelper* contentTypeFor(const String& path) {
88
// Find extension part of path
99
auto idx = path.lastIndexOf('.');
10-
if (idx < path.length()) {
10+
if (idx >= 0) {
1111
auto ext_str = path.begin() + idx + 1;
1212

1313
if (matches_p(ext_str, HTML_EXTENSION)) return FPSTR(CONTENT_TYPE_HTML);

src/DynamicBuffer.cpp

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,52 @@
22
#include <numeric>
33

44
// Helper class - lets us move the buffer out of a String
5-
class ReleasableString : public String {
6-
public:
7-
// Inherit constructors
8-
using String::String;
9-
ReleasableString(String&& s) : String(std::move(s)) {};
10-
11-
// Special feature: releease the buffer to the caller without deallocating
12-
char* release() {
13-
if (isSSO()) return nullptr;
14-
auto result = wbuffer();
15-
init();
16-
return result;
17-
}
18-
};
5+
namespace {
6+
class DynamicBufferString : public String {
7+
public:
8+
// Inherit constructors
9+
using String::String;
10+
DynamicBufferString(String&& s) : String(std::move(s)) {};
11+
DynamicBufferString(DynamicBuffer&& d) : String() {
12+
auto capacity = d.size() - 1;
13+
auto buf = d.release();
14+
auto len = strnlen(buf, capacity);
15+
if (len == capacity) buf[len] = 0; // enforce null termination
16+
setSSO(false);
17+
setBuffer(buf);
18+
setCapacity(capacity);
19+
setLen(len);
20+
}
21+
22+
// Special feature: releease the buffer to the caller without deallocating
23+
char* release() {
24+
if (isSSO()) return nullptr;
25+
auto result = wbuffer();
26+
init();
27+
return result;
28+
}
29+
};
30+
}
1931

2032
DynamicBuffer::DynamicBuffer(String&& s) : _data(nullptr), _len(s.length()) {
21-
auto rb = ReleasableString(std::move(s));
33+
auto rb = DynamicBufferString(std::move(s));
2234
_data = rb.release();
2335
if (!_data) {
2436
*this = DynamicBuffer(rb); // use const-ref constructor to copy string
2537
}
2638
}
2739

40+
DynamicBuffer::DynamicBuffer(const SharedBuffer& b) : DynamicBuffer(b.copy()) {};
41+
42+
DynamicBuffer::DynamicBuffer(SharedBuffer&& b) : _data(nullptr), _len(0) {
43+
if (b) *this = std::move(*b._buf);
44+
}
45+
46+
String toString(DynamicBuffer buf) {
47+
auto dbstr = DynamicBufferString(std::move(buf));
48+
return std::move(*static_cast<String*>(&dbstr)); // Move-construct the result string from dbstr
49+
}
50+
2851
template<typename list_type>
2952
static inline list_type allocateList(size_t total, size_t max_buffer_size) {
3053
list_type buffers;

src/DynamicBuffer.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include <list>
99
#include <utility>
1010

11+
// Forward declaration
12+
class SharedBuffer;
13+
1114
// The DynamicBuffer class holds a malloc() allocated heap buffer.
1215
// It's similar to std::vector<char>, but permits allocation failures without crashing the system.
1316
class DynamicBuffer {
@@ -23,6 +26,8 @@ class DynamicBuffer {
2326
DynamicBuffer(const char* buf, size_t len) : DynamicBuffer(len) { if (_data) memcpy(_data, buf, len); };
2427
explicit DynamicBuffer(const String& s) : DynamicBuffer(s.begin(), s.length()) {};
2528
explicit DynamicBuffer(String&&); // Move string contents in to buffer if possible
29+
DynamicBuffer(const SharedBuffer&);
30+
DynamicBuffer(SharedBuffer&&);
2631
~DynamicBuffer() { clear(); };
2732

2833
// Move
@@ -39,13 +44,16 @@ class DynamicBuffer {
3944

4045
explicit operator bool() const { return (_data != nullptr) && (_len > 0); }
4146

47+
// Release the buffer without freeing it
48+
char* release() { char* temp = _data; _data = nullptr; _len = 0; return temp; }
49+
4250
// TODO, if it ever matters - resizing
4351
};
4452

45-
4653
// Same interface as DynamicBuffer, but with shared_ptr semantics: buffer is held until last copy releases it.
4754
class SharedBuffer {
4855
std::shared_ptr<DynamicBuffer> _buf;
56+
friend class DynamicBuffer;
4957

5058
public:
5159

@@ -54,8 +62,8 @@ class SharedBuffer {
5462
SharedBuffer(const char* buf, size_t len) : _buf(std::make_shared<DynamicBuffer>(buf, len)) {};
5563
explicit SharedBuffer(const String& s) : _buf(std::make_shared<DynamicBuffer>(s)) {};
5664
explicit SharedBuffer(String&& s) : _buf(std::make_shared<DynamicBuffer>(std::move(s))) {};
57-
explicit SharedBuffer(const DynamicBuffer &d) : _buf(std::make_shared<DynamicBuffer>(d)) {};
58-
explicit SharedBuffer(DynamicBuffer&& d) : _buf(std::make_shared<DynamicBuffer>(std::move(d))) {};
65+
SharedBuffer(const DynamicBuffer &d) : _buf(std::make_shared<DynamicBuffer>(d)) {};
66+
SharedBuffer(DynamicBuffer&& d) : _buf(std::make_shared<DynamicBuffer>(std::move(d))) {};
5967

6068
char* data() const { return _buf ? _buf->data() : nullptr; };
6169
size_t size() const { return _buf ? _buf->size() : 0U; };
@@ -65,6 +73,9 @@ class SharedBuffer {
6573
DynamicBuffer copy() const { return *_buf; }; // Make a copy of the buffer
6674
};
6775

76+
// Utility functions
77+
String toString(DynamicBuffer buf); // Move a buffer in to a string. Buffer will be moved if buf is an rvalue, copied otherwise.
78+
6879

6980
// DynamicBufferList - an RAII list of DynamicBuffers
7081
// This structure can be used to create a chain of buffers, useful when the heap could get fragmented
@@ -131,6 +142,9 @@ class BufferListPrint : public Print {
131142
size_t write(uint8_t c) {
132143
return this->write(&c, 1);
133144
}
145+
146+
bool valid() const { return _valid; };
147+
explicit operator bool() const { return valid(); };
134148
};
135149

136150
typedef BufferListPrint<DynamicBufferList> DynamicBufferListPrint;

src/WebRequest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static const String SharedEmptyString = String();
3333
enum { PARSE_REQ_START, PARSE_REQ_HEADERS, PARSE_REQ_BODY, PARSE_REQ_END, PARSE_REQ_FAIL };
3434

3535
#ifdef ASYNCWEBSERVER_DEBUG_TRACE
36-
#define DEBUG_PRINTFP(fmt, ...) Serial.printf_P(PSTR("[%d]{%d}" fmt "\n"), millis(), ESP.getFreeHeap(), ##__VA_ARGS__)
36+
#define DEBUG_PRINTFP(fmt, ...) Serial.printf_P(PSTR("[%u]{%d}" fmt "\n"), (unsigned) millis(), ESP.getFreeHeap(), ##__VA_ARGS__)
3737
#else
3838
#define DEBUG_PRINTFP(...)
3939
#endif

src/WebResponses.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "cbuf.h"
2424

2525
#ifdef ASYNCWEBSERVER_DEBUG_TRACE
26-
#define DEBUG_PRINTFP(fmt, ...) Serial.printf_P(PSTR("[%d]" fmt), millis(), ##__VA_ARGS__)
26+
#define DEBUG_PRINTFP(fmt, ...) Serial.printf_P(PSTR("[%u]" fmt), (unsigned) millis(), ##__VA_ARGS__)
2727
#else
2828
#define DEBUG_PRINTFP(...)
2929
#endif

0 commit comments

Comments
 (0)