From 2e12a796610e8764af828192d7bd76738d95384d Mon Sep 17 00:00:00 2001 From: Chris--A Date: Fri, 19 Jun 2015 13:05:06 +1000 Subject: [PATCH 1/5] =?UTF-8?q?This=20commit=20improves=20the=20parsing=20?= =?UTF-8?q?capability=20by=20allowing=20decimals=20only=20prefixed=20by=20?= =?UTF-8?q?an=20'.'=20character.=20Previously=20the=20preceeding=20zero=20?= =?UTF-8?q?must=20be=20present:=20'0.'=EF=BB=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hardware/arduino/avr/cores/arduino/Stream.cpp | 15 +++++++++------ hardware/arduino/avr/cores/arduino/Stream.h | 2 +- hardware/arduino/sam/cores/arduino/Stream.cpp | 15 +++++++++------ hardware/arduino/sam/cores/arduino/Stream.h | 2 +- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/Stream.cpp b/hardware/arduino/avr/cores/arduino/Stream.cpp index b31942f293e..1f2f074f0d3 100644 --- a/hardware/arduino/avr/cores/arduino/Stream.cpp +++ b/hardware/arduino/avr/cores/arduino/Stream.cpp @@ -54,14 +54,17 @@ int Stream::timedPeek() // returns peek of the next digit in the stream or -1 if timeout // discards non-numeric characters -int Stream::peekNextDigit() +int Stream::peekNextDigit( bool detectDecimal ) { int c; while (1) { c = timedPeek(); - if (c < 0) return c; // timeout - if (c == '-') return c; - if (c >= '0' && c <= '9') return c; + + if( c < 0 || + c == '-' || + c >= '0' && c <= '9' || + detectDecimal && c == '.') return c; + read(); // discard non-numeric } } @@ -124,7 +127,7 @@ long Stream::parseInt(char skipChar) long value = 0; int c; - c = peekNextDigit(); + c = peekNextDigit(false); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout @@ -162,7 +165,7 @@ float Stream::parseFloat(char skipChar){ char c; float fraction = 1.0; - c = peekNextDigit(); + c = peekNextDigit(true); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout diff --git a/hardware/arduino/avr/cores/arduino/Stream.h b/hardware/arduino/avr/cores/arduino/Stream.h index 15f6761f001..4bc0036ca7f 100644 --- a/hardware/arduino/avr/cores/arduino/Stream.h +++ b/hardware/arduino/avr/cores/arduino/Stream.h @@ -42,7 +42,7 @@ class Stream : public Print unsigned long _startMillis; // used for timeout measurement int timedRead(); // private method to read stream with timeout int timedPeek(); // private method to peek stream with timeout - int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + int peekNextDigit( bool detectDecimal ); // returns the next numeric digit in the stream or -1 if timeout public: virtual int available() = 0; diff --git a/hardware/arduino/sam/cores/arduino/Stream.cpp b/hardware/arduino/sam/cores/arduino/Stream.cpp index b31942f293e..1f2f074f0d3 100644 --- a/hardware/arduino/sam/cores/arduino/Stream.cpp +++ b/hardware/arduino/sam/cores/arduino/Stream.cpp @@ -54,14 +54,17 @@ int Stream::timedPeek() // returns peek of the next digit in the stream or -1 if timeout // discards non-numeric characters -int Stream::peekNextDigit() +int Stream::peekNextDigit( bool detectDecimal ) { int c; while (1) { c = timedPeek(); - if (c < 0) return c; // timeout - if (c == '-') return c; - if (c >= '0' && c <= '9') return c; + + if( c < 0 || + c == '-' || + c >= '0' && c <= '9' || + detectDecimal && c == '.') return c; + read(); // discard non-numeric } } @@ -124,7 +127,7 @@ long Stream::parseInt(char skipChar) long value = 0; int c; - c = peekNextDigit(); + c = peekNextDigit(false); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout @@ -162,7 +165,7 @@ float Stream::parseFloat(char skipChar){ char c; float fraction = 1.0; - c = peekNextDigit(); + c = peekNextDigit(true); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout diff --git a/hardware/arduino/sam/cores/arduino/Stream.h b/hardware/arduino/sam/cores/arduino/Stream.h index 0d9a49aca3a..15f18106aa4 100644 --- a/hardware/arduino/sam/cores/arduino/Stream.h +++ b/hardware/arduino/sam/cores/arduino/Stream.h @@ -42,7 +42,7 @@ class Stream : public Print unsigned long _startMillis; // used for timeout measurement int timedRead(); // private method to read stream with timeout int timedPeek(); // private method to peek stream with timeout - int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + int peekNextDigit( bool detectDecimal ); // returns the next numeric digit in the stream or -1 if timeout public: virtual int available() = 0; From 9ecc150fa7611b64f5c0972a12043a26cfd3eb74 Mon Sep 17 00:00:00 2001 From: Chris--A Date: Fri, 19 Jun 2015 13:07:35 +1000 Subject: [PATCH 2/5] =?UTF-8?q?This=20is=20a=20bug=20fix=20which=20prevent?= =?UTF-8?q?s=20parseFloat=20from=20proceeding=20past=20multiple=20decimals?= =?UTF-8?q?=20'.'=20in=20the=20stream.=20Only=20one=20can=20be=20accepted?= =?UTF-8?q?=20for=20valid=20decimal=20numbers.=EF=BB=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hardware/arduino/avr/cores/arduino/Stream.cpp | 2 +- hardware/arduino/sam/cores/arduino/Stream.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/Stream.cpp b/hardware/arduino/avr/cores/arduino/Stream.cpp index 1f2f074f0d3..f67b431a10d 100644 --- a/hardware/arduino/avr/cores/arduino/Stream.cpp +++ b/hardware/arduino/avr/cores/arduino/Stream.cpp @@ -185,7 +185,7 @@ float Stream::parseFloat(char skipChar){ read(); // consume the character we got with peek c = timedPeek(); } - while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + while( (c >= '0' && c <= '9') || c == '.' && !isFraction || c == skipChar ); if(isNegative) value = -value; diff --git a/hardware/arduino/sam/cores/arduino/Stream.cpp b/hardware/arduino/sam/cores/arduino/Stream.cpp index 1f2f074f0d3..f67b431a10d 100644 --- a/hardware/arduino/sam/cores/arduino/Stream.cpp +++ b/hardware/arduino/sam/cores/arduino/Stream.cpp @@ -185,7 +185,7 @@ float Stream::parseFloat(char skipChar){ read(); // consume the character we got with peek c = timedPeek(); } - while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + while( (c >= '0' && c <= '9') || c == '.' && !isFraction || c == skipChar ); if(isNegative) value = -value; From 004838abec7dbebc6c14064fe3a8ae1a4becaca4 Mon Sep 17 00:00:00 2001 From: Chris--A Date: Tue, 16 Jun 2015 22:50:59 +1000 Subject: [PATCH 3/5] This adds control of Stream::parseInt/float lookahead. Its default is SKIP_ALL which reflects previous versions. However SKIP_NONE, and SKIP_WHITESPACE can refine this behaviour. A parameter used in the protected overloads of parseInt/Float has been changed from `skipChar` to `ignore`. --- hardware/arduino/avr/cores/arduino/Stream.cpp | 41 +++++++++++------- hardware/arduino/avr/cores/arduino/Stream.h | 29 +++++++++---- hardware/arduino/sam/cores/arduino/Stream.cpp | 43 ++++++++++++------- hardware/arduino/sam/cores/arduino/Stream.h | 29 +++++++++---- 4 files changed, 93 insertions(+), 49 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/Stream.cpp b/hardware/arduino/avr/cores/arduino/Stream.cpp index f67b431a10d..61ad67851d7 100644 --- a/hardware/arduino/avr/cores/arduino/Stream.cpp +++ b/hardware/arduino/avr/cores/arduino/Stream.cpp @@ -54,7 +54,7 @@ int Stream::timedPeek() // returns peek of the next digit in the stream or -1 if timeout // discards non-numeric characters -int Stream::peekNextDigit( bool detectDecimal ) +int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) { int c; while (1) { @@ -65,6 +65,17 @@ int Stream::peekNextDigit( bool detectDecimal ) c >= '0' && c <= '9' || detectDecimal && c == '.') return c; + switch( lookahead ){ + case SKIP_NONE: return -1; // Fail code. + case SKIP_WHITESPACE: + switch( c ){ + case ' ': + case '\t': + case '\r': + case '\n': break; + default: return -1; // Fail code. + } + } read(); // discard non-numeric } } @@ -114,26 +125,26 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t // 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. -long Stream::parseInt() +long Stream::parseInt(LookaheadMode lookahead) { - return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) + return parseInt(lookahead, NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) } -// as above but a given skipChar is ignored +// as above but 'ignore' is ignored // this allows format characters (typically commas) in values to be ignored -long Stream::parseInt(char skipChar) +long Stream::parseInt(LookaheadMode lookahead, char ignore) { bool isNegative = false; long value = 0; int c; - c = peekNextDigit(false); + c = peekNextDigit(lookahead, false); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout do{ - if(c == skipChar) + if(c == ignore) ; // ignore this charactor else if(c == '-') isNegative = true; @@ -142,7 +153,7 @@ long Stream::parseInt(char skipChar) read(); // consume the character we got with peek c = timedPeek(); } - while( (c >= '0' && c <= '9') || c == skipChar ); + while( (c >= '0' && c <= '9') || c == ignore ); if(isNegative) value = -value; @@ -151,27 +162,27 @@ long Stream::parseInt(char skipChar) // as parseInt but returns a floating point value -float Stream::parseFloat() +float Stream::parseFloat(LookaheadMode lookahead) { - return parseFloat(NO_SKIP_CHAR); + return parseFloat(lookahead, NO_SKIP_CHAR); } -// as above but the given skipChar is ignored +// as above but the given ignore is ignored // this allows format characters (typically commas) in values to be ignored -float Stream::parseFloat(char skipChar){ +float Stream::parseFloat(LookaheadMode lookahead, char ignore){ bool isNegative = false; bool isFraction = false; long value = 0; char c; float fraction = 1.0; - c = peekNextDigit(true); + c = peekNextDigit(lookahead, true); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout do{ - if(c == skipChar) + if(c == ignore) ; // ignore else if(c == '-') isNegative = true; @@ -185,7 +196,7 @@ float Stream::parseFloat(char skipChar){ read(); // consume the character we got with peek c = timedPeek(); } - while( (c >= '0' && c <= '9') || c == '.' && !isFraction || c == skipChar ); + while( (c >= '0' && c <= '9') || c == '.' && !isFraction || c == ignore ); if(isNegative) value = -value; diff --git a/hardware/arduino/avr/cores/arduino/Stream.h b/hardware/arduino/avr/cores/arduino/Stream.h index 4bc0036ca7f..8b34c6a9ee7 100644 --- a/hardware/arduino/avr/cores/arduino/Stream.h +++ b/hardware/arduino/avr/cores/arduino/Stream.h @@ -28,13 +28,22 @@ // compatability macros for testing /* #define getInt() parseInt() -#define getInt(skipChar) parseInt(skipchar) +#define getInt(ignore) parseInt(ignore) #define getFloat() parseFloat() -#define getFloat(skipChar) parseFloat(skipChar) +#define getFloat(ignore) parseFloat(ignore) #define getString( pre_string, post_string, buffer, length) readBytesBetween( pre_string, terminator, buffer, length) */ +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode{ + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + class Stream : public Print { protected: @@ -42,7 +51,7 @@ class Stream : public Print unsigned long _startMillis; // used for timeout measurement int timedRead(); // private method to read stream with timeout int timedPeek(); // private method to peek stream with timeout - int peekNextDigit( bool detectDecimal ); // returns the next numeric digit in the stream or -1 if timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout public: virtual int available() = 0; @@ -73,11 +82,11 @@ class Stream : public Print bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } - long parseInt(); // returns the first valid (long) integer value from the current position. + long parseInt(LookaheadMode lookahead = SKIP_ALL); // 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. - float parseFloat(); // float version of parseInt + float parseFloat(LookaheadMode lookahead = SKIP_ALL); // float version of parseInt size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } @@ -94,11 +103,13 @@ class Stream : public Print String readStringUntil(char terminator); protected: - long parseInt(char skipChar); // as above but the given skipChar is ignored - // as above but the given skipChar is ignored + long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } + long parseInt(LookaheadMode lookahead, char ignore); // as above but the given ignore is ignored + // as above but 'ignore' is ignored // this allows format characters (typically commas) in values to be ignored - - float parseFloat(char skipChar); // as above but the given skipChar is ignored + + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + float parseFloat(LookaheadMode lookahead, char ignore); // as above but the given ignore is ignored struct MultiTarget { const char *str; // string you're searching for diff --git a/hardware/arduino/sam/cores/arduino/Stream.cpp b/hardware/arduino/sam/cores/arduino/Stream.cpp index f67b431a10d..967d64ce61e 100644 --- a/hardware/arduino/sam/cores/arduino/Stream.cpp +++ b/hardware/arduino/sam/cores/arduino/Stream.cpp @@ -54,7 +54,7 @@ int Stream::timedPeek() // returns peek of the next digit in the stream or -1 if timeout // discards non-numeric characters -int Stream::peekNextDigit( bool detectDecimal ) +int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal ) { int c; while (1) { @@ -65,6 +65,17 @@ int Stream::peekNextDigit( bool detectDecimal ) c >= '0' && c <= '9' || detectDecimal && c == '.') return c; + switch( lookahead ){ + case SKIP_NONE: return -1; // Fail code. + case SKIP_WHITESPACE: + switch( c ){ + case ' ': + case '\t': + case '\r': + case '\n': break; + default: return -1; // Fail code. + } + } read(); // discard non-numeric } } @@ -114,27 +125,27 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t // 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. -long Stream::parseInt() +long Stream::parseInt(LookaheadMode lookahead) { - return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) + return parseInt(lookahead, NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) } -// as above but a given skipChar is ignored +// as above but 'ignore' is ignored // this allows format characters (typically commas) in values to be ignored -long Stream::parseInt(char skipChar) +long Stream::parseInt(LookaheadMode lookahead, char ignore) { bool isNegative = false; long value = 0; int c; - c = peekNextDigit(false); + c = peekNextDigit(lookahead, false); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout do{ - if(c == skipChar) - ; // ignore this charactor + if(c == ignore) + ; // ignore this character else if(c == '-') isNegative = true; else if(c >= '0' && c <= '9') // is c a digit? @@ -142,7 +153,7 @@ long Stream::parseInt(char skipChar) read(); // consume the character we got with peek c = timedPeek(); } - while( (c >= '0' && c <= '9') || c == skipChar ); + while( (c >= '0' && c <= '9') || c == ignore ); if(isNegative) value = -value; @@ -151,27 +162,27 @@ long Stream::parseInt(char skipChar) // as parseInt but returns a floating point value -float Stream::parseFloat() +float Stream::parseFloat(LookaheadMode lookahead) { - return parseFloat(NO_SKIP_CHAR); + return parseFloat(lookahead, NO_SKIP_CHAR); } -// as above but the given skipChar is ignored +// as above but the given ignore is ignored // this allows format characters (typically commas) in values to be ignored -float Stream::parseFloat(char skipChar){ +float Stream::parseFloat(LookaheadMode lookahead, char ignore){ bool isNegative = false; bool isFraction = false; long value = 0; char c; float fraction = 1.0; - c = peekNextDigit(true); + c = peekNextDigit(lookahead, true); // ignore non numeric leading characters if(c < 0) return 0; // zero returned if timeout do{ - if(c == skipChar) + if(c == ignore) ; // ignore else if(c == '-') isNegative = true; @@ -185,7 +196,7 @@ float Stream::parseFloat(char skipChar){ read(); // consume the character we got with peek c = timedPeek(); } - while( (c >= '0' && c <= '9') || c == '.' && !isFraction || c == skipChar ); + while( (c >= '0' && c <= '9') || c == '.' && !isFraction || c == ignore ); if(isNegative) value = -value; diff --git a/hardware/arduino/sam/cores/arduino/Stream.h b/hardware/arduino/sam/cores/arduino/Stream.h index 15f18106aa4..83e2e6e909b 100644 --- a/hardware/arduino/sam/cores/arduino/Stream.h +++ b/hardware/arduino/sam/cores/arduino/Stream.h @@ -28,13 +28,22 @@ // compatability macros for testing /* #define getInt() parseInt() -#define getInt(skipChar) parseInt(skipchar) +#define getInt(ignore) parseInt(ignore) #define getFloat() parseFloat() -#define getFloat(skipChar) parseFloat(skipChar) +#define getFloat(ignore) parseFloat(ignore) #define getString( pre_string, post_string, buffer, length) readBytesBetween( pre_string, terminator, buffer, length) */ +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode{ + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + class Stream : public Print { protected: @@ -42,7 +51,7 @@ class Stream : public Print unsigned long _startMillis; // used for timeout measurement int timedRead(); // private method to read stream with timeout int timedPeek(); // private method to peek stream with timeout - int peekNextDigit( bool detectDecimal ); // returns the next numeric digit in the stream or -1 if timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout public: virtual int available() = 0; @@ -71,11 +80,11 @@ class Stream : public Print bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } - long parseInt(); // returns the first valid (long) integer value from the current position. + long parseInt(LookaheadMode lookahead = SKIP_ALL); // 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. - float parseFloat(); // float version of parseInt + float parseFloat(LookaheadMode lookahead = SKIP_ALL); // float version of parseInt size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } @@ -92,11 +101,13 @@ class Stream : public Print String readStringUntil(char terminator); protected: - long parseInt(char skipChar); // as above but the given skipChar is ignored - // as above but the given skipChar is ignored + long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } + long parseInt(LookaheadMode lookahead, char ignore); // as above but the given ignore is ignored + // as above but 'ignore' is ignored // this allows format characters (typically commas) in values to be ignored - - float parseFloat(char skipChar); // as above but the given skipChar is ignored + + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + float parseFloat(LookaheadMode lookahead, char ignore); // as above but the given ignore is ignored struct MultiTarget { const char *str; // string you're searching for From 82e1a4c01dd2b0bea6e4f71c730d6612fa21f8b7 Mon Sep 17 00:00:00 2001 From: Chris--A Date: Mon, 22 Jun 2015 18:58:28 +1000 Subject: [PATCH 4/5] Add Stream::find(char); to SAM core. This is a feature added to the AVR core here: https://github.com/arduino/Arduino/commit/ed1b8eb486d39b4227af6f950b3ef4b7ab515adb It allows using the find method with a single char (#847). --- hardware/arduino/sam/cores/arduino/Stream.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hardware/arduino/sam/cores/arduino/Stream.h b/hardware/arduino/sam/cores/arduino/Stream.h index 83e2e6e909b..6abf0762d94 100644 --- a/hardware/arduino/sam/cores/arduino/Stream.h +++ b/hardware/arduino/sam/cores/arduino/Stream.h @@ -73,6 +73,8 @@ class Stream : public Print 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); } From 876e5402688e4c3cefbdc372b105af076cdc24c9 Mon Sep 17 00:00:00 2001 From: Chris--A Date: Thu, 9 Jul 2015 18:32:40 +1000 Subject: [PATCH 5/5] Make protected Stream::parseInt/Float overloads public. Stream::parseInt & Stream::parseFloat previously had protected overloads which allowed skipping a custom character. This commit brings this feature to the public interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To keep the public API simpler, the single paramter overload remains protected. However its functionality is available in the public interface using the two parameter overload. --- hardware/arduino/avr/cores/arduino/Stream.cpp | 24 ++++------------ hardware/arduino/avr/cores/arduino/Stream.h | 27 ++++++++++-------- hardware/arduino/sam/cores/arduino/Stream.cpp | 24 ++++------------ hardware/arduino/sam/cores/arduino/Stream.h | 28 +++++++++++-------- 4 files changed, 41 insertions(+), 62 deletions(-) diff --git a/hardware/arduino/avr/cores/arduino/Stream.cpp b/hardware/arduino/avr/cores/arduino/Stream.cpp index 61ad67851d7..758b9d270cc 100644 --- a/hardware/arduino/avr/cores/arduino/Stream.cpp +++ b/hardware/arduino/avr/cores/arduino/Stream.cpp @@ -26,7 +26,6 @@ #include "Stream.h" #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait -#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field // private method to read stream with timeout int Stream::timedRead() @@ -121,17 +120,11 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t } } - // 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. -long Stream::parseInt(LookaheadMode lookahead) -{ - return parseInt(lookahead, NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) -} - -// as above but 'ignore' is ignored -// this allows format characters (typically commas) in values to be ignored +// lookahead determines how parseInt looks ahead in the stream. +// See LookaheadMode enumeration at the top of the file. +// Lookahead is terminated by the first character that is not a valid part of an integer. +// Once parsing commences, 'ignore' will be skipped in the stream. long Stream::parseInt(LookaheadMode lookahead, char ignore) { bool isNegative = false; @@ -160,16 +153,9 @@ long Stream::parseInt(LookaheadMode lookahead, char ignore) return value; } - // as parseInt but returns a floating point value -float Stream::parseFloat(LookaheadMode lookahead) +float Stream::parseFloat(LookaheadMode lookahead, char ignore) { - return parseFloat(lookahead, NO_SKIP_CHAR); -} - -// as above but the given ignore is ignored -// this allows format characters (typically commas) in values to be ignored -float Stream::parseFloat(LookaheadMode lookahead, char ignore){ bool isNegative = false; bool isFraction = false; long value = 0; diff --git a/hardware/arduino/avr/cores/arduino/Stream.h b/hardware/arduino/avr/cores/arduino/Stream.h index 8b34c6a9ee7..db71bb6cd5f 100644 --- a/hardware/arduino/avr/cores/arduino/Stream.h +++ b/hardware/arduino/avr/cores/arduino/Stream.h @@ -44,6 +44,8 @@ enum LookaheadMode{ SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. }; +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + class Stream : public Print { protected: @@ -81,12 +83,15 @@ class Stream : public Print 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); } + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. - long parseInt(LookaheadMode lookahead = SKIP_ALL); // 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. - - float parseFloat(LookaheadMode lookahead = SKIP_ALL); // float version of parseInt + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } @@ -104,12 +109,10 @@ class Stream : public Print protected: long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } - long parseInt(LookaheadMode lookahead, char ignore); // as above but the given ignore is ignored - // as above but 'ignore' is ignored - // this allows format characters (typically commas) in values to be ignored - - float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } - float parseFloat(LookaheadMode lookahead, char ignore); // as above but the given ignore is ignored + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. struct MultiTarget { const char *str; // string you're searching for @@ -122,5 +125,5 @@ class Stream : public Print int findMulti(struct MultiTarget *targets, int tCount); }; - +#undef NO_IGNORE_CHAR #endif diff --git a/hardware/arduino/sam/cores/arduino/Stream.cpp b/hardware/arduino/sam/cores/arduino/Stream.cpp index 967d64ce61e..b25f8691ed3 100644 --- a/hardware/arduino/sam/cores/arduino/Stream.cpp +++ b/hardware/arduino/sam/cores/arduino/Stream.cpp @@ -26,7 +26,6 @@ #include "Stream.h" #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait -#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field // private method to read stream with timeout int Stream::timedRead() @@ -121,17 +120,11 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t } } - // 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. -long Stream::parseInt(LookaheadMode lookahead) -{ - return parseInt(lookahead, NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) -} - -// as above but 'ignore' is ignored -// this allows format characters (typically commas) in values to be ignored +// lookahead determines how parseInt looks ahead in the stream. +// See LookaheadMode enumeration at the top of the file. +// Lookahead is terminated by the first character that is not a valid part of an integer. +// Once parsing commences, 'ignore' will be skipped in the stream. long Stream::parseInt(LookaheadMode lookahead, char ignore) { bool isNegative = false; @@ -160,16 +153,9 @@ long Stream::parseInt(LookaheadMode lookahead, char ignore) return value; } - // as parseInt but returns a floating point value -float Stream::parseFloat(LookaheadMode lookahead) +float Stream::parseFloat(LookaheadMode lookahead, char ignore) { - return parseFloat(lookahead, NO_SKIP_CHAR); -} - -// as above but the given ignore is ignored -// this allows format characters (typically commas) in values to be ignored -float Stream::parseFloat(LookaheadMode lookahead, char ignore){ bool isNegative = false; bool isFraction = false; long value = 0; diff --git a/hardware/arduino/sam/cores/arduino/Stream.h b/hardware/arduino/sam/cores/arduino/Stream.h index 6abf0762d94..db71bb6cd5f 100644 --- a/hardware/arduino/sam/cores/arduino/Stream.h +++ b/hardware/arduino/sam/cores/arduino/Stream.h @@ -44,6 +44,8 @@ enum LookaheadMode{ SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. }; +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + class Stream : public Print { protected: @@ -74,19 +76,22 @@ class Stream : public Print // 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); } + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. - long parseInt(LookaheadMode lookahead = SKIP_ALL); // 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. - - float parseFloat(LookaheadMode lookahead = SKIP_ALL); // float version of parseInt + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } @@ -104,12 +109,10 @@ class Stream : public Print protected: long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } - long parseInt(LookaheadMode lookahead, char ignore); // as above but the given ignore is ignored - // as above but 'ignore' is ignored - // this allows format characters (typically commas) in values to be ignored - - float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } - float parseFloat(LookaheadMode lookahead, char ignore); // as above but the given ignore is ignored + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. struct MultiTarget { const char *str; // string you're searching for @@ -122,4 +125,5 @@ class Stream : public Print int findMulti(struct MultiTarget *targets, int tCount); }; +#undef NO_IGNORE_CHAR #endif