-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Extract Stream methods into an IStream. #5749
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
base: master
Are you sure you want to change the base?
Conversation
I do not think this is necessary. You can make the Print features private, hiding them from the user. class MyStream : public Stream{
public:
int available() { return 0; } //Fill in these as appropriate.
void flush() { return; }
int peek() { return -1; }
int read() { return -1; }
private:
using Print::print;
using Print::println;
using Print::write;
size_t write( uint8_t data ) { return (void)data, 0; }
};
MyStream stream;
void setup() {
stream.read(); //Fine
stream.println(); //Compile error
}
void loop() {}
|
@Chris--A: That's a workaround, but not a good one: void print_some_things(Print& p) {
p.println("Hello world");
}
MyStream stream; // using your definition
void setup() {
stream.read();
print_some_things(stream); // oops. This compiles just fine
static_cast<Stream&>(stream).println("oops again");
Print* p = &stream;
p->println("Oops");
} The existence of an ineffective workaround is not sufficient justification for an improvement being unnecessary. |
That isn't really an issue either. My workaround hides the print features when using the object directly, and for the cases that the object is cast to one of its inherited types, the print functionality has no effect. A library shouldn't be left up to assumptions, if you don't support print features, then make it well known, or don't even mention it, then no one would have a reason to use them. Another option using my original example is to make the Stream base private and only expose what you want: class MyStream : private Stream{
public:
int available() { return 0; }
void flush() { return; }
int peek() { return -1; }
int read() { return -1; }
using Stream::find;
using Stream::findUntil;
using Stream::parseInt;
using Stream::readBytes;
using Stream::readBytesUntil;
private:
size_t write( uint8_t data ) { return (void)data, 0; }
};
MyStream stream;
void setup() {
stream.read(); //Fine
stream.find('a'); //Fine
Stream &s = stream; //Compile error
Print &p = stream; //Compile error
}
void loop() {} Similar to the above, you can also have a Stream reference or pointer as a member variable and only expose the input functions. |
You've made the valid point that I've justified this poorly, so I've added some example code in my description.
That's kinda the point of this patch. There is currently no way to make it known that you support read features but not print features, yet there is a way to express the inverse. Why should things be this way? What if I want to write a function that can read from Look at this another way - if |
Good catch, this probably doesn't belong in |
Also see #2387. |
@matthijskooijman: Was tempted to fix that too. What's stopping that being merged? |
@eric-wieser, Nothing that I can see, apart from maybe lack of developer time. |
72c5c34
to
4d73331
Compare
Now that #2387 is merged, I've rebased this to be even simpler |
4d73331
to
9df1c0a
Compare
|
||
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field | ||
|
||
class IStream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only line that actually changed in this file other than renaming Stream
to IStream
- it was previously class Stream : public Print
This allows streams to exist that are input-only, such as a keyboard.
9df1c0a
to
fe40b60
Compare
@@ -1,6 +1,5 @@ | |||
/* | |||
Stream.h - base class for character-based streams. | |||
Copyright (c) 2010 David A. Mellis. All right reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing is left of the original file apart from the name Stream
, so this copyright notice has moved to IStream.h
|
This allows streams to exist that are unidirectional.
A summary of this diff, which github does not show well:
Stream
toIStream
, adjusting comments in the same wayPrint
base class from the newIStream
Stream.h
withclass Stream : public Print, public IStream {}
I can't see any reason for this not to be backwards-compatible.
Example usage:
I'm open to other names here instead of
IStream
, such as:InputStream
Read
(to matchPrint
)Reader
(which avoids naming classes after verbs)