mirror of https://github.com/lumapu/ahoy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.4 KiB
108 lines
3.4 KiB
//-----------------------------------------------------------------------------
|
|
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef __TMPL_PROC__
|
|
#define __TMPL_PROC__
|
|
|
|
// HTML template processor, searches keywords and calls callback
|
|
// inspired by: https://github.com/plapointe6/EspHtmlTemplateProcessor
|
|
|
|
#include "dbg.h"
|
|
#include <string.h>
|
|
#include <functional>
|
|
#include "ESPAsyncWebServer.h"
|
|
|
|
#define MAX_BUFFER_SIZE 256
|
|
#define MAX_KEY_LEN 20
|
|
enum { ST_NONE = 0, ST_BUF, ST_PROC, ST_START, ST_KEY };
|
|
|
|
typedef std::function<String(char* key)> TmplCb;
|
|
|
|
class tmplProc {
|
|
public:
|
|
tmplProc(AsyncWebServerRequest *request, uint32_t bufStartSize = 1000) {
|
|
// Note: don't choose the bufStartSize to small. A too small start
|
|
// size will result in fractioned memory and maybe in a zero
|
|
// increase -> fail (Arduino - cbuf.cpp)
|
|
mRequest = request;
|
|
mResponse = request->beginResponseStream("text/html", bufStartSize);
|
|
}
|
|
|
|
~tmplProc() {}
|
|
|
|
void process(const char* tmpl, const uint32_t tmplLen, TmplCb cb) {
|
|
char* buf = new char[MAX_BUFFER_SIZE];
|
|
char* p = buf;
|
|
uint32_t len = 0, pos = 0, i = 0;
|
|
uint8_t state = ST_BUF;
|
|
bool complete = false;
|
|
|
|
while (i < tmplLen) {
|
|
switch (state) {
|
|
default:
|
|
DPRINTLN(DBG_DEBUG, F("unknown state"));
|
|
break;
|
|
case ST_BUF:
|
|
if(0 != i) {
|
|
buf[pos] = '\0';
|
|
mResponse->print(p);
|
|
}
|
|
pos = 0;
|
|
len = ((tmplLen - i) > MAX_BUFFER_SIZE) ? MAX_BUFFER_SIZE : (tmplLen - i);
|
|
if((len + i) == tmplLen)
|
|
complete = true;
|
|
memcpy_P(buf, &tmpl[i], len);
|
|
if(len < MAX_BUFFER_SIZE)
|
|
buf[len] = '\0';
|
|
p = buf;
|
|
state = ST_PROC;
|
|
break;
|
|
|
|
case ST_PROC:
|
|
if(((pos + MAX_KEY_LEN) >= len) && !complete)
|
|
state = ST_BUF;
|
|
else if(buf[pos] == '{')
|
|
state = ST_START;
|
|
break;
|
|
|
|
case ST_START:
|
|
if(buf[pos] == '#') {
|
|
if(pos != 0)
|
|
buf[pos-1] = '\0';
|
|
mResponse->print(p);
|
|
p = &buf[pos+1];
|
|
state = ST_KEY;
|
|
}
|
|
else
|
|
state = ST_PROC;
|
|
break;
|
|
|
|
case ST_KEY:
|
|
if(buf[pos] == '}') {
|
|
buf[pos] = '\0';
|
|
mResponse->print((cb)(p));
|
|
p = &buf[pos+1];
|
|
state = ST_PROC;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(ST_BUF != state) {
|
|
pos++;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
mResponse->print(p);
|
|
delete[] buf;
|
|
mRequest->send(mResponse);
|
|
}
|
|
|
|
private:
|
|
AsyncWebServerRequest *mRequest;
|
|
AsyncResponseStream *mResponse;
|
|
};
|
|
|
|
#endif /*__TMPL_PROC__*/
|
|
|