source: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/Stream.cpp@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 7.0 KB
Line 
1/*
2 Stream.cpp - adds parsing methods to Stream class
3 Copyright (c) 2008 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 Created July 2011
20 parsing functions based on TextFinder library by Michael Margolis
21 */
22
23#include "Arduino.h"
24#include "Stream.h"
25
26#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
27#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
28
29// private method to read stream with timeout
30int Stream::timedRead()
31{
32 int c;
33 _startMillis = millis();
34 do {
35 c = read();
36 if (c >= 0) return c;
37 } while(millis() - _startMillis < _timeout);
38 return -1; // -1 indicates timeout
39}
40
41// private method to peek stream with timeout
42int Stream::timedPeek()
43{
44 int c;
45 _startMillis = millis();
46 do {
47 c = peek();
48 if (c >= 0) return c;
49 } while(millis() - _startMillis < _timeout);
50 return -1; // -1 indicates timeout
51}
52
53// returns peek of the next digit in the stream or -1 if timeout
54// discards non-numeric characters
55int Stream::peekNextDigit()
56{
57 int c;
58 while (1) {
59 c = timedPeek();
60 if (c < 0) return c; // timeout
61 if (c == '-') return c;
62 if (c >= '0' && c <= '9') return c;
63 read(); // discard non-numeric
64 }
65}
66
67// Public Methods
68//////////////////////////////////////////////////////////////
69
70void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
71{
72 _timeout = timeout;
73}
74
75 // find returns true if the target string is found
76bool Stream::find(char *target)
77{
78 return findUntil(target, "");
79}
80
81// reads data from the stream until the target string of given length is found
82// returns true if target string is found, false if timed out
83bool Stream::find(char *target, size_t length)
84{
85 return findUntil(target, length, NULL, 0);
86}
87
88// as find but search ends if the terminator string is found
89bool Stream::findUntil(char *target, char *terminator)
90{
91 return findUntil(target, strlen(target), terminator, strlen(terminator));
92}
93
94// reads data from the stream until the target string of the given length is found
95// search terminated if the terminator string is found
96// returns true if target string is found, false if terminated or timed out
97bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
98{
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 if(++index >= targetLen){ // return true if all chars in the target match
112 return true;
113 }
114 }
115
116 if(termLen > 0 && c == terminator[termIndex]){
117 if(++termIndex >= termLen)
118 return false; // return false if terminate string found before target string
119 }
120 else
121 termIndex = 0;
122 }
123 return false;
124}
125
126
127// returns the first valid (long) integer value from the current position.
128// initial characters that are not digits (or the minus sign) are skipped
129// function is terminated by the first character that is not a digit.
130long Stream::parseInt()
131{
132 return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
133}
134
135// as above but a given skipChar is ignored
136// this allows format characters (typically commas) in values to be ignored
137long Stream::parseInt(char skipChar)
138{
139 boolean isNegative = false;
140 long value = 0;
141 int c;
142
143 c = peekNextDigit();
144 // ignore non numeric leading characters
145 if(c < 0)
146 return 0; // zero returned if timeout
147
148 do{
149 if(c == skipChar)
150 ; // ignore this charactor
151 else if(c == '-')
152 isNegative = true;
153 else if(c >= '0' && c <= '9') // is c a digit?
154 value = value * 10 + c - '0';
155 read(); // consume the character we got with peek
156 c = timedPeek();
157 }
158 while( (c >= '0' && c <= '9') || c == skipChar );
159
160 if(isNegative)
161 value = -value;
162 return value;
163}
164
165
166// as parseInt but returns a floating point value
167float Stream::parseFloat()
168{
169 return parseFloat(NO_SKIP_CHAR);
170}
171
172// as above but the given skipChar is ignored
173// this allows format characters (typically commas) in values to be ignored
174float Stream::parseFloat(char skipChar){
175 boolean isNegative = false;
176 boolean isFraction = false;
177 long value = 0;
178 int c;
179 float fraction = 1.0;
180
181 c = peekNextDigit();
182 // ignore non numeric leading characters
183 if(c < 0)
184 return 0; // zero returned if timeout
185
186 do{
187 if(c == skipChar)
188 ; // ignore
189 else if(c == '-')
190 isNegative = true;
191 else if (c == '.')
192 isFraction = true;
193 else if(c >= '0' && c <= '9') { // is c a digit?
194 value = value * 10 + c - '0';
195 if(isFraction)
196 fraction *= 0.1;
197 }
198 read(); // consume the character we got with peek
199 c = timedPeek();
200 }
201 while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
202
203 if(isNegative)
204 value = -value;
205 if(isFraction)
206 return value * fraction;
207 else
208 return value;
209}
210
211// read characters from stream into buffer
212// terminates if length characters have been read, or timeout (see setTimeout)
213// returns the number of characters placed in the buffer
214// the buffer is NOT null terminated.
215//
216size_t Stream::readBytes(char *buffer, size_t length)
217{
218 size_t count = 0;
219 while (count < length) {
220 int c = timedRead();
221 if (c < 0) break;
222 *buffer++ = (char)c;
223 count++;
224 }
225 return count;
226}
227
228
229// as readBytes with terminator character
230// terminates if length characters have been read, timeout, or if the terminator character detected
231// returns the number of characters placed in the buffer (0 means no valid data found)
232
233size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
234{
235 if (length < 1) return 0;
236 size_t index = 0;
237 while (index < length) {
238 int c = timedRead();
239 if (c < 0 || c == terminator) break;
240 *buffer++ = (char)c;
241 index++;
242 }
243 return index; // return number of characters, not including null terminator
244}
245
246String Stream::readString()
247{
248 String ret;
249 int c = timedRead();
250 while (c >= 0)
251 {
252 ret += (char)c;
253 c = timedRead();
254 }
255 return ret;
256}
257
258String Stream::readStringUntil(char terminator)
259{
260 String ret;
261 int c = timedRead();
262 while (c >= 0 && c != terminator)
263 {
264 ret += (char)c;
265 c = timedRead();
266 }
267 return ret;
268}
269
Note: See TracBrowser for help on using the repository browser.