Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 474dcd3

Browse files
replace Strings with with StreamStrings to avoid String Reallocations.
1 parent b0c04b4 commit 474dcd3

File tree

3 files changed

+67
-18
lines changed

3 files changed

+67
-18
lines changed

‎cores/esp8266/Stream.cpp‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <Arduino.h>
2424
#include <Stream.h>
25+
#include <StreamString.h>
2526

2627
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
2728
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
@@ -288,6 +289,59 @@ String Stream::readStringUntil(const char* terminator, uint32_t untilTotalNumber
288289
return ret;
289290
}
290291

292+
String Stream::readStreamString(const ssize_t maxLen ,const oneShotMs::timeType timeoutMs) {
293+
String ret;
294+
S2Stream stream(ret);
295+
sendGeneric(&stream, maxLen, -1, timeoutMs);
296+
return ret;
297+
}
298+
299+
String Stream::readStreamStringUntil(const int readUntilChar, const oneShotMs::timeType timeoutMs) {
300+
String ret;
301+
S2Stream stream(ret);
302+
sendGeneric(&stream, -1, readUntilChar, timeoutMs);
303+
return ret;
304+
}
305+
306+
String Stream::readStreamStringUntil (const char* terminatorString, uint32_t untilTotalNumberOfOccurrences, const oneShotMs::timeType timeoutMs) {
307+
String ret;
308+
S2Stream stream(ret);
309+
uint32_t occurrences = 0;
310+
size_t termLen = strlen(terminatorString);
311+
size_t termIndex = 0;
312+
// Serial.printf("S %s\n",terminatorString);
313+
while(1){
314+
size_t read = sendGeneric(&stream, -1, terminatorString[termIndex], timeoutMs);
315+
// Serial.printf("r %d, l %d, ti %d\n", read, termLen, termIndex);
316+
if(getLastSendReport() != Report::Success) {
317+
Serial.printf("Error %d\n", (int) getLastSendReport());
318+
break;
319+
}
320+
if(termIndex == termLen - 1){
321+
// Serial.printf("m %d\n", occurrences);
322+
if(++occurrences == untilTotalNumberOfOccurrences){
323+
break;
324+
}else{
325+
ret += terminatorString;
326+
termIndex = 0;
327+
continue;
328+
}
329+
}
330+
int c = timedPeek();
331+
// Serial.printf("c %c %02X\n", c, c);
332+
if( c >= 0 && c != terminatorString[++termIndex]){
333+
ret += String(terminatorString).substring(0, termIndex);
334+
termIndex = 0;
335+
continue;
336+
};
337+
if(c < 0 || (read == 0 && termIndex == 0)) break;
338+
}
339+
340+
return ret;
341+
}
342+
343+
344+
291345
// read what can be read, immediate exit on unavailable data
292346
// prototype similar to Arduino's `int Client::read(buf, len)`
293347
int Stream::read (uint8_t* buffer, size_t maxLen)

‎cores/esp8266/Stream.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ class Stream: public Print {
212212
size_t sendSize (Stream* to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, maxLen, -1, timeoutMs); }
213213
size_t sendSize (Stream& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); }
214214

215+
String readStreamString (const ssize_t maxLen = -1 ,const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires);
216+
String readStreamStringUntil (const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires);
217+
String readStreamStringUntil (const char* terminatorString, uint32_t untilTotalNumberOfOccurrences = 1, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires);
218+
215219
// remaining size (-1 by default = unknown)
216220
virtual ssize_t streamRemaining () { return -1; }
217221

‎libraries/ESP8266WebServer/src/Parsing-impl.h‎

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ static bool readBytesWithTimeout(typename ServerType::ClientType& client, size_t
4444
template <typename ServerType>
4545
typename ESP8266WebServerTemplate<ServerType>::ClientFuture ESP8266WebServerTemplate<ServerType>::_parseRequest(ClientType& client) {
4646
// Read the first line of HTTP request
47-
String req = client.readStringUntil('\r');
47+
String req = client.readStreamStringUntil("\r\n");
4848
DBGWS("request: %s\n", req.c_str());
49-
client.readStringUntil('\n');
5049
//reset header value
5150
for (int i = 0; i < _headerKeysCount; ++i) {
5251
_currentHeaders[i].value.clear();
@@ -122,8 +121,7 @@ typename ESP8266WebServerTemplate<ServerType>::ClientFuture ESP8266WebServerTemp
122121
uint32_t contentLength = 0;
123122
//parse headers
124123
while(1){
125-
req = client.readStringUntil('\r');
126-
client.readStringUntil('\n');
124+
req = client.readStreamStringUntil("\r\n");
127125
if (req.isEmpty()) break; //no more headers
128126
int headerDiv = req.indexOf(':');
129127
if (headerDiv == -1){
@@ -198,8 +196,7 @@ typename ESP8266WebServerTemplate<ServerType>::ClientFuture ESP8266WebServerTemp
198196
String headerValue;
199197
//parse headers
200198
while(1){
201-
req = client.readStringUntil('\r');
202-
client.readStringUntil('\n');
199+
req = client.readStreamStringUntil("\r\n");
203200
if (req.isEmpty()) break;//no moar headers
204201
int headerDiv = req.indexOf(':');
205202
if (headerDiv == -1){
@@ -351,11 +348,10 @@ bool ESP8266WebServerTemplate<ServerType>::_parseForm(ClientType& client, const
351348
String line;
352349
int retry = 0;
353350
do {
354-
line = client.readStringUntil('\r');
351+
line = client.readStreamStringUntil("\r\n");
355352
++retry;
356353
} while (line.length() == 0 && retry < 3);
357354

358-
client.readStringUntil('\n');
359355
//start reading the form
360356
if (line == ("--"+boundary)){
361357
std::unique_ptr<RequestArgument[]> postArgs(new RequestArgument[WEBSERVER_MAX_POST_ARGS]);
@@ -367,8 +363,7 @@ bool ESP8266WebServerTemplate<ServerType>::_parseForm(ClientType& client, const
367363
String argFilename;
368364
bool argIsFile = false;
369365

370-
line = client.readStringUntil('\r');
371-
client.readStringUntil('\n');
366+
line = client.readStreamStringUntil("\r\n");
372367
if (line.length() > 19 && line.substring(0, 19).equalsIgnoreCase(F("Content-Disposition"))){
373368
int nameStart = line.indexOf('=');
374369
if (nameStart != -1){
@@ -388,19 +383,16 @@ bool ESP8266WebServerTemplate<ServerType>::_parseForm(ClientType& client, const
388383
DBGWS("PostArg Name: %s\n", argName.c_str());
389384
using namespace mime;
390385
argType = FPSTR(mimeTable[txt].mimeType);
391-
line = client.readStringUntil('\r');
392-
client.readStringUntil('\n');
386+
line = client.readStreamStringUntil("\r\n");
393387
if (line.length() > 12 && line.substring(0, 12).equalsIgnoreCase(FPSTR(Content_Type))){
394388
argType = line.substring(line.indexOf(':')+2);
395389
//skip next line
396-
client.readStringUntil('\r');
397-
client.readStringUntil('\n');
390+
client.readStringUntil("\r\n");
398391
}
399392
DBGWS("PostArg Type: %s\n", argType.c_str());
400393
if (!argIsFile){
401394
while(1){
402-
line = client.readStringUntil('\r');
403-
client.readStringUntil('\n');
395+
line = client.readStreamStringUntil("\r\n");
404396
if (line.startsWith("--"+boundary)) break;
405397
if (argValue.length() > 0) argValue += '\n';
406398
argValue += line;
@@ -474,8 +466,7 @@ bool ESP8266WebServerTemplate<ServerType>::_parseForm(ClientType& client, const
474466
_currentUpload->type.c_str(),
475467
(int)_currentUpload->totalSize);
476468
if (!client.connected()) return _parseFormUploadAborted();
477-
line = client.readStringUntil('\r');
478-
client.readStringUntil('\n');
469+
line = client.readStreamStringUntil("\r\n");
479470
if (line == "--") { // extra two dashes mean we reached the end of all form fields
480471
DBGWS("Done Parsing POST\n");
481472
break;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /