diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index ed174b5a0..a2ecd4efe 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -280,6 +280,8 @@ uint32_t EspClass::getFlashChipSizeByChipId(void) { return (2_MB); case 0x1440EF: // W25Q80 return (1_MB); + case 0x1340EF: // W25Q40 + return (512_kB); default: return 0; diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp b/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp index 75474ae70..08416382c 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp @@ -159,11 +159,22 @@ void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content) { } String header; - _prepareHeader(header, code, String(FPSTR(content_type)).c_str(), contentLength); + char type[64]; + memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type)); + _prepareHeader(header, code, (const char* )type, contentLength); sendContent(header); sendContent_P(content); } +void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) { + String header; + char type[64]; + memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type)); + _prepareHeader(header, code, (const char* )type, contentLength); + sendContent(header); + sendContent_P(content, contentLength); +} + void ESP8266WebServer::send(int code, char* content_type, const String& content) { send(code, (const char*)content_type, content); } @@ -216,6 +227,26 @@ void ESP8266WebServer::sendContent_P(PGM_P content) { } } +void ESP8266WebServer::sendContent_P(PGM_P content, size_t size) { + char contentUnit[HTTP_DOWNLOAD_UNIT_SIZE + 1]; + contentUnit[HTTP_DOWNLOAD_UNIT_SIZE] = '\0'; + size_t remaining_size = size; + + while (content != NULL && remaining_size > 0) { + size_t contentUnitLen = HTTP_DOWNLOAD_UNIT_SIZE; + + if (remaining_size < HTTP_DOWNLOAD_UNIT_SIZE) contentUnitLen = remaining_size; + // due to the memcpy signature, lots of casts are needed + memcpy_P((void*)contentUnit, (PGM_VOID_P)content, contentUnitLen); + + content += contentUnitLen; + remaining_size -= contentUnitLen; + + // write is so overloaded, had to use the cast to get it pick the right one + _currentClient.write((const char*)contentUnit, contentUnitLen); + } +} + String ESP8266WebServer::arg(const char* name) { for (int i = 0; i < _currentArgCount; ++i) { if (_currentArgs[i].key == name) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 33b7b8401..fad9fc55c 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -90,11 +90,13 @@ public: void send(int code, char* content_type, const String& content); void send(int code, const String& content_type, const String& content); void send_P(int code, PGM_P content_type, PGM_P content); + void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength); void setContentLength(size_t contentLength) { _contentLength = contentLength; } void sendHeader(const String& name, const String& value, bool first = false); void sendContent(const String& content); void sendContent_P(PGM_P content); + void sendContent_P(PGM_P content, size_t size); template size_t streamFile(T &file, const String& contentType){ setContentLength(file.size()); diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index 8165ba3ba..d881c4a87 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -186,24 +186,19 @@ size_t WiFiClient::write_P(PGM_P buf, size_t size) char chunkUnit[WIFICLIENT_MAX_PACKET_SIZE + 1]; chunkUnit[WIFICLIENT_MAX_PACKET_SIZE] = '\0'; - while (buf != NULL) - { - size_t chunkUnitLen; - PGM_P chunkNext; - chunkNext = (PGM_P)memccpy_P((void*)chunkUnit, (PGM_VOID_P)buf, 0, WIFICLIENT_MAX_PACKET_SIZE); - if (chunkNext == NULL) - { - // no terminator, more data available - buf += WIFICLIENT_MAX_PACKET_SIZE; - chunkUnitLen = WIFICLIENT_MAX_PACKET_SIZE; - } - else - { - // reached terminator - chunkUnitLen = chunkNext - buf; - buf = NULL; - } - if (size < WIFICLIENT_MAX_PACKET_SIZE) chunkUnitLen = size; + size_t remaining_size = size; + + while (buf != NULL && remaining_size > 0) { + size_t chunkUnitLen = WIFICLIENT_MAX_PACKET_SIZE; + + if (remaining_size < WIFICLIENT_MAX_PACKET_SIZE) chunkUnitLen = remaining_size; + // due to the memcpy signature, lots of casts are needed + memcpy_P((void*)chunkUnit, (PGM_VOID_P)buf, chunkUnitLen); + + buf += chunkUnitLen; + remaining_size -= chunkUnitLen; + + // write is so overloaded, had to use the cast to get it pick the right one _client->write((const char*)chunkUnit, chunkUnitLen); } return size;