Supports AutoConnectAux

pull/41/head
Hieromon Ikasamo 5 years ago
parent 071d92369f
commit a7402ea391
  1. 1
      keywords.txt
  2. 9
      src/AutoConnect.cpp
  3. 6
      src/AutoConnect.h
  4. 226
      src/AutoConnectAux.cpp
  5. 61
      src/AutoConnectAux.h
  6. 2
      src/AutoConnectPage.cpp

@ -39,7 +39,6 @@ onDetect KEYWORD2
onNotFound KEYWORD2
release KEYWORD2
save KEYWORD2
saveElement KEYWORD2
setElementValue KEYWORD2
setTitle KEYWORD2
toHTML KEYWORD2

@ -285,10 +285,10 @@ WebServerClass& AutoConnect::host() {
* @param uri An uri string.
* @return A pointer of AutoConnectAux instance.
*/
AutoConnectAux* AutoConnect::aux(const char* uri) const {
AutoConnectAux* AutoConnect::aux(const String& uri) const {
AutoConnectAux* aux_p = _aux.get();
while (aux_p) {
if (!strcmp(aux_p->uri(), uri))
if (!strcmp(aux_p->uri(), uri.c_str()))
break;
aux_p = aux_p->_next.get();
}
@ -339,7 +339,6 @@ void AutoConnect::_startWebServer() {
_webServer->onNotFound(std::bind(&AutoConnect::_handleNotFound, this));
// here, Prepare PageBuilders for captive portal
_responsePage = new PageBuilder();
// _responsePage->chunked(PB_ByteStream);
_responsePage->chunked(PB_ByteStream);
_responsePage->exitCanHandle(std::bind(&AutoConnect::_classifyHandle, this, std::placeholders::_1, std::placeholders::_2));
_responsePage->insert(*_webServer);
@ -460,10 +459,10 @@ void AutoConnect::handleRequest() {
* @return false AutoConnectAux page for the specified URI is not
* registered.
*/
bool AutoConnect::on(const char* uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order) {
bool AutoConnect::on(const String& uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order) {
AutoConnectAux* aux = _aux.get();
while (aux) {
if (!strcmp(uri, aux->uri())) {
if (!strcmp(uri.c_str(), aux->uri())) {
aux->on(handler, order);
return true;
}

@ -154,7 +154,7 @@ class AutoConnect {
AutoConnect();
AutoConnect(WebServerClass& webServer);
~AutoConnect();
AutoConnectAux* aux(const char* uri) const;
AutoConnectAux* aux(const String& uri) const;
bool config(AutoConnectConfig& Config);
bool config(const char* ap, const char* password = nullptr);
void home(String uri);
@ -166,11 +166,11 @@ class AutoConnect {
WebServerClass& host();
bool join(AutoConnectAux& aux);
bool join(std::vector<std::reference_wrapper<AutoConnectAux>> aux);
bool on(const char* uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order = AC_EXIT_AHEAD);
bool on(const String& uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order = AC_EXIT_AHEAD);
/** For AutoConnectAux described in JSON */
#ifdef AUTOCONNECT_USE_JSON
bool load(const char* aux);
bool load(const String& aux);
bool load(const __FlashStringHelper* aux);
bool load(Stream& aux, size_t bufferSize = AUTOCONNECT_JSON_BUFFER_SIZE);
bool _load(JsonVariant& aux);

@ -93,7 +93,7 @@ void AutoConnectAux::add(AutoConnectElementVT addons) {
* @param name Element name
* @return A pointer to the registered AutoConnectElement.
*/
AutoConnectElement* AutoConnectAux::getElement(const String name) {
AutoConnectElement* AutoConnectAux::getElement(const String& name) {
for (std::size_t n = 0; n < _addonElm.size(); n++)
if (name.equalsIgnoreCase(_addonElm[n].get().name))
return &(_addonElm[n].get());
@ -109,7 +109,7 @@ AutoConnectElement* AutoConnectAux::getElement(const String name) {
* @return true The specified AutoConnectElements have been released.
* @return false The specified AutoConnectElement not found in AutoConnectAux.
*/
bool AutoConnectAux::release(const String name) {
bool AutoConnectAux::release(const String& name) {
bool rc = false;
for (std::size_t n = 0; n < _addonElm.size(); n++) {
String elmName = _addonElm[n].get().name;
@ -130,7 +130,7 @@ bool AutoConnectAux::release(const String name) {
* @return false An element specified name is not registered,
* or its element value does not match storage type.
*/
bool AutoConnectAux::setElementValue(const String name, const String value) {
bool AutoConnectAux::setElementValue(const String& name, const String value) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() != AC_Select && elm->typeOf() != AC_Radio) {
@ -151,7 +151,7 @@ bool AutoConnectAux::setElementValue(const String name, const String value) {
* @return false An element specified name is not registered,
* or its element value must be array.
*/
bool AutoConnectAux::setElementValue(const String name, std::vector<String> values) {
bool AutoConnectAux::setElementValue(const String& name, std::vector<String> values) {
bool rc = false;
AutoConnectElement* elm = getElement(name);
@ -271,17 +271,17 @@ PageElement* AutoConnectAux::_setupPage(String uri) {
elm = new PageElement();
// Construct the auxiliary page
elm->setMold(_PAGE_AUX);
elm->addToken(PSTR("HEAD"), std::bind(&AutoConnect::_token_HEAD, mother, std::placeholders::_1));
elm->addToken(PSTR("AUX_TITLE"), std::bind(&AutoConnectAux::_injectTitle, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, mother, std::placeholders::_1));
elm->addToken(PSTR("CSS_UL"), std::bind(&AutoConnect::_token_CSS_UL, mother, std::placeholders::_1));
elm->addToken(PSTR("CSS_INPUT_BUTTON"), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, mother, std::placeholders::_1));
elm->addToken(PSTR("CSS_INPUT_TEXT"), std::bind(&AutoConnect::_token_CSS_INPUT_TEXT, mother, std::placeholders::_1));
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, mother, std::placeholders::_1));
elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, mother, std::placeholders::_1));
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, mother, std::placeholders::_1));
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, mother, std::placeholders::_1));
elm->addToken(PSTR("AUX_ELEMENT"), std::bind(&AutoConnectAux::_insertElement, this, std::placeholders::_1));
elm->addToken(String(FPSTR("HEAD")), std::bind(&AutoConnect::_token_HEAD, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("AUX_TITLE")), std::bind(&AutoConnectAux::_injectTitle, this, std::placeholders::_1));
elm->addToken(String(FPSTR("CSS_BASE")), std::bind(&AutoConnect::_token_CSS_BASE, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("CSS_UL")), std::bind(&AutoConnect::_token_CSS_UL, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("CSS_INPUT_BUTTON")), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("CSS_INPUT_TEXT")), std::bind(&AutoConnect::_token_CSS_INPUT_TEXT, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("CSS_LUXBAR")), std::bind(&AutoConnect::_token_CSS_LUXBAR, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("MENU_PRE")), std::bind(&AutoConnect::_token_MENU_PRE, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("MENU_AUX")), std::bind(&AutoConnect::_token_MENU_AUX, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("AUX_ELEMENT")), std::bind(&AutoConnectAux::_insertElement, this, std::placeholders::_1));
}
}
return elm;
@ -323,13 +323,13 @@ AutoConnectElement& AutoConnectAux::_nullElement() {
* @return A reference of AutoConnectButton class.
*/
template<>
AutoConnectButtonBasis& AutoConnectAux::getElement(const char* name) {
AutoConnectButtonBasis& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Button)
return *(reinterpret_cast<AutoConnectButtonBasis*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectButtonBasis&>(_nullElement());
}
@ -340,13 +340,13 @@ AutoConnectButtonBasis& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectCheckbox class.
*/
template<>
AutoConnectCheckboxBasis& AutoConnectAux::getElement(const char* name) {
AutoConnectCheckboxBasis& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Checkbox)
return *(reinterpret_cast<AutoConnectCheckboxBasis*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectCheckboxBasis&>(_nullElement());
}
@ -357,13 +357,13 @@ AutoConnectCheckboxBasis& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectInput class.
*/
template<>
AutoConnectInputBasis& AutoConnectAux::getElement(const char* name) {
AutoConnectInputBasis& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Input)
return *(reinterpret_cast<AutoConnectInputBasis*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectInputBasis&>(_nullElement());
}
@ -374,13 +374,13 @@ AutoConnectInputBasis& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectRadio class.
*/
template<>
AutoConnectRadioBasis& AutoConnectAux::getElement(const char* name) {
AutoConnectRadioBasis& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Radio)
return *(reinterpret_cast<AutoConnectRadioBasis*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectRadioBasis&>(_nullElement());
}
@ -391,13 +391,13 @@ AutoConnectRadioBasis& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectSelect class.
*/
template<>
AutoConnectSelectBasis& AutoConnectAux::getElement(const char* name) {
AutoConnectSelectBasis& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Select)
return *(reinterpret_cast<AutoConnectSelectBasis*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectSelectBasis&>(_nullElement());
}
@ -408,13 +408,13 @@ AutoConnectSelectBasis& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectSubmit class.
*/
template<>
AutoConnectSubmitBasis& AutoConnectAux::getElement(const char* name) {
AutoConnectSubmitBasis& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Submit)
return *(reinterpret_cast<AutoConnectSubmitBasis*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectSubmitBasis&>(_nullElement());
}
@ -425,13 +425,13 @@ AutoConnectSubmitBasis& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectText class.
*/
template<>
AutoConnectTextBasis& AutoConnectAux::getElement(const char* name) {
AutoConnectTextBasis& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Text)
return *(reinterpret_cast<AutoConnectTextBasis*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectTextBasis&>(_nullElement());
}
@ -459,13 +459,13 @@ bool AutoConnectAux::_jbLiteral; /**< JSON object lexical status */
* @return A reference of AutoConnectButton class.
*/
template<>
AutoConnectButtonJson& AutoConnectAux::getElement(const char* name) {
AutoConnectButtonJson& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Button)
return *(reinterpret_cast<AutoConnectButtonJson*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectButtonJson&>(_nullElement());
}
@ -476,13 +476,13 @@ AutoConnectButtonJson& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectCheckbox class.
*/
template<>
AutoConnectCheckboxJson& AutoConnectAux::getElement(const char* name) {
AutoConnectCheckboxJson& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Checkbox)
return *(reinterpret_cast<AutoConnectCheckboxJson*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectCheckboxJson&>(_nullElement());
}
@ -493,13 +493,13 @@ AutoConnectCheckboxJson& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectInput class.
*/
template<>
AutoConnectInputJson& AutoConnectAux::getElement(const char* name) {
AutoConnectInputJson& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Input)
return *(reinterpret_cast<AutoConnectInputJson*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectInputJson&>(_nullElement());
}
@ -510,13 +510,13 @@ AutoConnectInputJson& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectRadio class.
*/
template<>
AutoConnectRadioJson& AutoConnectAux::getElement(const char* name) {
AutoConnectRadioJson& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Radio)
return *(reinterpret_cast<AutoConnectRadioJson*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectRadioJson&>(_nullElement());
}
@ -527,13 +527,13 @@ AutoConnectRadioJson& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectSelect class.
*/
template<>
AutoConnectSelectJson& AutoConnectAux::getElement(const char* name) {
AutoConnectSelectJson& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Select)
return *(reinterpret_cast<AutoConnectSelectJson*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectSelectJson&>(_nullElement());
}
@ -544,13 +544,13 @@ AutoConnectSelectJson& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectSubmit class.
*/
template<>
AutoConnectSubmitJson& AutoConnectAux::getElement(const char* name) {
AutoConnectSubmitJson& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Submit)
return *(reinterpret_cast<AutoConnectSubmitJson*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectSubmitJson&>(_nullElement());
}
@ -561,13 +561,13 @@ AutoConnectSubmitJson& AutoConnectAux::getElement(const char* name) {
* @return A reference of AutoConnectText class.
*/
template<>
AutoConnectTextJson& AutoConnectAux::getElement(const char* name) {
AutoConnectTextJson& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Text)
return *(reinterpret_cast<AutoConnectTextJson*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name, elm->typeOf());
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectTextJson&>(_nullElement());
}
@ -579,20 +579,20 @@ AutoConnectTextJson& AutoConnectAux::getElement(const char* name) {
* @param aux JSON description to be load.
* @return true Successfully loaded.
*/
bool AutoConnect::load(const char* aux) {
const size_t bufferSize = AutoConnectAux::_calcJsonBufferSize(aux);
bool AutoConnect::load(const String& aux) {
const size_t bufferSize = AutoConnectAux::_calcJsonBufferSize(aux.c_str());
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonVariant jv = jsonBuffer.parse(aux);
return _load(jv);
}
/**
* Load AutoConnectAux page from JSON description stored in PROGMEM.
* This function can load AutoConnectAux for multiple AUX pages written
* in JSON and is registered in AutoConnect.
* @param aux JSON description to be load.
* @return true Successfully loaded.
*/
* Load AutoConnectAux page from JSON description stored in PROGMEM.
* This function can load AutoConnectAux for multiple AUX pages written
* in JSON and is registered in AutoConnect.
* @param aux JSON description to be load.
* @return true Successfully loaded.
*/
bool AutoConnect::load(const __FlashStringHelper* aux) {
const size_t bufferSize = AutoConnectAux::_calcJsonBufferSize(aux);
DynamicJsonBuffer jsonBuffer(bufferSize);
@ -704,8 +704,8 @@ AutoConnectElement* AutoConnectAux::_createElement(const JsonObject& json) {
* @return true The element collection successfully loaded.
* @return false Invalid JSON data occurred.
*/
bool AutoConnectAux::load(const char* in) {
const size_t bufferSize = _calcJsonBufferSize(in);
bool AutoConnectAux::load(const String& in) {
const size_t bufferSize = _calcJsonBufferSize(in.c_str());
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& jb = jsonBuffer.parseObject(in);
return _load(jb);
@ -756,7 +756,8 @@ bool AutoConnectAux::_load(JsonObject& jb) {
_uriStr = jb.get<String>(F(AUTOCONNECT_JSON_KEY_URI));
_uri = _uriStr.c_str();
_menu = jb.get<bool>(F(AUTOCONNECT_JSON_KEY_MENU));
(void)_loadElement(jb, "*");
JsonVariant elements = jb[F(AUTOCONNECT_JSON_KEY_ELEMENT)];
(void)_loadElement(elements, "");
return true;
}
@ -770,61 +771,72 @@ bool AutoConnectAux::_load(JsonObject& jb) {
* elements are to be loaded.
* @return A reference of loaded AutoConnectElement instance.
*/
AutoConnectElement& AutoConnectAux::loadElement(const String in, const String name) {
bool AutoConnectAux::loadElement(const String& in, const String& name) {
const size_t bufferSize = _calcJsonBufferSize(in.c_str());
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& jb = jsonBuffer.parseObject(in);
JsonVariant jb = jsonBuffer.parse(in);
return _loadElement(jb, name);
}
AutoConnectElement& AutoConnectAux::loadElement(const __FlashStringHelper* in, const String name) {
bool AutoConnectAux::loadElement(const __FlashStringHelper* in, const String& name) {
const size_t bufferSize = _calcJsonBufferSize(in);
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& jb = jsonBuffer.parseObject(in);
JsonVariant jb = jsonBuffer.parse(in);
return _loadElement(jb, name);
}
AutoConnectElement& AutoConnectAux::loadElement(Stream& in, const String name, const size_t bufferSize) {
bool AutoConnectAux::loadElement(Stream& in, const String& name, const size_t bufferSize) {
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& jb = jsonBuffer.parseObject(in);
JsonVariant jb = jsonBuffer.parse(in);
return _loadElement(jb, name);
}
AutoConnectElement& AutoConnectAux::_loadElement(JsonObject& jb, const String name) {
AutoConnectElement* auxElm = nullptr;
bool wc = name == "*";
if (!jb.success()) {
AC_DBG("json parse error\n");
return _nullElement();
bool AutoConnectAux::_loadElement(JsonVariant& jb, const String& name) {
bool rc = jb.success();
if (rc) {
if (jb.is<JsonArray>()) {
JsonArray& elements = jb.as<JsonArray>();
for (JsonObject& element : elements) {
AutoConnectElement& elm = _loadElement(element, name);
if (!elm.name.length()) {
rc = false;
break;
}
}
}
else {
JsonObject& element = jb.as<JsonObject>();
AutoConnectElement& elm = _loadElement(element, name);
if (!elm.name.length())
rc = false;
}
}
return rc;
}
JsonArray& elements = jb[AUTOCONNECT_JSON_KEY_ELEMENT];
for (JsonObject& element : elements) {
String elmName = element.get<String>(F(AUTOCONNECT_JSON_KEY_NAME));
if (wc || name.equalsIgnoreCase(elmName)) {
// The specified element is defined in the JSON stream.
// Loads from JSON object.
auxElm = getElement(elmName);
// The element is not created yet, create new one.
if (!auxElm) {
if ((auxElm = _createElement(element))) {
AC_DBG("%s<%d> of %s created\n", elmName.c_str(), (int)(auxElm->typeOf()), uri());
add(*auxElm); // Insert to AutoConnect
}
else {
AC_DBG("%s unknown element type\n", elmName.c_str());
continue;
}
AutoConnectElement& AutoConnectAux::_loadElement(JsonObject& element, const String& name) {
AutoConnectElement* auxElm = nullptr;
String elmName = element.get<String>(F(AUTOCONNECT_JSON_KEY_NAME));
if (!name.length() || name.equalsIgnoreCase(elmName)) {
// The specified element is defined in the JSON stream.
// Loads from JSON object.
auxElm = getElement(elmName);
// The element is not created yet, create new one.
if (!auxElm) {
if ((auxElm = _createElement(element))) {
AC_DBG("%s<%d> of %s created\n", elmName.c_str(), (int)(auxElm->typeOf()), uri());
add(*auxElm); // Insert to AutoConnect
}
if (auxElm->loadMember(element))
AC_DBG("%s<%d> of %s loaded\n", auxElm->name.c_str(), (int)auxElm->typeOf(), uri());
else {
// Element type mismatch
AC_DBG("Type of %s element mismatched\n", elmName.c_str());
continue;
AC_DBG("%s unknown element type\n", elmName.c_str());
}
}
if (auxElm->loadMember(element))
AC_DBG("%s<%d> of %s loaded\n", auxElm->name.c_str(), (int)auxElm->typeOf(), uri());
else {
// Element type mismatch
AC_DBG("Type of %s element mismatched\n", elmName.c_str());
}
}
return auxElm ? *auxElm : _nullElement();
}
@ -864,7 +876,7 @@ size_t AutoConnectAux::save(Stream& out) {
* @param name An element name to be output.
* @return Number of bytes output
*/
size_t AutoConnectAux::saveElement(const String name, Stream& out) {
size_t AutoConnectAux::saveElement(const String& name, Stream& out) {
for (std::size_t n = 0; n < _addonElm.size(); n++) {
AutoConnectElement& elm = _addonElm[n];
if (elm.name == name) {
@ -882,7 +894,7 @@ size_t AutoConnectAux::saveElement(const String name, Stream& out) {
* @param type An element type as String
* @return A type of ACElement_t
*/
const ACElement_t AutoConnectAux::_asElementType(const String type) {
const ACElement_t AutoConnectAux::_asElementType(const String& type) {
typedef struct {
const char* tName;
ACElement_t tEnum;
@ -900,17 +912,17 @@ const ACElement_t AutoConnectAux::_asElementType(const String type) {
ACElement_t t = AC_Unknown;
for (size_t n = 0; n < (sizeof(types) / sizeof(ACElementType_t)); n++) {
if (type.equalsIgnoreCase(String(types[n].tName)))
if (type.equalsIgnoreCase(String(FPSTR(types[n].tName))))
return types[n].tEnum;
}
return t;
}
/**
* Calculate JSON dynamic buffer size.
* @param in JSON string
* @return Estimated buffer size.
*/
* Calculate JSON dynamic buffer size.
* @param in JSON string
* @return Estimated buffer size.
*/
size_t AutoConnectAux::_calcJsonBufferSize(const char* in) {
_initJsonBufferSize();
while (*in)
@ -919,10 +931,10 @@ size_t AutoConnectAux::_calcJsonBufferSize(const char* in) {
}
/**
* Calculate JSON dynamic buffer size.
* @param in JSON string stored in pgm_data.
* @return Estimated buffer size.
*/
* Calculate JSON dynamic buffer size.
* @param in JSON string stored in pgm_data.
* @return Estimated buffer size.
*/
size_t AutoConnectAux::_calcJsonBufferSize(const __FlashStringHelper* in) {
_initJsonBufferSize();
uint8_t c = pgm_read_byte_near(reinterpret_cast<const char*>(in));
@ -935,8 +947,8 @@ size_t AutoConnectAux::_calcJsonBufferSize(const __FlashStringHelper* in) {
}
/**
* Initialize the stacks for JSON Dynamic buffer size calculation.
*/
* Initialize the stacks for JSON Dynamic buffer size calculation.
*/
void AutoConnectAux::_initJsonBufferSize() {
_jbSize = 0;
_jbByte = 0;
@ -950,8 +962,8 @@ void AutoConnectAux::_initJsonBufferSize() {
}
/**
* Accumulate JSON Dynamic buffer size.
*/
* Accumulate JSON Dynamic buffer size.
*/
void AutoConnectAux::_accJsonBufferSize(const char c) {
if (_jbSize < 0)
return;
@ -1029,9 +1041,9 @@ void AutoConnectAux::_accJsonBufferSize(const char c) {
}
/**
* Retrieve accumulated result value of JSON dynamic buffer size.
* @return the JSON Dynamic Buffer Size
*/
* Retrieve accumulated result value of JSON dynamic buffer size.
* @return the JSON Dynamic Buffer Size
*/
size_t AutoConnectAux::_resultJsonBufferSize() {
if (_jbSize < 0) {
AC_DBG("json buffer calculation error\n");

@ -3,7 +3,7 @@
* @file AutoConnectAuxBasis.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @date 2018-12-17
* @copyright MIT license.
*/
@ -20,7 +20,7 @@
#include <PageBuilder.h>
#include "AutoConnectElement.h"
#define AUTOCONENCT_JSONOBJECTTREE_MAXDEPTH 3
#define AUTOCONENCT_JSONOBJECTTREE_MAXDEPTH 3
class AutoConnect; // Reference to avoid circular
class AutoConnectAux; // Reference to avoid circular
@ -29,14 +29,13 @@ class AutoConnectAux; // Reference to avoid circular
typedef std::vector<std::reference_wrapper<AutoConnectElement>> AutoConnectElementVT;
// A type of callback function when AutoConnectAux page requested.
//typedef std::function<void(AutoConnectAux&, PageArgument&)> AuxHandleFuncT;
typedef std::function<String(AutoConnectAux&, PageArgument&)> AuxHandlerFunctionT;
// A type for the order in which callback functions are called.
typedef enum {
AC_EXIT_AHEAD = 1, /**< */
AC_EXIT_LATER = 2,
AC_EXIT_BOTH = 3
AC_EXIT_AHEAD = 1, /**< Callback before building HTML */
AC_EXIT_LATER = 2, /**< Callback after building HTML */
AC_EXIT_BOTH = 3 /**< Callback twice before and after building HTML */
} AutoConnectExitOrder_t;
/**
@ -49,37 +48,30 @@ typedef enum {
*/
class AutoConnectAux : public PageBuilder {
public:
explicit AutoConnectAux(const char* uri = nullptr, const char* title = "", const bool menu = true, const AutoConnectElementVT addons = AutoConnectElementVT()) :
_title(String(title)), _menu(menu), _addonElm(addons) { setUri(uri); _next.release(); _ac.release(); }
explicit AutoConnectAux(const String uri = String(""), const String title = String(""), const bool menu = true, const AutoConnectElementVT addons = AutoConnectElementVT()) :
_title(title), _menu(menu), _addonElm(addons) { setUri(uri.c_str()); _next.release(); _ac.release(); }
~AutoConnectAux();
void add(AutoConnectElement& addon); /**< Add an element to the auxiliary page. */
void add(AutoConnectElementVT addons); /**< Add the element set to the auxiliary page. */
void add(AutoConnectElement& addon); /**< Add an element to the auxiliary page */
void add(AutoConnectElementVT addons); /**< Add the element set to the auxiliary page */
template<typename T>
T& getElement(const char* name); /**< Get AutoConnect element */
AutoConnectElement* getElement(const char* name) { return getElement(String(name)); } /**< Get registered AutoConnectElement as specified name */
AutoConnectElement* getElement(const String name); /**< Get registered AutoConnectElement as specified name */
void menu(const bool post) { _menu = post; } /**< Set or reset the display as menu item for this aux. */
bool release(const char* name) { return release(String(name)); } /**< Release an AutoConnectElement */
bool release(const String name); /**< Release an AutoConnectElement */
AutoConnectElement& setElement(AutoConnectElement& element); /**< Set or replace the element */
bool setElementValue(const char* name, const String value) { return setElementValue(String(name), value); }
bool setElementValue(const String name, const String value);
bool setElementValue(const char* name, std::vector<String> values) { return setElementValue(String(name), values); }
bool setElementValue(const String name, std::vector<String> values);
void setTitle(const char* title) { setTitle(String(title)); } /**< Set a title of the auxiliary page. */
void setTitle(const String title) { _title = title; } /**< Set a title of the auxiliary page. */
T& getElement(const String& name);
AutoConnectElement* getElement(const String& name); /**< Get registered AutoConnectElement as specified name */
void menu(const bool post) { _menu = post; } /**< Set or reset the display as menu item for this aux */
bool release(const String& name); /**< Release an AutoConnectElement */
bool setElementValue(const String& name, const String value); /**< Set value to specified element */
bool setElementValue(const String& name, std::vector<String> values); /**< Set values collection to specified element */
void setTitle(const String title) { _title = title; } /**< Set a title of the auxiliary page */
void on(const AuxHandlerFunctionT handler, const AutoConnectExitOrder_t order = AC_EXIT_AHEAD) { _handler = handler; _order = order; } /**< Set user handler */
#ifdef AUTOCONNECT_USE_JSON
bool load(const char* in); /**< Load whole elements to AutoConnectAux Page */
bool load(const String& in); /**< Load whole elements to AutoConnectAux Page */
bool load(const __FlashStringHelper* in); /**< Load whole elements to AutoConnectAux Page */
bool load(Stream& in, const size_t bufferSize = AUTOCONNECT_JSON_BUFFER_SIZE); /**< Load whole elements to AutoConnectAux Page */
AutoConnectElement& loadElement(const String in, const String name = "*"); /**< Load specified element */
AutoConnectElement& loadElement(const __FlashStringHelper* in, const String name = "*"); /**< Load specified element */
AutoConnectElement& loadElement(Stream& in, const String name = "*", const size_t bufferSize = AUTOCONNECT_JSON_BUFFER_SIZE); /**< Load specified element */
bool load(Stream& in, const size_t bufferSize = AUTOCONNECT_JSON_BUFFER_SIZE); /**< Load whole elements to AutoConnectAux Page */
bool loadElement(const String& in, const String& name = String("")); /**< Load specified element */
bool loadElement(const __FlashStringHelper* in, const String& name = String("")); /**< Load specified element */
bool loadElement(Stream& in, const String& name = String(""), const size_t bufferSize = AUTOCONNECT_JSON_BUFFER_SIZE); /**< Load specified element */
size_t save(Stream& out); /**< Write AutoConnectAux elements to the stream */
size_t saveElement(const char* name, Stream& out) { return saveElement(String(name), out); } /**< Write an element of AutoConnectAux to the stream */
size_t saveElement(const String name, Stream& out); /**< Write an element of AutoConnectAux to the stream */
size_t saveElement(const String& name, Stream& out); /**< Write an element of AutoConnectAux to the stream */
#endif // !AUTOCONNECT_USE_JSON
protected:
@ -87,15 +79,16 @@ class AutoConnectAux : public PageBuilder {
void _join(AutoConnect& ac); /**< Make a link to AutoConnect */
PageElement* _setupPage(String uri); /**< AutoConnectAux page builder */
const String _insertElement(PageArgument& args); /**< Insert a generated HTML to the page built by PageBuilder */
const String _injectTitle(PageArgument& args) { return _title; } /**< Returns title of this page to PageBuilder */
const String _injectTitle(PageArgument& args) const { (void)(args); return _title; } /**< Returns title of this page to PageBuilder */
const String _injectMenu(PageArgument& args); /**< Inject menu title of this page to PageBuilder */
static AutoConnectElement& _nullElement(void); /**< A static returning value as invalid */
#ifdef AUTOCONNECT_USE_JSON
bool _load(JsonObject& in); /**< Load all elements from JSON object */
AutoConnectElement& _loadElement(JsonObject& in, const String name); /**< Load an element as specified name from JSON object */
bool _load(JsonObject& in); /**< Load all elements from JSON object */
bool _loadElement(JsonVariant& in, const String& name); /**< Load an element as specified name from JSON object */
AutoConnectElement& _loadElement(JsonObject& in, const String& name); /**< Load an element as specified name from JSON object */
AutoConnectElement* _createElement(const JsonObject& json); /**< Create an AutoConnectElement instance from JSON object */
static const ACElement_t _asElementType(const String type); /**< Convert a string of element type to the enumeration value */
static const ACElement_t _asElementType(const String& type); /**< Convert a string of element type to the enumeration value */
#endif // !AUTOCONNECT_USE_JSON
String _title; /**< A title of the page */

@ -819,7 +819,7 @@ String AutoConnect::_token_CSS_TABLE(PageArgument& args) {
String AutoConnect::_token_HEAD(PageArgument& args) {
AC_UNUSED(args);
return String((_ELM_HTML_HEAD));
return String(FPSTR(_ELM_HTML_HEAD));
}
String AutoConnect::_token_MENU_PRE(PageArgument& args) {

Loading…
Cancel
Save