Skip to content

Commit 4d73331

Browse files
committed
Extract Stream methods into an IStream
This allows streams to exist that are input-only, such as a keyboard.
1 parent e69ce9c commit 4d73331

File tree

3 files changed

+148
-118
lines changed

3 files changed

+148
-118
lines changed

hardware/arduino/avr/cores/arduino/Stream.cpp renamed to hardware/arduino/avr/cores/arduino/IStream.cpp

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Stream.cpp - adds parsing methods to Stream class
2+
IStream.cpp - adds parsing methods to IStream class
33
Copyright (c) 2008 David A. Mellis. All right reserved.
44
55
This library is free software; you can redistribute it and/or
@@ -23,12 +23,12 @@
2323
*/
2424

2525
#include "Arduino.h"
26-
#include "Stream.h"
26+
#include "IStream.h"
2727

2828
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
2929

3030
// protected method to read stream with timeout
31-
int Stream::timedRead()
31+
int IStream::timedRead()
3232
{
3333
int c;
3434
_startMillis = millis();
@@ -40,7 +40,7 @@ int Stream::timedRead()
4040
}
4141

4242
// protected method to peek stream with timeout
43-
int Stream::timedPeek()
43+
int IStream::timedPeek()
4444
{
4545
int c;
4646
_startMillis = millis();
@@ -53,7 +53,7 @@ int Stream::timedPeek()
5353

5454
// returns peek of the next digit in the stream or -1 if timeout
5555
// discards non-numeric characters
56-
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
56+
int IStream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
5757
{
5858
int c;
5959
while (1) {
@@ -84,34 +84,34 @@ int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
8484
// Public Methods
8585
//////////////////////////////////////////////////////////////
8686

87-
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
87+
void IStream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
8888
{
8989
_timeout = timeout;
9090
}
9191

9292
// find returns true if the target string is found
93-
bool Stream::find(char *target)
93+
bool IStream::find(char *target)
9494
{
9595
return findUntil(target, strlen(target), NULL, 0);
9696
}
9797

9898
// reads data from the stream until the target string of given length is found
9999
// returns true if target string is found, false if timed out
100-
bool Stream::find(char *target, size_t length)
100+
bool IStream::find(char *target, size_t length)
101101
{
102102
return findUntil(target, length, NULL, 0);
103103
}
104104

105105
// as find but search ends if the terminator string is found
106-
bool Stream::findUntil(char *target, char *terminator)
106+
bool IStream::findUntil(char *target, char *terminator)
107107
{
108108
return findUntil(target, strlen(target), terminator, strlen(terminator));
109109
}
110110

111111
// reads data from the stream until the target string of the given length is found
112112
// search terminated if the terminator string is found
113113
// returns true if target string is found, false if terminated or timed out
114-
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
114+
bool IStream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
115115
{
116116
if (terminator == NULL) {
117117
MultiTarget t[1] = {{target, targetLen, 0}};
@@ -127,7 +127,7 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t
127127
// See LookaheadMode enumeration at the top of the file.
128128
// Lookahead is terminated by the first character that is not a valid part of an integer.
129129
// Once parsing commences, 'ignore' will be skipped in the stream.
130-
long Stream::parseInt(LookaheadMode lookahead, char ignore)
130+
long IStream::parseInt(LookaheadMode lookahead, char ignore)
131131
{
132132
bool isNegative = false;
133133
long value = 0;
@@ -156,7 +156,7 @@ long Stream::parseInt(LookaheadMode lookahead, char ignore)
156156
}
157157

158158
// as parseInt but returns a floating point value
159-
float Stream::parseFloat(LookaheadMode lookahead, char ignore)
159+
float IStream::parseFloat(LookaheadMode lookahead, char ignore)
160160
{
161161
bool isNegative = false;
162162
bool isFraction = false;
@@ -199,7 +199,7 @@ float Stream::parseFloat(LookaheadMode lookahead, char ignore)
199199
// returns the number of characters placed in the buffer
200200
// the buffer is NOT null terminated.
201201
//
202-
size_t Stream::readBytes(char *buffer, size_t length)
202+
size_t IStream::readBytes(char *buffer, size_t length)
203203
{
204204
size_t count = 0;
205205
while (count < length) {
@@ -216,7 +216,7 @@ size_t Stream::readBytes(char *buffer, size_t length)
216216
// terminates if length characters have been read, timeout, or if the terminator character detected
217217
// returns the number of characters placed in the buffer (0 means no valid data found)
218218

219-
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
219+
size_t IStream::readBytesUntil(char terminator, char *buffer, size_t length)
220220
{
221221
if (length < 1) return 0;
222222
size_t index = 0;
@@ -229,7 +229,7 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
229229
return index; // return number of characters, not including null terminator
230230
}
231231

232-
String Stream::readString()
232+
String IStream::readString()
233233
{
234234
String ret;
235235
int c = timedRead();
@@ -241,7 +241,7 @@ String Stream::readString()
241241
return ret;
242242
}
243243

244-
String Stream::readStringUntil(char terminator)
244+
String IStream::readStringUntil(char terminator)
245245
{
246246
String ret;
247247
int c = timedRead();
@@ -253,7 +253,7 @@ String Stream::readStringUntil(char terminator)
253253
return ret;
254254
}
255255

256-
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
256+
int IStream::findMulti( struct IStream::MultiTarget *targets, int tCount) {
257257
// any zero length target string automatically matches and would make
258258
// a mess of the rest of the algorithm.
259259
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
IStream.h - base class for character-based input streams.
3+
Copyright (c) 2010 David A. Mellis. All right reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
19+
parsing functions based on TextFinder library by Michael Margolis
20+
*/
21+
22+
#ifndef IStream_h
23+
#define IStream_h
24+
25+
#include <inttypes.h>
26+
27+
// compatability macros for testing
28+
/*
29+
#define getInt() parseInt()
30+
#define getInt(ignore) parseInt(ignore)
31+
#define getFloat() parseFloat()
32+
#define getFloat(ignore) parseFloat(ignore)
33+
#define getString( pre_string, post_string, buffer, length)
34+
readBytesBetween( pre_string, terminator, buffer, length)
35+
*/
36+
37+
// This enumeration provides the lookahead options for parseInt(), parseFloat()
38+
// The rules set out here are used until either the first valid character is found
39+
// or a time out occurs due to lack of input.
40+
enum LookaheadMode{
41+
SKIP_ALL, // All invalid characters are ignored.
42+
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
43+
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
44+
};
45+
46+
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
47+
48+
class IStream
49+
{
50+
protected:
51+
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
52+
unsigned long _startMillis; // used for timeout measurement
53+
int timedRead(); // private method to read stream with timeout
54+
int timedPeek(); // private method to peek stream with timeout
55+
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
56+
57+
public:
58+
virtual int available() = 0;
59+
virtual int read() = 0;
60+
virtual int peek() = 0;
61+
62+
IStream() {_timeout=1000;}
63+
64+
// parsing methods
65+
66+
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
67+
unsigned long getTimeout(void) { return _timeout; }
68+
69+
bool find(char *target); // reads data from the stream until the target string is found
70+
bool find(uint8_t *target) { return find ((char *)target); }
71+
// returns true if target string is found, false if timed out (see setTimeout)
72+
73+
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
74+
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
75+
// returns true if target string is found, false if timed out
76+
77+
bool find(char target) { return find (&target, 1); }
78+
79+
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
80+
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
81+
82+
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
83+
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
84+
85+
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
86+
// returns the first valid (long) integer value from the current position.
87+
// lookahead determines how parseInt looks ahead in the stream.
88+
// See LookaheadMode enumeration at the top of the file.
89+
// Lookahead is terminated by the first character that is not a valid part of an integer.
90+
// Once parsing commences, 'ignore' will be skipped in the stream.
91+
92+
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
93+
// float version of parseInt
94+
95+
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
96+
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
97+
// terminates if length characters have been read or timeout (see setTimeout)
98+
// returns the number of characters placed in the buffer (0 means no valid data found)
99+
100+
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
101+
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
102+
// terminates if length characters have been read, timeout, or if the terminator character detected
103+
// returns the number of characters placed in the buffer (0 means no valid data found)
104+
105+
// Arduino String functions to be added here
106+
String readString();
107+
String readStringUntil(char terminator);
108+
109+
protected:
110+
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
111+
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
112+
// These overload exists for compatibility with any class that has derived
113+
// IStream and used parseFloat/Int with a custom ignore character. To keep
114+
// the public API simple, these overload remains protected.
115+
116+
struct MultiTarget {
117+
const char *str; // string you're searching for
118+
size_t len; // length of string you're searching for
119+
size_t index; // index used by the search routine.
120+
};
121+
122+
// This allows you to search for an arbitrary number of strings.
123+
// Returns index of the target that is found first or -1 if timeout occurs.
124+
int findMulti(struct MultiTarget *targets, int tCount);
125+
};
126+
127+
#undef NO_IGNORE_CHAR
128+
#endif
+3-101
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Stream.h - base class for character-based streams.
2+
Stream.h - base class for character-based input/output streams.
33
Copyright (c) 2010 David A. Mellis. All right reserved.
44
55
This library is free software; you can redistribute it and/or
@@ -15,115 +15,17 @@
1515
You should have received a copy of the GNU Lesser General Public
1616
License along with this library; if not, write to the Free Software
1717
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18-
19-
parsing functions based on TextFinder library by Michael Margolis
2018
*/
2119

2220
#ifndef Stream_h
2321
#define Stream_h
2422

2523
#include <inttypes.h>
2624
#include "Print.h"
25+
#include "IStream.h"
2726

28-
// compatability macros for testing
29-
/*
30-
#define getInt() parseInt()
31-
#define getInt(ignore) parseInt(ignore)
32-
#define getFloat() parseFloat()
33-
#define getFloat(ignore) parseFloat(ignore)
34-
#define getString( pre_string, post_string, buffer, length)
35-
readBytesBetween( pre_string, terminator, buffer, length)
36-
*/
37-
38-
// This enumeration provides the lookahead options for parseInt(), parseFloat()
39-
// The rules set out here are used until either the first valid character is found
40-
// or a time out occurs due to lack of input.
41-
enum LookaheadMode{
42-
SKIP_ALL, // All invalid characters are ignored.
43-
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
44-
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
45-
};
46-
47-
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
48-
49-
class Stream : public Print
27+
class Stream : public Print, public IStream
5028
{
51-
protected:
52-
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
53-
unsigned long _startMillis; // used for timeout measurement
54-
int timedRead(); // read stream with timeout
55-
int timedPeek(); // peek stream with timeout
56-
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
57-
58-
public:
59-
virtual int available() = 0;
60-
virtual int read() = 0;
61-
virtual int peek() = 0;
62-
63-
Stream() {_timeout=1000;}
64-
65-
// parsing methods
66-
67-
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
68-
unsigned long getTimeout(void) { return _timeout; }
69-
70-
bool find(char *target); // reads data from the stream until the target string is found
71-
bool find(uint8_t *target) { return find ((char *)target); }
72-
// returns true if target string is found, false if timed out (see setTimeout)
73-
74-
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
75-
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
76-
// returns true if target string is found, false if timed out
77-
78-
bool find(char target) { return find (&target, 1); }
79-
80-
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
81-
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
82-
83-
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
84-
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
85-
86-
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
87-
// returns the first valid (long) integer value from the current position.
88-
// lookahead determines how parseInt looks ahead in the stream.
89-
// See LookaheadMode enumeration at the top of the file.
90-
// Lookahead is terminated by the first character that is not a valid part of an integer.
91-
// Once parsing commences, 'ignore' will be skipped in the stream.
92-
93-
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
94-
// float version of parseInt
95-
96-
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
97-
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
98-
// terminates if length characters have been read or timeout (see setTimeout)
99-
// returns the number of characters placed in the buffer (0 means no valid data found)
100-
101-
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
102-
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
103-
// terminates if length characters have been read, timeout, or if the terminator character detected
104-
// returns the number of characters placed in the buffer (0 means no valid data found)
105-
106-
// Arduino String functions to be added here
107-
String readString();
108-
String readStringUntil(char terminator);
109-
110-
protected:
111-
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
112-
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
113-
// These overload exists for compatibility with any class that has derived
114-
// Stream and used parseFloat/Int with a custom ignore character. To keep
115-
// the public API simple, these overload remains protected.
116-
117-
struct MultiTarget {
118-
const char *str; // string you're searching for
119-
size_t len; // length of string you're searching for
120-
size_t index; // index used by the search routine.
121-
};
122-
123-
// This allows you to search for an arbitrary number of strings.
124-
// Returns index of the target that is found first or -1 if timeout occurs.
125-
int findMulti(struct MultiTarget *targets, int tCount);
12629
};
12730

128-
#undef NO_IGNORE_CHAR
12931
#endif

0 commit comments

Comments
 (0)