Skip to content

Commit b63c975

Browse files
committed
Merge pull request #753 from martinayotte/esp8266
add ESP8266WebServer::sendContent_P and ESP8266WebServer::send_P with contentLength
2 parents 89df285 + 26537be commit b63c975

File tree

4 files changed

+49
-19
lines changed

4 files changed

+49
-19
lines changed

hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ uint32_t EspClass::getFlashChipSizeByChipId(void) {
280280
return (2_MB);
281281
case 0x1440EF: // W25Q80
282282
return (1_MB);
283+
case 0x1340EF: // W25Q40
284+
return (512_kB);
283285

284286
default:
285287
return 0;

hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp

+32-1
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,22 @@ void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
159159
}
160160

161161
String header;
162-
_prepareHeader(header, code, String(FPSTR(content_type)).c_str(), contentLength);
162+
char type[64];
163+
memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
164+
_prepareHeader(header, code, (const char* )type, contentLength);
163165
sendContent(header);
164166
sendContent_P(content);
165167
}
166168

169+
void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) {
170+
String header;
171+
char type[64];
172+
memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
173+
_prepareHeader(header, code, (const char* )type, contentLength);
174+
sendContent(header);
175+
sendContent_P(content, contentLength);
176+
}
177+
167178
void ESP8266WebServer::send(int code, char* content_type, const String& content) {
168179
send(code, (const char*)content_type, content);
169180
}
@@ -216,6 +227,26 @@ void ESP8266WebServer::sendContent_P(PGM_P content) {
216227
}
217228
}
218229

230+
void ESP8266WebServer::sendContent_P(PGM_P content, size_t size) {
231+
char contentUnit[HTTP_DOWNLOAD_UNIT_SIZE + 1];
232+
contentUnit[HTTP_DOWNLOAD_UNIT_SIZE] = '\0';
233+
size_t remaining_size = size;
234+
235+
while (content != NULL && remaining_size > 0) {
236+
size_t contentUnitLen = HTTP_DOWNLOAD_UNIT_SIZE;
237+
238+
if (remaining_size < HTTP_DOWNLOAD_UNIT_SIZE) contentUnitLen = remaining_size;
239+
// due to the memcpy signature, lots of casts are needed
240+
memcpy_P((void*)contentUnit, (PGM_VOID_P)content, contentUnitLen);
241+
242+
content += contentUnitLen;
243+
remaining_size -= contentUnitLen;
244+
245+
// write is so overloaded, had to use the cast to get it pick the right one
246+
_currentClient.write((const char*)contentUnit, contentUnitLen);
247+
}
248+
}
249+
219250
String ESP8266WebServer::arg(const char* name) {
220251
for (int i = 0; i < _currentArgCount; ++i) {
221252
if (_currentArgs[i].key == name)

hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/ESP8266WebServer.h

+2
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,13 @@ class ESP8266WebServer
9090
void send(int code, char* content_type, const String& content);
9191
void send(int code, const String& content_type, const String& content);
9292
void send_P(int code, PGM_P content_type, PGM_P content);
93+
void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength);
9394

9495
void setContentLength(size_t contentLength) { _contentLength = contentLength; }
9596
void sendHeader(const String& name, const String& value, bool first = false);
9697
void sendContent(const String& content);
9798
void sendContent_P(PGM_P content);
99+
void sendContent_P(PGM_P content, size_t size);
98100

99101
template<typename T> size_t streamFile(T &file, const String& contentType){
100102
setContentLength(file.size());

hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp

+13-18
Original file line numberDiff line numberDiff line change
@@ -186,24 +186,19 @@ size_t WiFiClient::write_P(PGM_P buf, size_t size)
186186

187187
char chunkUnit[WIFICLIENT_MAX_PACKET_SIZE + 1];
188188
chunkUnit[WIFICLIENT_MAX_PACKET_SIZE] = '\0';
189-
while (buf != NULL)
190-
{
191-
size_t chunkUnitLen;
192-
PGM_P chunkNext;
193-
chunkNext = (PGM_P)memccpy_P((void*)chunkUnit, (PGM_VOID_P)buf, 0, WIFICLIENT_MAX_PACKET_SIZE);
194-
if (chunkNext == NULL)
195-
{
196-
// no terminator, more data available
197-
buf += WIFICLIENT_MAX_PACKET_SIZE;
198-
chunkUnitLen = WIFICLIENT_MAX_PACKET_SIZE;
199-
}
200-
else
201-
{
202-
// reached terminator
203-
chunkUnitLen = chunkNext - buf;
204-
buf = NULL;
205-
}
206-
if (size < WIFICLIENT_MAX_PACKET_SIZE) chunkUnitLen = size;
189+
size_t remaining_size = size;
190+
191+
while (buf != NULL && remaining_size > 0) {
192+
size_t chunkUnitLen = WIFICLIENT_MAX_PACKET_SIZE;
193+
194+
if (remaining_size < WIFICLIENT_MAX_PACKET_SIZE) chunkUnitLen = remaining_size;
195+
// due to the memcpy signature, lots of casts are needed
196+
memcpy_P((void*)chunkUnit, (PGM_VOID_P)buf, chunkUnitLen);
197+
198+
buf += chunkUnitLen;
199+
remaining_size -= chunkUnitLen;
200+
201+
// write is so overloaded, had to use the cast to get it pick the right one
207202
_client->write((const char*)chunkUnit, chunkUnitLen);
208203
}
209204
return size;

0 commit comments

Comments
 (0)