Skip to content

Commit a320ffe

Browse files
committed
fix(StreamString): Improve StreamString::readBytes() speed with large buffers
Using `StreamString` on large buffers causes large movements of memory data when reading which can cause the TWDT to trigger, heap fragmentation or crash due to allocation failures. `StreamString` is definitely slower than cbuf.h for large buffers. Explanation of the issue with a small MRE: ESP32Async/ESPAsyncWebServer#148 (comment) This issue was discovered in the OpenDTU project : tbnobody/OpenDTU#2535
1 parent b333bf2 commit a320ffe

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

Diff for: cores/esp32/StreamString.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,26 @@ int StreamString::read() {
5353
return -1;
5454
}
5555

56+
size_t StreamString::readBytes(char *buffer, size_t buffLen) {
57+
if (!buffLen || !buffer) {
58+
return 0;
59+
}
60+
const uint32_t start = millis();
61+
size_t count = 0;
62+
do {
63+
if (this->length()) {
64+
const size_t available = min(buffLen - count, (size_t)this->length());
65+
memcpy(buffer + count, c_str(), available);
66+
remove(0, available);
67+
count += available;
68+
}
69+
if (count == buffLen || _timeout == 0) {
70+
return count;
71+
}
72+
} while (millis() - start < _timeout);
73+
return count;
74+
}
75+
5676
int StreamString::peek() {
5777
if (length()) {
5878
char c = charAt(0);

Diff for: cores/esp32/StreamString.h

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class StreamString : public Stream, public String {
3131

3232
int available() override;
3333
int read() override;
34+
size_t readBytes(char *buffer, size_t count) override;
3435
int peek() override;
3536
void flush() override;
3637
};

0 commit comments

Comments
 (0)