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

Appearance settings

Commit 648094c

Browse filesBrowse files
fix(api): Update Arduino Stream class (espressif#10328)
* fix(api): Update Arduino Stream class Upstream code contains some fixes * Update Stream.h * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent eda6d21 commit 648094c
Copy full SHA for 648094c

File tree

2 files changed

+186
-176
lines changed
Filter options

2 files changed

+186
-176
lines changed

‎cores/esp32/Stream.cpp

Copy file name to clipboardExpand all lines: cores/esp32/Stream.cpp
+117-126Lines changed: 117 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
1919
Created July 2011
2020
parsing functions based on TextFinder library by Michael Margolis
21+
22+
findMulti/findUntil routines written by Jim Leonard/Xuth
2123
*/
2224

2325
#include "Arduino.h"
2426
#include "Stream.h"
25-
#include "esp32-hal.h"
2627

2728
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
28-
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
2929

3030
// private method to read stream with timeout
3131
int Stream::timedRead() {
@@ -55,18 +55,26 @@ int Stream::timedPeek() {
5555

5656
// returns peek of the next digit in the stream or -1 if timeout
5757
// discards non-numeric characters
58-
int Stream::peekNextDigit() {
58+
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) {
5959
int c;
6060
while (1) {
6161
c = timedPeek();
62-
if (c < 0) {
63-
return c; // timeout
64-
}
65-
if (c == '-') {
62+
63+
if (c < 0 || c == '-' || (c >= '0' && c <= '9') || (detectDecimal && c == '.')) {
6664
return c;
6765
}
68-
if (c >= '0' && c <= '9') {
69-
return c;
66+
67+
switch (lookahead) {
68+
case SKIP_NONE: return -1; // Fail code.
69+
case SKIP_WHITESPACE:
70+
switch (c) {
71+
case ' ':
72+
case '\t':
73+
case '\r':
74+
case '\n': break;
75+
default: return -1; // Fail code.
76+
}
77+
case SKIP_ALL: break;
7078
}
7179
read(); // discard non-numeric
7280
}
@@ -79,9 +87,6 @@ void Stream::setTimeout(unsigned long timeout) // sets the maximum number of mi
7987
{
8088
_timeout = timeout;
8189
}
82-
unsigned long Stream::getTimeout(void) {
83-
return _timeout;
84-
}
8590

8691
// find returns true if the target string is found
8792
bool Stream::find(const char *target) {
@@ -105,115 +110,40 @@ bool Stream::findUntil(const char *target, const char *terminator) {
105110
bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen) {
106111
if (terminator == NULL) {
107112
MultiTarget t[1] = {{target, targetLen, 0}};
108-
return findMulti(t, 1) == 0 ? true : false;
113+
return findMulti(t, 1) == 0;
109114
} else {
110115
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
111-
return findMulti(t, 2) == 0 ? true : false;
116+
return findMulti(t, 2) == 0;
112117
}
113118
}
114119

115-
int Stream::findMulti(struct Stream::MultiTarget *targets, int tCount) {
116-
// any zero length target string automatically matches and would make
117-
// a mess of the rest of the algorithm.
118-
for (struct MultiTarget *t = targets; t < targets + tCount; ++t) {
119-
if (t->len <= 0) {
120-
return t - targets;
121-
}
122-
}
123-
124-
while (1) {
125-
int c = timedRead();
126-
if (c < 0) {
127-
return -1;
128-
}
129-
130-
for (struct MultiTarget *t = targets; t < targets + tCount; ++t) {
131-
// the simple case is if we match, deal with that first.
132-
if (c == t->str[t->index]) {
133-
if (++t->index == t->len) {
134-
return t - targets;
135-
} else {
136-
continue;
137-
}
138-
}
139-
140-
// if not we need to walk back and see if we could have matched further
141-
// down the stream (ie '1112' doesn't match the first position in '11112'
142-
// but it will match the second position so we can't just reset the current
143-
// index to 0 when we find a mismatch.
144-
if (t->index == 0) {
145-
continue;
146-
}
147-
148-
int origIndex = t->index;
149-
do {
150-
--t->index;
151-
// first check if current char works against the new current index
152-
if (c != t->str[t->index]) {
153-
continue;
154-
}
155-
156-
// if it's the only char then we're good, nothing more to check
157-
if (t->index == 0) {
158-
t->index++;
159-
break;
160-
}
161-
162-
// otherwise we need to check the rest of the found string
163-
int diff = origIndex - t->index;
164-
size_t i;
165-
for (i = 0; i < t->index; ++i) {
166-
if (t->str[i] != t->str[i + diff]) {
167-
break;
168-
}
169-
}
170-
171-
// if we successfully got through the previous loop then our current
172-
// index is good.
173-
if (i == t->index) {
174-
t->index++;
175-
break;
176-
}
177-
178-
// otherwise we just try the next index
179-
} while (t->index);
180-
}
181-
}
182-
// unreachable
183-
return -1;
184-
}
185-
186120
// returns the first valid (long) integer value from the current position.
187-
// initial characters that are not digits (or the minus sign) are skipped
188-
// function is terminated by the first character that is not a digit.
189-
long Stream::parseInt() {
190-
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
191-
}
192-
193-
// as above but a given skipChar is ignored
194-
// this allows format characters (typically commas) in values to be ignored
195-
long Stream::parseInt(char skipChar) {
196-
boolean isNegative = false;
121+
// lookahead determines how parseInt looks ahead in the stream.
122+
// See LookaheadMode enumeration at the top of the file.
123+
// Lookahead is terminated by the first character that is not a valid part of an integer.
124+
// Once parsing commences, 'ignore' will be skipped in the stream.
125+
long Stream::parseInt(LookaheadMode lookahead, char ignore) {
126+
bool isNegative = false;
197127
long value = 0;
198128
int c;
199129

200-
c = peekNextDigit();
130+
c = peekNextDigit(lookahead, false);
201131
// ignore non numeric leading characters
202132
if (c < 0) {
203133
return 0; // zero returned if timeout
204134
}
205135

206136
do {
207-
if (c == skipChar) {
208-
} // ignore this character
137+
if ((char)c == ignore)
138+
; // ignore this character
209139
else if (c == '-') {
210140
isNegative = true;
211141
} else if (c >= '0' && c <= '9') { // is c a digit?
212142
value = value * 10 + c - '0';
213143
}
214144
read(); // consume the character we got with peek
215145
c = timedPeek();
216-
} while ((c >= '0' && c <= '9') || c == skipChar);
146+
} while ((c >= '0' && c <= '9') || (char)c == ignore);
217147

218148
if (isNegative) {
219149
value = -value;
@@ -222,50 +152,43 @@ long Stream::parseInt(char skipChar) {
222152
}
223153

224154
// as parseInt but returns a floating point value
225-
float Stream::parseFloat() {
226-
return parseFloat(NO_SKIP_CHAR);
227-
}
228-
229-
// as above but the given skipChar is ignored
230-
// this allows format characters (typically commas) in values to be ignored
231-
float Stream::parseFloat(char skipChar) {
232-
boolean isNegative = false;
233-
boolean isFraction = false;
234-
long value = 0;
155+
float Stream::parseFloat(LookaheadMode lookahead, char ignore) {
156+
bool isNegative = false;
157+
bool isFraction = false;
158+
double value = 0.0;
235159
int c;
236-
float fraction = 1.0;
160+
double fraction = 1.0;
237161

238-
c = peekNextDigit();
162+
c = peekNextDigit(lookahead, true);
239163
// ignore non numeric leading characters
240164
if (c < 0) {
241165
return 0; // zero returned if timeout
242166
}
243167

244168
do {
245-
if (c == skipChar) {
246-
} // ignore
169+
if ((char)c == ignore)
170+
; // ignore
247171
else if (c == '-') {
248172
isNegative = true;
249173
} else if (c == '.') {
250174
isFraction = true;
251175
} else if (c >= '0' && c <= '9') { // is c a digit?
252-
value = value * 10 + c - '0';
253176
if (isFraction) {
254-
fraction *= 0.1f;
177+
fraction *= 0.1;
178+
value = value + fraction * (c - '0');
179+
} else {
180+
value = value * 10 + c - '0';
255181
}
256182
}
257183
read(); // consume the character we got with peek
258184
c = timedPeek();
259-
} while ((c >= '0' && c <= '9') || c == '.' || c == skipChar);
185+
} while ((c >= '0' && c <= '9') || (c == '.' && !isFraction) || (char)c == ignore);
260186

261187
if (isNegative) {
262188
value = -value;
263189
}
264-
if (isFraction) {
265-
return value * fraction;
266-
} else {
267-
return value;
268-
}
190+
191+
return value;
269192
}
270193

271194
// read characters from stream into buffer
@@ -291,13 +214,10 @@ size_t Stream::readBytes(char *buffer, size_t length) {
291214
// returns the number of characters placed in the buffer (0 means no valid data found)
292215

293216
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) {
294-
if (length < 1) {
295-
return 0;
296-
}
297217
size_t index = 0;
298218
while (index < length) {
299219
int c = timedRead();
300-
if (c < 0 || c == terminator) {
220+
if (c < 0 || (char)c == terminator) {
301221
break;
302222
}
303223
*buffer++ = (char)c;
@@ -319,9 +239,80 @@ String Stream::readString() {
319239
String Stream::readStringUntil(char terminator) {
320240
String ret;
321241
int c = timedRead();
322-
while (c >= 0 && c != terminator) {
242+
while (c >= 0 && (char)c != terminator) {
323243
ret += (char)c;
324244
c = timedRead();
325245
}
326246
return ret;
327247
}
248+
249+
int Stream::findMulti(struct Stream::MultiTarget *targets, int tCount) {
250+
// any zero length target string automatically matches and would make
251+
// a mess of the rest of the algorithm.
252+
for (struct MultiTarget *t = targets; t < targets + tCount; ++t) {
253+
if (t->len <= 0) {
254+
return t - targets;
255+
}
256+
}
257+
258+
while (1) {
259+
int c = timedRead();
260+
if (c < 0) {
261+
return -1;
262+
}
263+
264+
for (struct MultiTarget *t = targets; t < targets + tCount; ++t) {
265+
// the simple case is if we match, deal with that first.
266+
if ((char)c == t->str[t->index]) {
267+
if (++t->index == t->len) {
268+
return t - targets;
269+
} else {
270+
continue;
271+
}
272+
}
273+
274+
// if not we need to walk back and see if we could have matched further
275+
// down the stream (ie '1112' doesn't match the first position in '11112'
276+
// but it will match the second position so we can't just reset the current
277+
// index to 0 when we find a mismatch.
278+
if (t->index == 0) {
279+
continue;
280+
}
281+
282+
int origIndex = t->index;
283+
do {
284+
--t->index;
285+
// first check if current char works against the new current index
286+
if ((char)c != t->str[t->index]) {
287+
continue;
288+
}
289+
290+
// if it's the only char then we're good, nothing more to check
291+
if (t->index == 0) {
292+
t->index++;
293+
break;
294+
}
295+
296+
// otherwise we need to check the rest of the found string
297+
int diff = origIndex - t->index;
298+
size_t i;
299+
for (i = 0; i < t->index; ++i) {
300+
if (t->str[i] != t->str[i + diff]) {
301+
break;
302+
}
303+
}
304+
305+
// if we successfully got through the previous loop then our current
306+
// index is good.
307+
if (i == t->index) {
308+
t->index++;
309+
break;
310+
}
311+
312+
// otherwise we just try the next index
313+
} while (t->index);
314+
}
315+
}
316+
// unreachable
317+
return -1;
318+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.