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:
commit
c0e0836a0b
@ -35,8 +35,8 @@ class StringSumHelper;
|
|||||||
// an abstract class used as a means to proide a unique pointer type
|
// an abstract class used as a means to proide a unique pointer type
|
||||||
// but really has no body
|
// but really has no body
|
||||||
class __FlashStringHelper;
|
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
|
// The string class
|
||||||
class String {
|
class String {
|
||||||
|
@ -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 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.
|
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)
|
## WiFi(ESP8266WiFi library)
|
||||||
|
|
||||||
This is mostly similar to WiFi shield library. Differences include:
|
This is mostly similar to WiFi shield library. Differences include:
|
||||||
|
@ -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 += String(code);
|
||||||
response += " ";
|
response += " ";
|
||||||
response += _responseCodeToString(code);
|
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);
|
sendHeader("Content-Type", content_type, true);
|
||||||
if (_contentLength != CONTENT_LENGTH_UNKNOWN && _contentLength != CONTENT_LENGTH_NOT_SET) {
|
if (_contentLength != CONTENT_LENGTH_UNKNOWN && _contentLength != CONTENT_LENGTH_NOT_SET) {
|
||||||
sendHeader("Content-Length", String(_contentLength).c_str());
|
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("Connection", "close");
|
||||||
sendHeader("Access-Control-Allow-Origin", "*");
|
sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
response += _responseHeaders;
|
response += _responseHeaders;
|
||||||
response += "\r\n";
|
response += "\r\n";
|
||||||
response += content;
|
|
||||||
_responseHeaders = String();
|
_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) {
|
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) {
|
String ESP8266WebServer::arg(const char* name) {
|
||||||
for (int i = 0; i < _currentArgCount; ++i) {
|
for (int i = 0; i < _currentArgCount; ++i) {
|
||||||
if (_currentArgs[i].key == name)
|
if (_currentArgs[i].key == name)
|
||||||
|
@ -80,10 +80,12 @@ public:
|
|||||||
void send(int code, const char* content_type = NULL, const String& content = String(""));
|
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, char* content_type, const String& content);
|
||||||
void send(int code, const String& 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 setContentLength(size_t contentLength) { _contentLength = contentLength; }
|
||||||
void sendHeader(const String& name, const String& value, bool first = false);
|
void sendHeader(const String& name, const String& value, bool first = false);
|
||||||
void sendContent(const String& content);
|
void sendContent(const String& content);
|
||||||
|
void sendContent_P(PGM_P content);
|
||||||
|
|
||||||
template<typename T> size_t streamFile(T &file, const String& contentType){
|
template<typename T> size_t streamFile(T &file, const String& contentType){
|
||||||
setContentLength(file.size());
|
setContentLength(file.size());
|
||||||
@ -104,6 +106,7 @@ protected:
|
|||||||
void _parseForm(WiFiClient& client, String boundary, uint32_t len);
|
void _parseForm(WiFiClient& client, String boundary, uint32_t len);
|
||||||
void _uploadWriteByte(uint8_t b);
|
void _uploadWriteByte(uint8_t b);
|
||||||
uint8_t _uploadReadByte(WiFiClient& client);
|
uint8_t _uploadReadByte(WiFiClient& client);
|
||||||
|
void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
|
||||||
|
|
||||||
struct RequestHandler;
|
struct RequestHandler;
|
||||||
struct RequestArgument {
|
struct RequestArgument {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user