Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream: +helpers to stream regular String #9043

Merged
merged 8 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cores/esp8266/Stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,21 +196,25 @@ class Stream: public Print {
// returns number of transferred bytes
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); }

// transfers data until timeout
// 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 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
// 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 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
// 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 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)
virtual ssize_t streamRemaining () { return -1; }
Expand Down
16 changes: 8 additions & 8 deletions cores/esp8266/StreamString.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#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)

class S2Stream: public Stream
Expand Down Expand Up @@ -184,26 +184,26 @@ class S2Stream: public Stream
return peekPointer < 0 ? string->length() : string->length() - peekPointer;
}

// calling setConsume() will consume bytes as the stream is read
// (enabled by default)
// calling setConsume() will make the string consumed as the stream is read.
// (default behaviour)
void setConsume()
{
peekPointer = -1;
}

// Reading this stream will mark the string as read without consuming
// (not enabled by default)
// Calling resetPointer() resets the read state and allows rereading.
void resetPointer(int pointer = 0)
// Calling resetPointer() resets the read cursor and allows rereading.
// (this is the opposite of default mode set by setConsume())
void resetPointer(size_t pointer = 0)
{
peekPointer = pointer;
peekPointer = std::min(std::max(0U, (unsigned int)pointer), string->length());
mcspr marked this conversation as resolved.
Show resolved Hide resolved
}

protected:
String* string;
int peekPointer; // -1:String is consumed / >=0:resettable pointer
};

///////////////////////////////////////////////////////////////
// StreamString is a S2Stream holding the String

class StreamString: public String, public S2Stream
Expand Down
20 changes: 16 additions & 4 deletions libraries/esp8266/examples/StreamString/StreamString.ino
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void testStreamString() {
{
// 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
// 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.clear();
Expand All @@ -77,7 +77,7 @@ void testStreamString() {
// Now inputString is made into a Stream using S2Stream,
// 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.

S2Stream input(inputString);
Expand All @@ -87,7 +87,7 @@ void testStreamString() {
input.sendAll(result);
input.sendAll(result);
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");
}

{
Expand All @@ -103,6 +103,17 @@ void testStreamString() {
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
// reading the Stream consumes the String
Expand Down Expand Up @@ -181,7 +192,8 @@ void setup() {

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