1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

Merge branch 'WifiSendP' of https://github.com/Makuna/Arduino into Makuna-WifiSendP

Conflicts:
	README.md
This commit is contained in:
Ivan Grokhotkov 2015-07-28 18:15:20 +03:00
commit c0e0836a0b
4 changed files with 104 additions and 26 deletions

View File

@ -35,8 +35,8 @@ class StringSumHelper;
// an abstract class used as a means to proide a unique pointer type
// but really has no body
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#define F(string_literal) (FPSTR(PSTR(string_literal)))
// The string class
class String {

View File

@ -78,6 +78,32 @@ Both `Serial` and `Serial1` objects support 5, 6, 7, 8 data bits, odd (O), even
The Program memory features work much the same way as on a regular Arduino; placing read only data and strings in read only memory and freeing heap for your application.
The important difference is that on the ESP8266 the literal strings are not pooled. This means that the same literal string defined inside a `F("")` and/or `PSTR("")` will take up space for each instance in the code. So you will need to manage the duplicate strings yourself.
There is one additional helper macro to make it easier to pass ```const PROGMEM``` strings to methods that take a ```__FlashStringHelper``` called ```FPSTR()```. The use of this will help make it easier to pool strings.
Not pooling strings...
```С++
String response1;
response1 += F("http:");
...
String response2;
response2 += F("http:");
```
using FPSTR would become...
```С++
const char HTTP[] PROGMEM = "http:";
...
{
String response1;
response1 += FPSTR(HTTP);
...
String response2;
response2 += FPSTR(HTTP);
}
```
## WiFi(ESP8266WiFi library)
This is mostly similar to WiFi shield library. Differences include:

View File

@ -129,8 +129,9 @@ void ESP8266WebServer::sendHeader(const String& name, const String& value, bool
}
}
void ESP8266WebServer::send(int code, const char* content_type, const String& content) {
String response = "HTTP/1.1 ";
void ESP8266WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
response = "HTTP/1.1 ";
response += String(code);
response += " ";
response += _responseCodeToString(code);
@ -142,17 +143,37 @@ void ESP8266WebServer::send(int code, const char* content_type, const String& co
sendHeader("Content-Type", content_type, true);
if (_contentLength != CONTENT_LENGTH_UNKNOWN && _contentLength != CONTENT_LENGTH_NOT_SET) {
sendHeader("Content-Length", String(_contentLength).c_str());
} else if(content.length() > 0){
sendHeader("Content-Length", String(content.length()).c_str());
}
else if (contentLength > 0){
sendHeader("Content-Length", String(contentLength).c_str());
}
sendHeader("Connection", "close");
sendHeader("Access-Control-Allow-Origin", "*");
response += _responseHeaders;
response += "\r\n";
response += content;
_responseHeaders = String();
sendContent(response);
}
void ESP8266WebServer::send(int code, const char* content_type, const String& content) {
String header;
_prepareHeader(header, code, content_type, content.length());
sendContent(header);
sendContent(content);
}
void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
size_t contentLength = 0;
if (content != NULL) {
contentLength = strlen_P(content);
}
String header;
_prepareHeader(header, code, String(FPSTR(content_type)).c_str(), contentLength);
sendContent(header);
sendContent_P(content);
}
void ESP8266WebServer::send(int code, char* content_type, const String& content) {
@ -178,6 +199,34 @@ void ESP8266WebServer::sendContent(const String& content) {
}
}
void ESP8266WebServer::sendContent_P(PGM_P content) {
char contentUnit[HTTP_DOWNLOAD_UNIT_SIZE + 1];
contentUnit[HTTP_DOWNLOAD_UNIT_SIZE] = '\0';
while (content != NULL) {
size_t contentUnitLen;
PGM_P contentNext;
// due to the memccpy signature, lots of casts are needed
contentNext = (PGM_P)memccpy_P((void*)contentUnit, (PGM_VOID_P)content, 0, HTTP_DOWNLOAD_UNIT_SIZE);
if (contentNext == NULL) {
// no terminator, more data available
content += HTTP_DOWNLOAD_UNIT_SIZE;
contentUnitLen = HTTP_DOWNLOAD_UNIT_SIZE;
}
else {
// reached terminator
contentUnitLen = contentNext - content;
content = NULL;
}
// 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)

View File

@ -80,10 +80,12 @@ public:
void send(int code, const char* content_type = NULL, const String& content = String(""));
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 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);
template<typename T> size_t streamFile(T &file, const String& contentType){
setContentLength(file.size());
@ -104,6 +106,7 @@ protected:
void _parseForm(WiFiClient& client, String boundary, uint32_t len);
void _uploadWriteByte(uint8_t b);
uint8_t _uploadReadByte(WiFiClient& client);
void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
struct RequestHandler;
struct RequestArgument {