/** Copyright (c) 2021-2022, RTduino Development Team** SPDX-License-Identifier: LGPL-v2.1** https://github.com/RTduino/RTduino* https://gitee.com/rtduino/RTduino** Change Logs:* Date Author Notes* 2021年12月10日 Meco Man port to RTduino*//*Stream.cpp - adds parsing methods to Stream classCopyright (c) 2008 David A. Mellis. All right reserved.This library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2.1 of the License, or (at your option) any later version.This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USACreated July 2011parsing functions based on TextFinder library by Michael MargolisfindMulti/findUntil routines written by Jim Leonard/Xuth*/#include "Arduino.h"#include "Stream.h"// protected method to read stream with timeoutint Stream::timedRead(void){int c;_startMillis = millis();do {c = read();if(c >= 0) return c;//yield(); //cherry-pick from esp8266 arduino 55f07f1e08868b855f2ae2fb3b7b42004ff8022f} while(millis() - _startMillis < _timeout);return -1; // -1 indicates timeout}// protected method to peek stream with timeoutint Stream::timedPeek(void){int c;_startMillis = millis();do {c = peek();if(c >= 0) return c;//yield(); //cherry-pick from esp8266 arduino 55f07f1e08868b855f2ae2fb3b7b42004ff8022f} while(millis() - _startMillis < _timeout);return -1; // -1 indicates timeout}// returns peek of the next digit in the stream or -1 if timeout// discards non-numeric charactersint Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal){int c;while (1) {c = timedPeek();if( c < 0 ||c == '-' ||(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.}case SKIP_ALL:break;}read(); // discard non-numeric}}// Public Methods//////////////////////////////////////////////////////////////void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait{_timeout = timeout;}// find returns true if the target string is foundbool Stream::find(const char *target){return findUntil(target, strlen(target), NULL, 0);}// reads data from the stream until the target string of given length is found// returns true if target string is found, false if timed outbool Stream::find(const char *target, size_t length){return findUntil(target, length, NULL, 0);}// as find but search ends if the terminator string is foundbool Stream::findUntil(const char *target, const char *terminator){return findUntil(target, strlen(target), terminator, strlen(terminator));}// reads data from the stream until the target string of the given length is found// search terminated if the terminator string is found// returns true if target string is found, false if terminated or timed outbool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen){if (terminator == NULL) {MultiTarget t[1] = {{target, targetLen, 0}};return findMulti(t, 1) == 0;} else {MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};return findMulti(t, 2) == 0;}}// 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 Stream::parseInt(LookaheadMode lookahead, char ignore){bool isNegative = false;long value = 0;int c;c = peekNextDigit(lookahead, false);// ignore non numeric leading charactersif(c < 0)return 0; // zero returned if timeoutdo{if((char)c == ignore); // ignore this characterelse if(c == '-')isNegative = true;else if(c >= '0' && c <= '9') // is c a digit?value = value * 10 + c - '0';read(); // consume the character we got with peekc = timedPeek();}while( (c >= '0' && c <= '9') || (char)c == ignore );if(isNegative)value = -value;return value;}// as parseInt but returns a floating point valuefloat Stream::parseFloat(LookaheadMode lookahead, char ignore){bool isNegative = false;bool isFraction = false;double value = 0.0;int c;double fraction = 1.0;c = peekNextDigit(lookahead, true);// ignore non numeric leading charactersif(c < 0)return 0; // zero returned if timeoutdo{if((char)c == ignore); // ignoreelse if(c == '-')isNegative = true;else if (c == '.')isFraction = true;else if(c >= '0' && c <= '9') { // is c a digit?if(isFraction) {fraction *= 0.1;value = value + fraction * (c - '0');} else {value = value * 10 + c - '0';}}read(); // consume the character we got with peekc = timedPeek();}while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || (char)c == ignore );if(isNegative)value = -value;return value;}// read characters from stream into buffer// terminates if length characters have been read, or timeout (see setTimeout)// returns the number of characters placed in the buffer// the buffer is NOT null terminated.//size_t Stream::readBytes(char *buffer, size_t length){size_t count = 0;while (count < length) {int c = timedRead();if (c < 0) break;*buffer++ = (char)c;count++;}return count;}// as readBytes with terminator character// terminates if length characters have been read, timeout, or if the terminator character detected// returns the number of characters placed in the buffer (0 means no valid data found)size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length){size_t index = 0;while (index < length) {int c = timedRead();if (c < 0 || (char)c == terminator) break;*buffer++ = (char)c;index++;}return index; // return number of characters, not including null terminator}String Stream::readString(void){String ret;int c = timedRead();while (c >= 0){ret += (char)c;c = timedRead();}return ret;}String Stream::readStringUntil(char terminator){String ret;int c = timedRead();while (c >= 0 && (char)c != terminator){ret += (char)c;c = timedRead();}return ret;}int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {// any zero length target string automatically matches and would make// a mess of the rest of the algorithm.for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {if (t->len <= 0)return t - targets;}while (1) {int c = timedRead();if (c < 0)return -1;for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {// the simple case is if we match, deal with that first.if ((char)c == t->str[t->index]) {if (++t->index == t->len)return t - targets;elsecontinue;}// if not we need to walk back and see if we could have matched further// down the stream (ie '1112' doesn't match the first position in '11112'// but it will match the second position so we can't just reset the current// index to 0 when we find a mismatch.if (t->index == 0)continue;int origIndex = t->index;do {--t->index;// first check if current char works against the new current indexif ((char)c != t->str[t->index])continue;// if it's the only char then we're good, nothing more to checkif (t->index == 0) {t->index++;break;}// otherwise we need to check the rest of the found stringint diff = origIndex - t->index;size_t i;for (i = 0; i < t->index; ++i) {if (t->str[i] != t->str[i + diff])break;}// if we successfully got through the previous loop then our current// index is good.if (i == t->index) {t->index++;break;}// otherwise we just try the next index} while (t->index);}}// unreachable// return -1;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型