-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Corrections of Stream.Find, FindUntil and added FindMulti - like AVR-Core Libraries #3442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,7 +85,7 @@ void Stream::setTimeout(unsigned long timeout) // sets the maximum number of mi | |
unsigned long Stream::getTimeout(void) { | ||
return _timeout; | ||
} | ||
|
||
/* | ||
// find returns true if the target string is found | ||
bool Stream::find(const char *target) | ||
{ | ||
|
@@ -141,6 +141,114 @@ bool Stream::findUntil(const char *target, size_t targetLen, const char *termina | |
return false; | ||
} | ||
|
||
*/ | ||
|
||
// ******************** ALEXANDRE | ||
|
||
// find returns true if the target string is found | ||
bool Stream::find(char *target) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should restore the const signatures for these methods. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Const signature was not there on original AVR Core code. |
||
{ | ||
return findUntil(target, strlen(target), NULL, 0); | ||
} | ||
|
||
// reads data from the stream until the target string of given length is found | ||
// returns true if target string is found, false if timed out | ||
bool Stream::find(char *target, size_t length) | ||
{ | ||
return findUntil(target, length, NULL, 0); | ||
} | ||
|
||
// as find but search ends if the terminator string is found | ||
bool Stream::findUntil(char *target, char *terminator) | ||
{ | ||
return findUntil(target, strlen(target), terminator, strlen(terminator)); | ||
} | ||
|
||
// reads data from the stream until the target string of the given length is found | ||
// search terminated if the terminator string is found | ||
// returns true if target string is found, false if terminated or timed out | ||
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) | ||
{ | ||
if (terminator == NULL) { | ||
MultiTarget t[1] = {{target, targetLen, 0}}; | ||
return findMulti(t, 1) == 0 ? true : false; | ||
} else { | ||
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; | ||
return findMulti(t, 2) == 0 ? true : false; | ||
} | ||
} | ||
|
||
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { | ||
// any zero length target string automatically matches and would make | ||
// a mess of the rest of the algorithm. | ||
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { | ||
if (t->len <= 0) | ||
return t - targets; | ||
} | ||
|
||
while (1) { | ||
int c = timedRead(); | ||
if (c < 0) | ||
return -1; | ||
|
||
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { | ||
// the simple case is if we match, deal with that first. | ||
if (c == t->str[t->index]) { | ||
if (++t->index == t->len) | ||
return t - targets; | ||
else | ||
continue; | ||
} | ||
|
||
// if not we need to walk back and see if we could have matched further | ||
// down the stream (ie '1112' doesn't match the first position in '11112' | ||
// but it will match the second position so we can't just reset the current | ||
// index to 0 when we find a mismatch. | ||
if (t->index == 0) | ||
continue; | ||
|
||
int origIndex = t->index; | ||
do { | ||
--t->index; | ||
// first check if current char works against the new current index | ||
if (c != t->str[t->index]) | ||
continue; | ||
|
||
// if it's the only char then we're good, nothing more to check | ||
if (t->index == 0) { | ||
t->index++; | ||
break; | ||
} | ||
|
||
// otherwise we need to check the rest of the found string | ||
int diff = origIndex - t->index; | ||
size_t i; | ||
for (i = 0; i < t->index; ++i) { | ||
if (t->str[i] != t->str[i + diff]) | ||
break; | ||
} | ||
|
||
// if we successfully got through the previous loop then our current | ||
// index is good. | ||
if (i == t->index) { | ||
t->index++; | ||
break; | ||
} | ||
|
||
// otherwise we just try the next index | ||
} while (t->index); | ||
} | ||
} | ||
// unreachable | ||
return -1; | ||
} | ||
|
||
|
||
|
||
// ********************************** | ||
|
||
|
||
|
||
// returns the first valid (long) integer value from the current position. | ||
// initial characters that are not digits (or the minus sign) are skipped | ||
// function is terminated by the first character that is not a digit. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,6 +60,24 @@ class Stream: public Print | |
|
||
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second | ||
unsigned long getTimeout(void); | ||
|
||
bool find(char *target); // reads data from the stream until the target string is found | ||
bool find(uint8_t *target) { return find ((char *)target); } | ||
// returns true if target string is found, false if timed out (see setTimeout) | ||
|
||
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found | ||
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } | ||
// returns true if target string is found, false if timed out | ||
|
||
bool find(char target) { return find (&target, 1); } | ||
|
||
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found | ||
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } | ||
|
||
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found | ||
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } | ||
|
||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here about dead code and retaining the const signature updates. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I leave this code to Espressif decide what to do. About const it was not there on original AVR Core code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unless the code modifies the chars, they should be const. Regardless if that is on AVR or not :) |
||
bool find(const char *target); // reads data from the stream until the target string is found | ||
bool find(uint8_t *target) | ||
{ | ||
|
@@ -90,7 +108,7 @@ class Stream: public Print | |
{ | ||
return findUntil((char *) target, targetLen, terminate, termLen); | ||
} | ||
|
||
*/ | ||
long parseInt(); // returns the first valid (long) integer value from the current position. | ||
// initial characters that are not digits (or the minus sign) are skipped | ||
// integer is terminated by the first character that is not a digit. | ||
|
@@ -123,6 +141,17 @@ class Stream: public Print | |
// this allows format characters (typically commas) in values to be ignored | ||
|
||
float parseFloat(char skipChar); // as above but the given skipChar is ignored | ||
|
||
struct MultiTarget { | ||
const char *str; // string you're searching for | ||
size_t len; // length of string you're searching for | ||
size_t index; // index used by the search routine. | ||
}; | ||
|
||
// This allows you to search for an arbitrary number of strings. | ||
// Returns index of the target that is found first or -1 if timeout occurs. | ||
int findMulti(struct MultiTarget *targets, int tCount); | ||
|
||
}; | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of leaving a lot of dead code behind, just delete it.