/** * Implementation of template functions of AutoConnect and AutoConnectAux. * This implementation instantiates completely the void AutoConnectElement * as each type and also absorbs interface differences due to ArduinoJson * version differences. * @file AutoConnectAuxImpl.h * @author hieromon@gmail.com * @version 0.9.8 * @date 2019-03-21 * @copyright MIT license. */ #ifndef _AUTOCONNECTAUXIMPL_H_ #define _AUTOCONNECTAUXIMPL_H_ #include "AutoConnectDefs.h" #ifndef AUTOCONNECT_USE_JSON /** * Get AutoConnectElementBasis element. * @param name an element name. * @return A reference of AutoConnectElement class. */ template<> AutoConnectElementBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { return *(reinterpret_cast(elm)); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectButtonBasis element. * @param name An element name. * @return A reference of AutoConnectButton class. */ template<> AutoConnectButtonBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Button) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectCheckboxBasis element. * @param name An element name. * @return A reference of AutoConnectCheckbox class. */ template<> AutoConnectCheckboxBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Checkbox) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectFileBasis element. * @param name An element name. * @return A reference of AutoConnectFile class. */ template<> AutoConnectFileBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_File) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectInputBasis element. * @param name An element name. * @return A reference of AutoConnectInput class. */ template<> AutoConnectInputBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Input) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectRadioBasis element. * @param name An element name. * @return A reference of AutoConnectRadio class. */ template<> AutoConnectRadioBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Radio) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectSelectBasis element. * @param name An element name. * @return A reference of AutoConnectSelect class. */ template<> AutoConnectSelectBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Select) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectSubmitBasis element. * @param name An element name. * @return A reference of AutoConnectSubmit class. */ template<> AutoConnectSubmitBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Submit) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectTextBasis element. * @param name An element name. * @return A reference of AutoConnectText class. */ template<> AutoConnectTextBasis& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Text) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } #else /** * Parse and load a JSON document which marks up multiple custom web * pages. The compiler instantiates this template according to the stored * data type that contains the JSON document. * This template also generates different parsing function calls * depending on the ArduinoJson version. * @param T An object type of the JSON document which must be a * passable object to ArduinoJson. * @param in An instance of a source JSON document to load. */ template bool AutoConnect::_parseJson(T in) { ArduinoJsonBuffer jsonBuffer(AUTOCONNECT_JSONBUFFER_PRIMITIVE_SIZE); JsonVariant jv; #if ARDUINOJSON_VERSION_MAJOR<=5 jv = jsonBuffer.parse(in); if (!jv.success()) { AC_DBG("JSON parse error\n"); return false; } #else DeserializationError err = deserializeJson(jsonBuffer, in); if (err) { AC_DBG("Deserialize error:%s\n", err.c_str()); return false; } jv = jsonBuffer.as(); #endif return _load(jv); } /** * Parse and load a JSON document which marks up a custom web page. * The compiler instantiates this template according to the stored data * type that contains the JSON document. * This template also generates different parsing function calls * depending on the ArduinoJson version. * @param T An object type of the JSON document which must be a * passable object to ArduinoJson. * @param in An instance of a source JSON document to load. */ template bool AutoConnectAux::_parseJson(T in) { ArduinoJsonBuffer jsonBuffer(AUTOCONNECT_JSONBUFFER_PRIMITIVE_SIZE); #if ARDUINOJSON_VERSION_MAJOR<=5 JsonObject& jb = jsonBuffer.parseObject(in); if (!jb.success()) { AC_DBG("JSON parse error\n"); return false; } #else DeserializationError err = deserializeJson(jsonBuffer, in); if (err) { AC_DBG("Deserialize:%s\n", err.c_str()); return false; } JsonObject jb = jsonBuffer.as(); #endif return _load(jb); } /** * Parse and load a JSON document which declares one of the AutoConnectElement. * The compiler instantiates this template according to the stored data * type that contains the JSON document. * This template also generates different parsing function calls * depending on the ArduinoJson version. * @param T An object type of the JSON document which must be a * passable object to ArduinoJson. * @param in An instance of a source JSON document to load. */ template bool AutoConnectAux::_parseElement(T in, const String& name) { ArduinoJsonBuffer jsonBuffer(AUTOCONNECT_JSONBUFFER_PRIMITIVE_SIZE); JsonVariant jb; #if ARDUINOJSON_VERSION_MAJOR<=5 jb = jsonBuffer.parse(in); if (!jb.success()) { AC_DBG("JSON parse error\n"); return false; } #else DeserializationError err = deserializeJson(jsonBuffer, in); if (err) { AC_DBG("Deserialize:%s\n", err.c_str()); return false; } jb = jsonBuffer.as(); #endif return _loadElement(jb, name); } /** * Get AutoConnectElementJson element. * @param name an element name. * @return A reference of AutoConnectElement class. */ template<> AutoConnectElementJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { return *(reinterpret_cast(elm)); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectButtonJson element. * @param name An element name. * @return A reference of AutoConnectButton class. */ template<> AutoConnectButtonJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Button) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectCheckboxJson element. * @param name An element name. * @return A reference of AutoConnectCheckbox class. */ template<> AutoConnectCheckboxJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Checkbox) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectFile element. * @param name An element name. * @return A reference of AutoConnectFile class. */ template<> AutoConnectFileJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_File) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectInputJson element. * @param name An element name. * @return A reference of AutoConnectInput class. */ template<> AutoConnectInputJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Input) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectRadioJson element. * @param name An element name. * @return A reference of AutoConnectRadio class. */ template<> AutoConnectRadioJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Radio) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectSelectJson element. * @param name An element name. * @return A reference of AutoConnectSelect class. */ template<> AutoConnectSelectJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Select) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectSubmitJson element. * @param name An element name. * @return A reference of AutoConnectSubmit class. */ template<> AutoConnectSubmitJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Submit) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } /** * Get AutoConnectTextJson element. * @param name An element name. * @return A reference of AutoConnectText class. */ template<> AutoConnectTextJson& AutoConnectAux::getElement(const String& name) { AutoConnectElement* elm = getElement(name); if (elm) { if (elm->typeOf() == AC_Text) return *(reinterpret_cast(elm)); else AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); } return reinterpret_cast(_nullElement()); } #endif // !AUTOCONNECT_USE_JSON #endif // !_AUTOCONNECTAUXIMPL_H_