Skip to content

Commit 474d5a1

Browse files
committed
comments
1 parent 92c99f2 commit 474d5a1

File tree

3 files changed

+86
-48
lines changed

3 files changed

+86
-48
lines changed

cores/esp8266/Stream.h

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -109,62 +109,94 @@ class Stream: public Print {
109109
virtual String readString();
110110
String readStringUntil(char terminator);
111111

112-
// ::read(buf, len): conflicting returned type:
112+
//////////////////// extension: readNow (is ::read() with unified signature)
113+
// (supposed to be internally used, and ephemeral)
114+
//
115+
// about ::read(buf, len): conflicting returned type:
113116
// - `int` in arduino's Client::
114117
// - `size_t` in esp8266 API (HardwareSerial::, FS::)
115118
// - not existent in arduino's Stream::
116119
// changing every read()/write() `size_t` return type to `int` will be a breaking change
117120
// => adding int ::readNow(buf, len) for now (following official `int Client::read(buf, len))`
118121
//
119122
// int ::readNow(buf, len)
120-
// read at most len bytes, returns effectively transfered bytes (can be less than len)
121-
// immediate return when no more data are available (no timeout)
122-
virtual int readNow(char* buffer, size_t len);
123-
virtual int readNow(uint8_t* buffer, size_t len) final { return readNow((char*)buffer, len); }
123+
// read at most len bytes, returns effectively transfered bytes (can be less than 'len')
124+
// with no timeout: immediate return when no more data are available
125+
virtual int readNow (char* buffer, size_t len);
126+
virtual int readNow (uint8_t* buffer, size_t len) final { return readNow((char*)buffer, len); }
124127

125-
//////////////////// extensions: direct access to input buffer
128+
//////////////////// extension: direct access to input buffer
129+
// for providing, when possible, a pointer to available data for read
126130

127-
// inform user and ::to() on effective buffered peek API implementation
131+
// informs user and ::to() on effective buffered peek API implementation
132+
// by default: not available
128133
virtual bool peekBufferAPI () const { return false; }
129134

130-
// return number of byte accessible by peekBuffer()
135+
// returns number of byte accessible by peekBuffer()
131136
virtual size_t availableForPeek () { return 0; }
132137

133-
// return a pointer to available data buffer (size = availableForPeek())
134-
// semantic forbids any kind of read()
135-
// after calling peekBuffer()
136-
// and before calling peekConsume()
138+
// returns a pointer to available data buffer (size = availableForPeek())
139+
// semantic forbids any kind of ::read()
140+
// - after calling peekBuffer()
141+
// - and before calling peekConsume()
137142
virtual const char* peekBuffer () { return nullptr; }
138143

139-
// consume bytes after peekBuffer() use
144+
// consumes bytes after peekBuffer() use
145+
// (then ::read() is allowed)
140146
virtual void peekConsume (size_t consume) { (void)consume; }
141147

142148
// by default read timeout is possible (incoming data from network,serial..)
143-
// (children can override to false (like String))
149+
// children can override to false (like String::)
150+
// (outputTimeoutPossible() is defined in Print::)
144151
virtual bool inputTimeoutPossible () const { return true; }
145152

146153
//////////////////// extensions: Stream streams
147-
148154
// Stream::to()
149-
// transfer from `Stream::` to `Print::` at most maxlen bytes and return number of transfered bytes
150-
// (uses 1-copy peekBuffer API when available, or transfer through a 2-copies local stack space)
151-
// - maxLen<0 will transfer until input starvation or saturated output
152-
// - timeout_ms==TimeoutMs::neverExpires: use getTimeout() (when 0: take what's available and immediate return)
153-
// - readUntilChar: setting anything in 0..255 will stop transfer when this char is read *and copied too*.
155+
//
156+
// Stream::to() uses 1-copy transfers when peekBuffer API is
157+
// available, or makes a regular transfer through a local temporary
158+
// stack buffer.
159+
//
160+
// By default "source->to(&dest)" transfers everything until
161+
// available (read or write) gets to 0 and a timeout occurs.
162+
//
163+
// "source->to(&dest, maxLen)" is like above but also returns when
164+
// maxLen bytes are transferred.
165+
//
166+
// More generally ::to() will transfer as much as possible until:
167+
// - maxLen (>=0) bytes are transferred (without timeout),
168+
// - or readUntilChar (>=0) is reached (without timeout),
169+
// - or available for read or write gets to zero (after timeout).
170+
//
171+
// Timeout value is by default thisStream->getTimeout() but it can
172+
// be set to "alwaysExpired" (=0) or any value within oneShotMs
173+
// allowed range.
174+
//
175+
// Return value:
176+
// >0: the number of transfered bytes
177+
// 0: nothing has been transfered, getLastTo() may contain an error reason
178+
//
179+
// Notes:
180+
// - readUntilChar is copied and counted
181+
// - for efficiency: Stream classes should implement peekAPI when possible
182+
// - for efficiency: Stream classes should implement {input,output}TimeoutPossible()
183+
184+
using oneShotMs = esp8266::polledTimeout::oneShotFastMs;
185+
154186
virtual size_t to (Print* to,
155-
const ssize_t len = -1,
156-
esp8266::polledTimeout::oneShotFastMs::timeType timeout = esp8266::polledTimeout::oneShotFastMs::neverExpires /* =>getTimeout() */,
187+
const ssize_t maxLen = -1,
188+
oneShotMs::timeType timeout = oneShotMs::neverExpires /* =>getTimeout() */,
157189
int readUntilChar = -1) final;
158-
enum
190+
typedef enum
159191
{
160-
TOSTREAM_SUCCESS = 0,
161-
TOSTREAM_TIMED_OUT,
162-
TOSTREAM_READ_ERROR,
163-
TOSTREAM_WRITE_ERROR,
164-
TOSTREAM_SHORT,
165-
} _last_to = TOSTREAM_SUCCESS;
166-
167-
decltype(_last_to) getLastTo () const { return _last_to; }
192+
STREAMTO_SUCCESS = 0,
193+
STREAMTO_TIMED_OUT,
194+
STREAMTO_READ_ERROR,
195+
STREAMTO_WRITE_ERROR,
196+
STREAMTO_SHORT,
197+
} toReport_e;
198+
199+
toReport_e getLastTo () /*const*/ { return (toReport_e)getWriteError(); }
168200

169201
//////////////////// end of extensions
170202

cores/esp8266/StreamDev.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ size_t Stream::to (Print* to,
1010
oneShotFastMs::timeType timeout,
1111
int readUntilChar)
1212
{
13-
_last_to = TOSTREAM_SUCCESS;
13+
setWriteError(STREAMTO_SUCCESS);
1414

1515
if (len == 0)
16-
return 0; // avoid timeout for no requested data
16+
return 0; // conveniently avoids timeout for no requested data
1717

1818
// There are two timeouts:
1919
// - read (network, serial, ...)
@@ -33,7 +33,7 @@ size_t Stream::to (Print* to,
3333
size_t written = 0;
3434

3535
// len==-1 => maxLen=0 <=> until starvation
36-
size_t maxLen = std::max((decltype(len))0, len);
36+
size_t maxLen = std::max((ssize_t)0, len);
3737

3838
if (peekBufferAPI())
3939

@@ -105,7 +105,7 @@ size_t Stream::to (Print* to,
105105
w = to->write(c);
106106
if (w != 1)
107107
{
108-
_last_to = TOSTREAM_WRITE_ERROR;
108+
setWriteError(STREAMTO_WRITE_ERROR);
109109
break;
110110
}
111111
written += 1;
@@ -143,14 +143,14 @@ size_t Stream::to (Print* to,
143143
ssize_t r = readNow(temp, w);
144144
if (r < 0)
145145
{
146-
_last_to = TOSTREAM_READ_ERROR;
146+
setWriteError(STREAMTO_READ_ERROR);
147147
break;
148148
}
149149
w = to->write(temp, r);
150150
written += w;
151151
if ((size_t)r != w)
152152
{
153-
_last_to = TOSTREAM_WRITE_ERROR;
153+
setWriteError(STREAMTO_WRITE_ERROR);
154154
break;
155155
}
156156
if (w)
@@ -162,12 +162,18 @@ size_t Stream::to (Print* to,
162162
yield();
163163
}
164164

165-
if (_last_to == TOSTREAM_SUCCESS)
165+
if (getWriteError() == STREAMTO_SUCCESS)
166166
{
167167
if (timedOut)
168-
_last_to = TOSTREAM_TIMED_OUT;
169-
else if (len > 0 && (ssize_t)written != len)
170-
_last_to = TOSTREAM_SHORT;
168+
setWriteError(STREAMTO_TIMED_OUT);
169+
else if ((ssize_t)written != len)
170+
// This is happening when source cannot timeout (ex: a String)
171+
// but has not enough data, or a dest has closed or cannot
172+
// timeout but is too small (String, buffer...)
173+
//
174+
// Mark it as an error because user usually wants to get what is
175+
// asked for.
176+
setWriteError(STREAMTO_SHORT);
171177
}
172178
return written;
173179
}

libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ int TO2HTTPC (int streamToError)
3737
{
3838
switch (streamToError)
3939
{
40-
case Stream::TOSTREAM_TIMED_OUT: return HTTPC_ERROR_READ_TIMEOUT;
41-
case Stream::TOSTREAM_READ_ERROR: return HTTPC_ERROR_NO_STREAM;
42-
case Stream::TOSTREAM_WRITE_ERROR: return HTTPC_ERROR_STREAM_WRITE;
43-
case Stream::TOSTREAM_SHORT: return HTTPC_ERROR_STREAM_WRITE;
40+
case Stream::STREAMTO_TIMED_OUT: return HTTPC_ERROR_READ_TIMEOUT;
41+
case Stream::STREAMTO_READ_ERROR: return HTTPC_ERROR_NO_STREAM;
42+
case Stream::STREAMTO_WRITE_ERROR: return HTTPC_ERROR_STREAM_WRITE;
43+
case Stream::STREAMTO_SHORT: return HTTPC_ERROR_STREAM_WRITE;
4444
default:
45-
case Stream::TOSTREAM_SUCCESS: return 0;
45+
case Stream::STREAMTO_SUCCESS: return 0;
4646
}
4747
}
4848

@@ -849,7 +849,7 @@ int HTTPClient::writeToStream(Stream * stream)
849849
ret = _client->to(stream, len);
850850

851851
// have we an error?
852-
if(_client->getLastTo() != Stream::TOSTREAM_SUCCESS) {
852+
if(_client->getLastTo() != Stream::STREAMTO_SUCCESS) {
853853
return returnError(TO2HTTPC(ret));
854854
}
855855
} else if(_transferEncoding == HTTPC_TE_CHUNKED) {
@@ -875,7 +875,7 @@ int HTTPClient::writeToStream(Stream * stream)
875875
if(len > 0) {
876876
// read len bytes with timeout
877877
int r = _client->to(stream, len);
878-
if (_client->getLastTo() != Stream::TOSTREAM_SUCCESS)
878+
if (_client->getLastTo() != Stream::STREAMTO_SUCCESS)
879879
// not all data transferred
880880
return returnError(TO2HTTPC(ret));
881881
ret += r;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy