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"
@@ -75,7 +77,7 @@ void Stream::setTimeout(unsigned long timeout) // sets the maximum number of mi
7577 // find returns true if the target string is found
7678bool Stream::find (char *target)
7779{
78- return findUntil (target, ( char *) " " );
80+ return findUntil (target, strlen (target), NULL , 0 );
7981}
8082
8183// reads data from the stream until the target string of given length is found
@@ -96,32 +98,13 @@ bool Stream::findUntil(char *target, char *terminator)
9698// returns true if target string is found, false if terminated or timed out
9799bool Stream::findUntil (char *target, size_t targetLen, char *terminator, size_t termLen)
98100{
99- size_t index = 0 ; // maximum target string length is 64k bytes!
100- size_t termIndex = 0 ;
101- int c;
102-
103- if ( *target == 0 )
104- return true ; // return true if target is a null string
105- while ( (c = timedRead ()) > 0 ){
106-
107- if (c != target[index])
108- index = 0 ; // reset index if any char does not match
109-
110- if ( c == target[index]){
111- // ////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
112- if (++index >= targetLen){ // return true if all chars in the target match
113- return true ;
114- }
115- }
116-
117- if (termLen > 0 && c == terminator[termIndex]){
118- if (++termIndex >= termLen)
119- return false ; // return false if terminate string found before target string
120- }
121- else
122- termIndex = 0 ;
101+ if (terminator == NULL ) {
102+ MultiTarget t[1 ] = {{target, targetLen, 0 }};
103+ return findMulti (t, 1 ) == 0 ? true : false ;
104+ } else {
105+ MultiTarget t[2 ] = {{target, targetLen, 0 }, {terminator, termLen, 0 }};
106+ return findMulti (t, 2 ) == 0 ? true : false ;
123107 }
124- return false ;
125108}
126109
127110
@@ -137,7 +120,7 @@ long Stream::parseInt()
137120// this allows format characters (typically commas) in values to be ignored
138121long Stream::parseInt (char skipChar)
139122{
140- boolean isNegative = false ;
123+ bool isNegative = false ;
141124 long value = 0 ;
142125 int c;
143126
@@ -173,10 +156,10 @@ float Stream::parseFloat()
173156// as above but the given skipChar is ignored
174157// this allows format characters (typically commas) in values to be ignored
175158float Stream::parseFloat (char skipChar){
176- boolean isNegative = false ;
177- boolean isFraction = false ;
159+ bool isNegative = false ;
160+ bool isFraction = false ;
178161 long value = 0 ;
179- int c;
162+ char c;
180163 float fraction = 1.0 ;
181164
182165 c = peekNextDigit ();
@@ -268,3 +251,62 @@ String Stream::readStringUntil(char terminator)
268251 return ret;
269252}
270253
254+ int Stream::findMulti ( struct Stream ::MultiTarget *targets, int tCount) {
255+ // any zero length target string automatically matches and would make
256+ // a mess of the rest of the algorithm.
257+ for (struct MultiTarget *t = targets; t < targets+tCount; ++t)
258+ if (t->len <= 0 )
259+ return t - targets;
260+
261+ while (1 ) {
262+ int c = timedRead ();
263+ if (c < 0 )
264+ return -1 ;
265+
266+ for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
267+ // the simple case is if we match, deal with that first.
268+ if (c == t->str [t->index ])
269+ if (++t->index == t->len )
270+ return t - targets;
271+ else
272+ continue ;
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+ int origIndex = t->index ;
282+ do {
283+ --t->index ;
284+ // first check if current char works against the new current index
285+ if (c != t->str [t->index ])
286+ continue ;
287+
288+ // if it's the only char then we're good, nothing more to check
289+ if (t->index == 0 ) {
290+ t->index ++;
291+ break ;
292+ }
293+
294+ // otherwise we need to check the rest of the found string
295+ int diff = origIndex - t->index ;
296+ int i;
297+ for (i = 0 ; i < t->index ; ++i)
298+ if (t->str [i] != t->str [i + diff])
299+ break ;
300+ // if we successfully got through the previous loop then our current
301+ // index is good.
302+ if (i == t->index ) {
303+ t->index ++;
304+ break ;
305+ }
306+ // otherwise we just try the next index
307+ } while (t->index );
308+ }
309+ }
310+ // unreachable
311+ return -1 ;
312+ }
0 commit comments