Skip to content

add ESP8266WebServer::sendContent_P and ESP8266WebServer::send_P with contentLength #753

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

Merged
merged 8 commits into from
Sep 18, 2015
2 changes: 2 additions & 0 deletions hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,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);
}
Expand Down Expand Up @@ -221,6 +232,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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@ class ESP8266WebServer
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<typename T> size_t streamFile(T &file, const String& contentType){
setContentLength(file.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down