Supports AutoConnectAux

pull/41/head
Hieromon Ikasamo 6 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 onNotFound KEYWORD2
release KEYWORD2 release KEYWORD2
save KEYWORD2 save KEYWORD2
saveElement KEYWORD2
setElementValue KEYWORD2 setElementValue KEYWORD2
setTitle KEYWORD2 setTitle KEYWORD2
toHTML KEYWORD2 toHTML KEYWORD2

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

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

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

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

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

Loading…
Cancel
Save