Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0f84e93

Browse files
committed
Added Stream class
1 parentea00d59 commit0f84e93

File tree

3 files changed

+448
-0
lines changed

3 files changed

+448
-0
lines changed

‎api/ArduinoAPI.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#ifdef__cplusplus
2929
#include"Print.h"
3030
#include"String.h"
31+
#include"Stream.h"
3132
#endif
3233

3334
#endif

‎api/Stream.cpp‎

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
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+
findMulti/findUntil routines written by Jim Leonard/Xuth
23+
*/
24+
25+
#include"Arduino.h"
26+
#include"Stream.h"
27+
28+
#definePARSE_TIMEOUT1000// default number of milli-seconds to wait
29+
30+
// private method to read stream with timeout
31+
intStream::timedRead()
32+
{
33+
int c;
34+
_startMillis =millis();
35+
do {
36+
c =read();
37+
if (c >=0)return c;
38+
}while(millis() - _startMillis < _timeout);
39+
return -1;// -1 indicates timeout
40+
}
41+
42+
// private method to peek stream with timeout
43+
intStream::timedPeek()
44+
{
45+
int c;
46+
_startMillis =millis();
47+
do {
48+
c =peek();
49+
if (c >=0)return c;
50+
}while(millis() - _startMillis < _timeout);
51+
return -1;// -1 indicates timeout
52+
}
53+
54+
// returns peek of the next digit in the stream or -1 if timeout
55+
// discards non-numeric characters
56+
intStream::peekNextDigit(LookaheadMode lookahead,bool detectDecimal)
57+
{
58+
int c;
59+
while (1) {
60+
c =timedPeek();
61+
62+
if( c <0 ||
63+
c =='-' ||
64+
(c >='0' && c <='9') ||
65+
(detectDecimal && c =='.'))return c;
66+
67+
switch( lookahead ){
68+
case SKIP_NONE:return -1;// Fail code.
69+
case SKIP_WHITESPACE:
70+
switch( c ){
71+
case'':
72+
case'\t':
73+
case'\r':
74+
case'\n':break;
75+
default:return -1;// Fail code.
76+
}
77+
case SKIP_ALL:
78+
break;
79+
}
80+
read();// discard non-numeric
81+
}
82+
}
83+
84+
// Public Methods
85+
//////////////////////////////////////////////////////////////
86+
87+
voidStream::setTimeout(unsignedlong timeout)// sets the maximum number of milliseconds to wait
88+
{
89+
_timeout = timeout;
90+
}
91+
92+
// find returns true if the target string is found
93+
boolStream::find(char *target)
94+
{
95+
returnfindUntil(target,strlen(target),NULL,0);
96+
}
97+
98+
// reads data from the stream until the target string of given length is found
99+
// returns true if target string is found, false if timed out
100+
boolStream::find(char *target,size_t length)
101+
{
102+
returnfindUntil(target, length,NULL,0);
103+
}
104+
105+
// as find but search ends if the terminator string is found
106+
boolStream::findUntil(char *target,char *terminator)
107+
{
108+
returnfindUntil(target,strlen(target), terminator,strlen(terminator));
109+
}
110+
111+
// reads data from the stream until the target string of the given length is found
112+
// search terminated if the terminator string is found
113+
// returns true if target string is found, false if terminated or timed out
114+
boolStream::findUntil(char *target,size_t targetLen,char *terminator,size_t termLen)
115+
{
116+
if (terminator ==NULL) {
117+
MultiTarget t[1] = {{target, targetLen,0}};
118+
returnfindMulti(t,1) ==0 ?true :false;
119+
}else {
120+
MultiTarget t[2] = {{target, targetLen,0}, {terminator, termLen,0}};
121+
returnfindMulti(t,2) ==0 ?true :false;
122+
}
123+
}
124+
125+
// returns the first valid (long) integer value from the current position.
126+
// lookahead determines how parseInt looks ahead in the stream.
127+
// See LookaheadMode enumeration at the top of the file.
128+
// Lookahead is terminated by the first character that is not a valid part of an integer.
129+
// Once parsing commences, 'ignore' will be skipped in the stream.
130+
longStream::parseInt(LookaheadMode lookahead,char ignore)
131+
{
132+
bool isNegative =false;
133+
long value =0;
134+
int c;
135+
136+
c =peekNextDigit(lookahead,false);
137+
// ignore non numeric leading characters
138+
if(c <0)
139+
return0;// zero returned if timeout
140+
141+
do{
142+
if(c == ignore)
143+
;// ignore this character
144+
elseif(c =='-')
145+
isNegative =true;
146+
elseif(c >='0' && c <='9')// is c a digit?
147+
value = value *10 + c -'0';
148+
read();// consume the character we got with peek
149+
c =timedPeek();
150+
}
151+
while( (c >='0' && c <='9') || c == ignore );
152+
153+
if(isNegative)
154+
value = -value;
155+
return value;
156+
}
157+
158+
// as parseInt but returns a floating point value
159+
floatStream::parseFloat(LookaheadMode lookahead,char ignore)
160+
{
161+
bool isNegative =false;
162+
bool isFraction =false;
163+
long value =0;
164+
int c;
165+
float fraction =1.0;
166+
167+
c =peekNextDigit(lookahead,true);
168+
// ignore non numeric leading characters
169+
if(c <0)
170+
return0;// zero returned if timeout
171+
172+
do{
173+
if(c == ignore)
174+
;// ignore
175+
elseif(c =='-')
176+
isNegative =true;
177+
elseif (c =='.')
178+
isFraction =true;
179+
elseif(c >='0' && c <='9') {// is c a digit?
180+
value = value *10 + c -'0';
181+
if(isFraction)
182+
fraction *=0.1;
183+
}
184+
read();// consume the character we got with peek
185+
c =timedPeek();
186+
}
187+
while( (c >='0' && c <='9') || (c =='.' && !isFraction) || c == ignore );
188+
189+
if(isNegative)
190+
value = -value;
191+
if(isFraction)
192+
return value * fraction;
193+
else
194+
return value;
195+
}
196+
197+
// read characters from stream into buffer
198+
// terminates if length characters have been read, or timeout (see setTimeout)
199+
// returns the number of characters placed in the buffer
200+
// the buffer is NOT null terminated.
201+
//
202+
size_tStream::readBytes(char *buffer,size_t length)
203+
{
204+
size_t count =0;
205+
while (count < length) {
206+
int c =timedRead();
207+
if (c <0)break;
208+
*buffer++ = (char)c;
209+
count++;
210+
}
211+
return count;
212+
}
213+
214+
215+
// as readBytes with terminator character
216+
// terminates if length characters have been read, timeout, or if the terminator character detected
217+
// returns the number of characters placed in the buffer (0 means no valid data found)
218+
219+
size_tStream::readBytesUntil(char terminator,char *buffer,size_t length)
220+
{
221+
if (length <1)return0;
222+
size_t index =0;
223+
while (index < length) {
224+
int c =timedRead();
225+
if (c <0 || c == terminator)break;
226+
*buffer++ = (char)c;
227+
index++;
228+
}
229+
return index;// return number of characters, not including null terminator
230+
}
231+
232+
StringStream::readString()
233+
{
234+
String ret;
235+
int c =timedRead();
236+
while (c >=0)
237+
{
238+
ret += (char)c;
239+
c =timedRead();
240+
}
241+
return ret;
242+
}
243+
244+
StringStream::readStringUntil(char terminator)
245+
{
246+
String ret;
247+
int c =timedRead();
248+
while (c >=0 && c != terminator)
249+
{
250+
ret += (char)c;
251+
c =timedRead();
252+
}
253+
return ret;
254+
}
255+
256+
intStream::findMulti(structStream::MultiTarget *targets,int tCount) {
257+
// any zero length target string automatically matches and would make
258+
// a mess of the rest of the algorithm.
259+
for (structMultiTarget *t = targets; t < targets+tCount; ++t) {
260+
if (t->len <=0)
261+
return t - targets;
262+
}
263+
264+
while (1) {
265+
int c =timedRead();
266+
if (c <0)
267+
return -1;
268+
269+
for (structMultiTarget *t = targets; t < targets+tCount; ++t) {
270+
// the simple case is if we match, deal with that first.
271+
if (c == t->str[t->index]) {
272+
if (++t->index == t->len)
273+
return t - targets;
274+
else
275+
continue;
276+
}
277+
278+
// if not we need to walk back and see if we could have matched further
279+
// down the stream (ie '1112' doesn't match the first position in '11112'
280+
// but it will match the second position so we can't just reset the current
281+
// index to 0 when we find a mismatch.
282+
if (t->index ==0)
283+
continue;
284+
285+
int origIndex = t->index;
286+
do {
287+
--t->index;
288+
// first check if current char works against the new current index
289+
if (c != t->str[t->index])
290+
continue;
291+
292+
// if it's the only char then we're good, nothing more to check
293+
if (t->index ==0) {
294+
t->index++;
295+
break;
296+
}
297+
298+
// otherwise we need to check the rest of the found string
299+
int diff = origIndex - t->index;
300+
size_t i;
301+
for (i =0; i < t->index; ++i) {
302+
if (t->str[i] != t->str[i + diff])
303+
break;
304+
}
305+
306+
// if we successfully got through the previous loop then our current
307+
// index is good.
308+
if (i == t->index) {
309+
t->index++;
310+
break;
311+
}
312+
313+
// otherwise we just try the next index
314+
}while (t->index);
315+
}
316+
}
317+
// unreachable
318+
return -1;
319+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp