mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-20 10:24:18 +03:00
Stream: +helpers to stream regular String (#9043)
This allows to use a String as a destination Stream by using a temporary with streaming helpers.
This commit is contained in:
@ -196,21 +196,25 @@ class Stream: public Print {
|
|||||||
// returns number of transferred bytes
|
// returns number of transferred bytes
|
||||||
size_t sendAvailable (Stream* to) { return sendGeneric(to, -1, -1, oneShotMs::alwaysExpired); }
|
size_t sendAvailable (Stream* to) { return sendGeneric(to, -1, -1, oneShotMs::alwaysExpired); }
|
||||||
size_t sendAvailable (Stream& to) { return sendAvailable(&to); }
|
size_t sendAvailable (Stream& to) { return sendAvailable(&to); }
|
||||||
|
size_t sendAvailable (Stream&& to) { return sendAvailable(&to); }
|
||||||
|
|
||||||
// transfers data until timeout
|
// transfers data until timeout
|
||||||
// returns number of transferred bytes
|
// returns number of transferred bytes
|
||||||
size_t sendAll (Stream* to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, -1, timeoutMs); }
|
size_t sendAll (Stream* to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, -1, timeoutMs); }
|
||||||
size_t sendAll (Stream& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); }
|
size_t sendAll (Stream& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); }
|
||||||
|
size_t sendAll (Stream&& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); }
|
||||||
|
|
||||||
// transfers data until a char is encountered (the char is swallowed but not transferred) with timeout
|
// transfers data until a char is encountered (the char is swallowed but not transferred) with timeout
|
||||||
// returns number of transferred bytes
|
// returns number of transferred bytes
|
||||||
size_t sendUntil (Stream* to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, readUntilChar, timeoutMs); }
|
size_t sendUntil (Stream* to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, readUntilChar, timeoutMs); }
|
||||||
size_t sendUntil (Stream& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); }
|
size_t sendUntil (Stream& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); }
|
||||||
|
size_t sendUntil (Stream&& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); }
|
||||||
|
|
||||||
// transfers data until requested size or timeout
|
// transfers data until requested size or timeout
|
||||||
// returns number of transferred bytes
|
// returns number of transferred bytes
|
||||||
size_t sendSize (Stream* to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, maxLen, -1, timeoutMs); }
|
size_t sendSize (Stream* to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, maxLen, -1, timeoutMs); }
|
||||||
size_t sendSize (Stream& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); }
|
size_t sendSize (Stream& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); }
|
||||||
|
size_t sendSize (Stream&& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); }
|
||||||
|
|
||||||
// remaining size (-1 by default = unknown)
|
// remaining size (-1 by default = unknown)
|
||||||
virtual ssize_t streamRemaining () { return -1; }
|
virtual ssize_t streamRemaining () { return -1; }
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "WString.h"
|
#include "WString.h"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
||||||
// S2Stream points to a String and makes it a Stream
|
// S2Stream ("String to Stream") points to a String and makes it a Stream
|
||||||
// (it is also the helper for StreamString)
|
// (it is also the helper for StreamString)
|
||||||
|
|
||||||
class S2Stream: public Stream
|
class S2Stream: public Stream
|
||||||
@ -184,19 +184,18 @@ public:
|
|||||||
return peekPointer < 0 ? string->length() : string->length() - peekPointer;
|
return peekPointer < 0 ? string->length() : string->length() - peekPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calling setConsume() will consume bytes as the stream is read
|
// calling setConsume() will make the string consumed as the stream is read.
|
||||||
// (enabled by default)
|
// (default behaviour)
|
||||||
void setConsume()
|
void setConsume()
|
||||||
{
|
{
|
||||||
peekPointer = -1;
|
peekPointer = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading this stream will mark the string as read without consuming
|
// Calling resetPointer() resets the read cursor and allows rereading.
|
||||||
// (not enabled by default)
|
// (this is the opposite of default mode set by setConsume())
|
||||||
// Calling resetPointer() resets the read state and allows rereading.
|
void resetPointer(size_t pointer = 0)
|
||||||
void resetPointer(int pointer = 0)
|
|
||||||
{
|
{
|
||||||
peekPointer = pointer;
|
peekPointer = std::min(pointer, (size_t)string->length());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -204,6 +203,7 @@ protected:
|
|||||||
int peekPointer; // -1:String is consumed / >=0:resettable pointer
|
int peekPointer; // -1:String is consumed / >=0:resettable pointer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
// StreamString is a S2Stream holding the String
|
// StreamString is a S2Stream holding the String
|
||||||
|
|
||||||
class StreamString: public String, public S2Stream
|
class StreamString: public String, public S2Stream
|
||||||
|
@ -54,7 +54,7 @@ void testStreamString() {
|
|||||||
{
|
{
|
||||||
// We use a a lighter StreamConstPtr(input) to make a read-only Stream out of
|
// We use a a lighter StreamConstPtr(input) to make a read-only Stream out of
|
||||||
// a String that obviously should not be modified during the time the
|
// a String that obviously should not be modified during the time the
|
||||||
// StreamConstPtr instance is used. It is used as a source to be sent to
|
// StreamConstPtr instance is used. It is used as a read-only source to be sent to
|
||||||
// 'result'.
|
// 'result'.
|
||||||
|
|
||||||
result.clear();
|
result.clear();
|
||||||
@ -77,7 +77,7 @@ void testStreamString() {
|
|||||||
// Now inputString is made into a Stream using S2Stream,
|
// Now inputString is made into a Stream using S2Stream,
|
||||||
// and set in non-consume mode (using ::resetPointer()).
|
// and set in non-consume mode (using ::resetPointer()).
|
||||||
|
|
||||||
// Then, after that input is read once, it won't be anymore readable
|
// Then, after input is read once, it won't be anymore readable
|
||||||
// until the pointer is reset.
|
// until the pointer is reset.
|
||||||
|
|
||||||
S2Stream input(inputString);
|
S2Stream input(inputString);
|
||||||
@ -87,7 +87,7 @@ void testStreamString() {
|
|||||||
input.sendAll(result);
|
input.sendAll(result);
|
||||||
input.sendAll(result);
|
input.sendAll(result);
|
||||||
check("S2Stream.sendAll(StreamString)", result.c_str(), "hello");
|
check("S2Stream.sendAll(StreamString)", result.c_str(), "hello");
|
||||||
check("unmodified String given to S2Stream", inputString.c_str(), "hello");
|
check("String given to S2Stream is unmodified", inputString.c_str(), "hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -103,6 +103,17 @@ void testStreamString() {
|
|||||||
check("S2Stream.resetPointer(2):", result.c_str(), "llo");
|
check("S2Stream.resetPointer(2):", result.c_str(), "llo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Streaming to a regular String
|
||||||
|
|
||||||
|
String someSource{ F("hello") };
|
||||||
|
String someDestString;
|
||||||
|
|
||||||
|
StreamConstPtr(someSource).sendAll(S2Stream(someDestString));
|
||||||
|
StreamConstPtr(someSource).sendAll(S2Stream(someDestString));
|
||||||
|
check("StreamConstPtr(someSource).sendAll(S2Stream(someDestString))", someDestString.c_str(), "hellohello");
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// inputString made into a Stream
|
// inputString made into a Stream
|
||||||
// reading the Stream consumes the String
|
// reading the Stream consumes the String
|
||||||
@ -181,7 +192,8 @@ void setup() {
|
|||||||
|
|
||||||
testStreamString();
|
testStreamString();
|
||||||
|
|
||||||
Serial.printf("sizeof: String:%d Stream:%d StreamString:%d SStream:%d\n", (int)sizeof(String), (int)sizeof(Stream), (int)sizeof(StreamString), (int)sizeof(S2Stream));
|
Serial.printf("sizeof: String:%zu Stream:%zu StreamString:%zu S2Stream:%zu StreamConstPtr:%zu\n",
|
||||||
|
sizeof(String), sizeof(Stream), sizeof(StreamString), sizeof(S2Stream), sizeof(StreamConstPtr));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user