Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a5d31a7

Browse filesBrowse files
authored
deprecate and update Stream::send*(Print -> Stream) (esp8266#8874)
* deprecate and update Stream::send(Print -> Stream) in order to benefit from and use output's timeout value
1 parent 01d1c8e commit a5d31a7
Copy full SHA for a5d31a7

File tree

Expand file treeCollapse file tree

4 files changed

+185
-125
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+185
-125
lines changed

‎cores/esp8266/Stream.h

Copy file name to clipboardExpand all lines: cores/esp8266/Stream.h
+38-8Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,25 +167,49 @@ class Stream: public Print {
167167
// When result is 0 or less than requested maxLen, Print::getLastSend()
168168
// contains an error reason.
169169

170+
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
171+
172+
// transfers already buffered / immediately available data (no timeout)
173+
// returns number of transferred bytes
174+
[[deprecated]] size_t sendAvailable (Print* to) { return sendGeneric(to, -1, -1, oneShotMs::alwaysExpired); }
175+
[[deprecated]] size_t sendAvailable (Print& to) { return sendAvailable(&to); }
176+
177+
// transfers data until timeout
178+
// returns number of transferred bytes
179+
[[deprecated]] size_t sendAll (Print* to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, -1, timeoutMs); }
180+
[[deprecated]] size_t sendAll (Print& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); }
181+
182+
// transfers data until a char is encountered (the char is swallowed but not transferred) with timeout
183+
// returns number of transferred bytes
184+
[[deprecated]] size_t sendUntil (Print* to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, readUntilChar, timeoutMs); }
185+
[[deprecated]] size_t sendUntil (Print& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); }
186+
187+
// transfers data until requested size or timeout
188+
// returns number of transferred bytes
189+
[[deprecated]] size_t sendSize (Print* to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, maxLen, -1, timeoutMs); }
190+
[[deprecated]] size_t sendSize (Print& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); }
191+
192+
#pragma GCC diagnostic pop
193+
170194
// transfers already buffered / immediately available data (no timeout)
171195
// returns number of transferred bytes
172-
size_t sendAvailable (Print* to) { return sendGeneric(to, -1, -1, oneShotMs::alwaysExpired); }
173-
size_t sendAvailable (Print& to) { return sendAvailable(&to); }
196+
size_t sendAvailable (Stream* to) { return sendGeneric(to, -1, -1, oneShotMs::alwaysExpired); }
197+
size_t sendAvailable (Stream& to) { return sendAvailable(&to); }
174198

175199
// transfers data until timeout
176200
// returns number of transferred bytes
177-
size_t sendAll (Print* to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, -1, timeoutMs); }
178-
size_t sendAll (Print& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); }
201+
size_t sendAll (Stream* to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, -1, timeoutMs); }
202+
size_t sendAll (Stream& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); }
179203

180204
// transfers data until a char is encountered (the char is swallowed but not transferred) with timeout
181205
// returns number of transferred bytes
182-
size_t sendUntil (Print* to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, readUntilChar, timeoutMs); }
183-
size_t sendUntil (Print& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); }
206+
size_t sendUntil (Stream* to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, readUntilChar, timeoutMs); }
207+
size_t sendUntil (Stream& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); }
184208

185209
// transfers data until requested size or timeout
186210
// returns number of transferred bytes
187-
size_t sendSize (Print* to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, maxLen, -1, timeoutMs); }
188-
size_t sendSize (Print& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); }
211+
size_t sendSize (Stream* to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, maxLen, -1, timeoutMs); }
212+
size_t sendSize (Stream& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); }
189213

190214
// remaining size (-1 by default = unknown)
191215
virtual ssize_t streamRemaining () { return -1; }
@@ -202,11 +226,17 @@ class Stream: public Print {
202226
Report getLastSendReport () const { return _sendReport; }
203227

204228
protected:
229+
[[deprecated]]
205230
size_t sendGeneric (Print* to,
206231
const ssize_t len = -1,
207232
const int readUntilChar = -1,
208233
oneShotMs::timeType timeoutMs = oneShotMs::neverExpires /* neverExpires=>getTimeout() */);
209234

235+
size_t sendGeneric (Stream* to,
236+
const ssize_t len = -1,
237+
const int readUntilChar = -1,
238+
oneShotMs::timeType timeoutMs = oneShotMs::neverExpires /* neverExpires=>getTimeout() */);
239+
210240
size_t SendGenericPeekBuffer(Print* to, const ssize_t len, const int readUntilChar, const oneShotMs::timeType timeoutMs);
211241
size_t SendGenericRegularUntil(Print* to, const ssize_t len, const int readUntilChar, const oneShotMs::timeType timeoutMs);
212242
size_t SendGenericRegular(Print* to, const ssize_t len, const oneShotMs::timeType timeoutMs);

‎cores/esp8266/StreamSend.cpp

Copy file name to clipboardExpand all lines: cores/esp8266/StreamSend.cpp
+54-15Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,54 @@
2222
#include <Arduino.h>
2323
#include <StreamDev.h>
2424

25+
size_t Stream::sendGeneric(Stream* to, const ssize_t len, const int readUntilChar,
26+
const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
27+
{
28+
// "neverExpires (default, impossible)" is translated to default timeout
29+
esp8266::polledTimeout::oneShotFastMs::timeType inputTimeoutMs
30+
= timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout()
31+
: timeoutMs;
32+
33+
esp8266::polledTimeout::oneShotFastMs::timeType mainTimeoutMs = std::max(
34+
inputTimeoutMs, (esp8266::polledTimeout::oneShotFastMs::timeType)to->getTimeout());
35+
36+
setReport(Report::Success);
37+
38+
if (len == 0)
39+
{
40+
return 0; // conveniently avoids timeout for no requested data
41+
}
42+
43+
// There are two timeouts:
44+
// - read (network, serial, ...)
45+
// - write (network, serial, ...)
46+
// However
47+
// - getTimeout() is for reading only
48+
// - there is no getOutputTimeout() api
49+
// So we use getTimeout() for both,
50+
// (also when inputCanTimeout() is false)
51+
52+
if (hasPeekBufferAPI())
53+
{
54+
return SendGenericPeekBuffer(to, len, readUntilChar, mainTimeoutMs);
55+
}
56+
57+
if (readUntilChar >= 0)
58+
{
59+
return SendGenericRegularUntil(to, len, readUntilChar, mainTimeoutMs);
60+
}
61+
62+
return SendGenericRegular(to, len, mainTimeoutMs);
63+
}
64+
2565
size_t Stream::sendGeneric(Print* to, const ssize_t len, const int readUntilChar,
2666
const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
2767
{
68+
// "neverExpires (default, impossible)" is translated to default timeout
69+
esp8266::polledTimeout::oneShotFastMs::timeType inputTimeoutMs
70+
= timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout()
71+
: timeoutMs;
72+
2873
setReport(Report::Success);
2974

3075
if (len == 0)
@@ -43,25 +88,23 @@ size_t Stream::sendGeneric(Print* to, const ssize_t len, const int readUntilChar
4388

4489
if (hasPeekBufferAPI())
4590
{
46-
return SendGenericPeekBuffer(to, len, readUntilChar, timeoutMs);
91+
return SendGenericPeekBuffer(to, len, readUntilChar, inputTimeoutMs);
4792
}
4893

4994
if (readUntilChar >= 0)
5095
{
51-
return SendGenericRegularUntil(to, len, readUntilChar, timeoutMs);
96+
return SendGenericRegularUntil(to, len, readUntilChar, inputTimeoutMs);
5297
}
5398

54-
return SendGenericRegular(to, len, timeoutMs);
99+
return SendGenericRegular(to, len, inputTimeoutMs);
55100
}
56101

57102
size_t
58103
Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int readUntilChar,
59104
const esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
60105
{
61-
// "neverExpires (default, impossible)" is translated to default timeout
62-
esp8266::polledTimeout::oneShotFastMs timedOut(
63-
timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout()
64-
: timeoutMs);
106+
esp8266::polledTimeout::oneShotFastMs timedOut(timeoutMs);
107+
65108
// len==-1 => maxLen=0 <=> until starvation
66109
const size_t maxLen = std::max((ssize_t)0, len);
67110
size_t written = 0;
@@ -152,10 +195,8 @@ Stream::SendGenericRegularUntil(Print* to, const ssize_t len, const int readUnti
152195
// regular Stream API
153196
// no other choice than reading byte by byte
154197

155-
// "neverExpires (default, impossible)" is translated to default timeout
156-
esp8266::polledTimeout::oneShotFastMs timedOut(
157-
timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout()
158-
: timeoutMs);
198+
esp8266::polledTimeout::oneShotFastMs timedOut(timeoutMs);
199+
159200
// len==-1 => maxLen=0 <=> until starvation
160201
const size_t maxLen = std::max((ssize_t)0, len);
161202
size_t written = 0;
@@ -231,10 +272,8 @@ size_t Stream::SendGenericRegular(Print* to, const ssize_t len,
231272
// regular Stream API
232273
// use an intermediary buffer
233274

234-
// "neverExpires (default, impossible)" is translated to default timeout
235-
esp8266::polledTimeout::oneShotFastMs timedOut(
236-
timeoutMs >= esp8266::polledTimeout::oneShotFastMs::neverExpires ? getTimeout()
237-
: timeoutMs);
275+
esp8266::polledTimeout::oneShotFastMs timedOut(timeoutMs);
276+
238277
// len==-1 => maxLen=0 <=> until starvation
239278
const size_t maxLen = std::max((ssize_t)0, len);
240279
size_t written = 0;

‎libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp

Copy file name to clipboardExpand all lines: libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp
+1-100Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static_assert(std::is_move_assignable_v<HTTPClient>, "");
3939
static const char defaultUserAgentPstr[] PROGMEM = "ESP8266HTTPClient";
4040
const String HTTPClient::defaultUserAgent = defaultUserAgentPstr;
4141

42-
static int StreamReportToHttpClientReport (Stream::Report streamSendError)
42+
int HTTPClient::StreamReportToHttpClientReport (Stream::Report streamSendError)
4343
{
4444
switch (streamSendError)
4545
{
@@ -627,105 +627,6 @@ WiFiClient* HTTPClient::getStreamPtr(void)
627627
return nullptr;
628628
}
629629

630-
/**
631-
* write all message body / payload to Stream
632-
* @param stream Stream *
633-
* @return bytes written ( negative values are error codes )
634-
*/
635-
int HTTPClient::writeToStream(Stream * stream)
636-
{
637-
return writeToPrint(stream);
638-
}
639-
640-
/**
641-
* write all message body / payload to Print
642-
* @param print Print *
643-
* @return bytes written ( negative values are error codes )
644-
*/
645-
int HTTPClient::writeToPrint(Print * print)
646-
{
647-
648-
if(!print) {
649-
return returnError(HTTPC_ERROR_NO_STREAM);
650-
}
651-
652-
// Only return error if not connected and no data available, because otherwise ::getString() will return an error instead of an empty
653-
// string when the server returned a http code 204 (no content)
654-
if(!connected() && _transferEncoding != HTTPC_TE_IDENTITY && _size > 0) {
655-
return returnError(HTTPC_ERROR_NOT_CONNECTED);
656-
}
657-
658-
// get length of document (is -1 when Server sends no Content-Length header)
659-
int len = _size;
660-
int ret = 0;
661-
662-
if(_transferEncoding == HTTPC_TE_IDENTITY) {
663-
// len < 0: transfer all of it, with timeout
664-
// len >= 0: max:len, with timeout
665-
ret = _client->sendSize(print, len);
666-
667-
// do we have an error?
668-
if(_client->getLastSendReport() != Stream::Report::Success) {
669-
return returnError(StreamReportToHttpClientReport(_client->getLastSendReport()));
670-
}
671-
} else if(_transferEncoding == HTTPC_TE_CHUNKED) {
672-
int size = 0;
673-
while(1) {
674-
if(!connected()) {
675-
return returnError(HTTPC_ERROR_CONNECTION_LOST);
676-
}
677-
String chunkHeader = _client->readStringUntil('\n');
678-
679-
if(chunkHeader.length() <= 0) {
680-
return returnError(HTTPC_ERROR_READ_TIMEOUT);
681-
}
682-
683-
chunkHeader.trim(); // remove \r
684-
685-
// read size of chunk
686-
len = (uint32_t) strtol((const char *) chunkHeader.c_str(), NULL, 16);
687-
size += len;
688-
DEBUG_HTTPCLIENT("[HTTP-Client] read chunk len: %d\n", len);
689-
690-
// data left?
691-
if(len > 0) {
692-
// read len bytes with timeout
693-
int r = _client->sendSize(print, len);
694-
if (_client->getLastSendReport() != Stream::Report::Success)
695-
// not all data transferred
696-
return returnError(StreamReportToHttpClientReport(_client->getLastSendReport()));
697-
ret += r;
698-
} else {
699-
700-
// if no length Header use global chunk size
701-
if(_size <= 0) {
702-
_size = size;
703-
}
704-
705-
// check if we have write all data out
706-
if(ret != _size) {
707-
return returnError(HTTPC_ERROR_STREAM_WRITE);
708-
}
709-
break;
710-
}
711-
712-
// read trailing \r\n at the end of the chunk
713-
char buf[2];
714-
auto trailing_seq_len = _client->readBytes((uint8_t*)buf, 2);
715-
if (trailing_seq_len != 2 || buf[0] != '\r' || buf[1] != '\n') {
716-
return returnError(HTTPC_ERROR_READ_TIMEOUT);
717-
}
718-
719-
esp_yield();
720-
}
721-
} else {
722-
return returnError(HTTPC_ERROR_ENCODING);
723-
}
724-
725-
disconnect(true);
726-
return ret;
727-
}
728-
729630
/**
730631
* return all payload as String (may need lot of ram or trigger out of memory!)
731632
* @return String

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.