From: Maxim Mamontov Date: Sun, 20 Oct 2013 08:45:14 +0000 (+0300) Subject: Added tariff parsers/serializers. X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/6c05b2e63b58b19df2f35707fa12f238a18458e7 Added tariff parsers/serializers. --- diff --git a/stglibs/srvconf.lib/Makefile b/stglibs/srvconf.lib/Makefile index 60177a97..94f33741 100644 --- a/stglibs/srvconf.lib/Makefile +++ b/stglibs/srvconf.lib/Makefile @@ -14,6 +14,9 @@ SRCS = parsers/property.cpp \ parsers/get_admins.cpp \ parsers/get_admin.cpp \ parsers/chg_admin.cpp \ + parsers/get_tariffs.cpp \ + parsers/get_tariff.cpp \ + parsers/chg_tariff.cpp \ parsers/auth_by.cpp \ parsers/get_user.cpp \ parsers/get_users.cpp \ diff --git a/stglibs/srvconf.lib/include/stg/servconf.h b/stglibs/srvconf.lib/include/stg/servconf.h index b3bb7523..c9908640 100644 --- a/stglibs/srvconf.lib/include/stg/servconf.h +++ b/stglibs/srvconf.lib/include/stg/servconf.h @@ -36,6 +36,7 @@ struct USER_CONF_RES; struct USER_STAT_RES; +struct TARIFF_DATA_RES; namespace STG { @@ -59,6 +60,14 @@ public: SIMPLE::CALLBACK f, void * data); int DelAdmin(const std::string & login, SIMPLE::CALLBACK f, void * data); + int GetTariffs(GET_TARIFFS::CALLBACK f, void * data); + int GetTariff(const std::string & name, GET_TARIFF::CALLBACK f, void * data); + int ChgTariff(const TARIFF_DATA_RES & conf, SIMPLE::CALLBACK f, void * data); + int AddTariff(const std::string & name, + const TARIFF_DATA_RES & conf, + SIMPLE::CALLBACK f, void * data); + int DelTariff(const std::string & name, SIMPLE::CALLBACK f, void * data); + int GetUsers(GET_USERS::CALLBACK f, void * data); int GetUser(const std::string & login, GET_USER::CALLBACK f, void * data); int ChgUser(const std::string & login, diff --git a/stglibs/srvconf.lib/include/stg/servconf_types.h b/stglibs/srvconf.lib/include/stg/servconf_types.h index 86df8e95..4c0e5927 100644 --- a/stglibs/srvconf.lib/include/stg/servconf_types.h +++ b/stglibs/srvconf.lib/include/stg/servconf_types.h @@ -39,6 +39,7 @@ #define ENC_MSG_LEN (8) struct ADMIN_CONF; +struct TARIFF_DATA; namespace STG { @@ -173,6 +174,22 @@ typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & } +namespace GET_TARIFF +{ + +typedef TARIFF_DATA INFO; +typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data); + +} + +namespace GET_TARIFFS +{ + +typedef std::vector INFO; +typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data); + +} + } // namespace STG #endif diff --git a/stglibs/srvconf.lib/parsers/chg_tariff.cpp b/stglibs/srvconf.lib/parsers/chg_tariff.cpp new file mode 100644 index 00000000..c23cd0cd --- /dev/null +++ b/stglibs/srvconf.lib/parsers/chg_tariff.cpp @@ -0,0 +1,94 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#include "chg_tariff.h" + +#include "stg/tariff_conf.h" +#include "stg/common.h" + +#include + +#include + +using namespace STG; + +namespace +{ + +template +void appendResetable(std::ostream & stream, const std::string & name, const T & value) +{ +if (!value.empty()) + stream << "<" << name << " value=\"" << value.data() << "\"/>"; +} + +template +void appendSlashedResetable(std::ostream & stream, const std::string & name, const A & array, T A::value_type:: * field) +{ +std::string res; +for (typename A::size_type i = 0; i < array.size(); ++i) + { + if ((array[i].*field).empty()) // All values must be set + return; + if (!res.empty()) + res += "/"; + res += x2str((array[i].*field).data()); + } +stream << "<" << name << " value=\"" << res << "\"/>"; +} + +} // namespace anonymous + +std::string CHG_TARIFF::Serialize(const TARIFF_DATA_RES & data) +{ +std::ostringstream stream; + +appendResetable(stream, "fee", data.tariffConf.fee); +appendResetable(stream, "passiveCost", data.tariffConf.passiveCost); +appendResetable(stream, "free", data.tariffConf.free); + +if (!data.tariffConf.traffType.empty()) + switch (data.tariffConf.traffType.data()) + { + case TRAFF_UP: stream << ""; break; + case TRAFF_DOWN: stream << ""; break; + case TRAFF_UP_DOWN: stream << ""; break; + case TRAFF_MAX: stream << ""; break; + } + +for (size_t i = 0; i < DIR_NUM; ++i) + if (!data.dirPrice[i].hDay.empty() && + !data.dirPrice[i].mDay.empty() && + !data.dirPrice[i].hNight.empty() && + !data.dirPrice[i].mNight.empty()) + stream << ""; + +appendSlashedResetable(stream, "priceDayA", data.dirPrice, &DIRPRICE_DATA_RES::priceDayA); +appendSlashedResetable(stream, "priceDayB", data.dirPrice, &DIRPRICE_DATA_RES::priceDayB); +appendSlashedResetable(stream, "priceNightA", data.dirPrice, &DIRPRICE_DATA_RES::priceNightA); +appendSlashedResetable(stream, "priceNightB", data.dirPrice, &DIRPRICE_DATA_RES::priceNightB); +appendSlashedResetable(stream, "singlePrice", data.dirPrice, &DIRPRICE_DATA_RES::singlePrice); +appendSlashedResetable(stream, "noDiscount", data.dirPrice, &DIRPRICE_DATA_RES::noDiscount); + +return stream.str(); +} diff --git a/stglibs/srvconf.lib/parsers/chg_tariff.h b/stglibs/srvconf.lib/parsers/chg_tariff.h new file mode 100644 index 00000000..c5cc0f0c --- /dev/null +++ b/stglibs/srvconf.lib/parsers/chg_tariff.h @@ -0,0 +1,42 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef __STG_STGLIBS_SRVCONF_PARSER_CHG_TARIFF_H__ +#define __STG_STGLIBS_SRVCONF_PARSER_CHG_TARIFF_H__ + +#include "base.h" + +#include "stg/servconf_types.h" + +#include + +struct TARIFF_DATA_RES; + +namespace STG +{ +namespace CHG_TARIFF +{ + +std::string Serialize(const TARIFF_DATA_RES & data); + +} // namespace CHG_TARIFF +} // namespace STG + +#endif diff --git a/stglibs/srvconf.lib/parsers/get_tariff.cpp b/stglibs/srvconf.lib/parsers/get_tariff.cpp new file mode 100644 index 00000000..993f8b50 --- /dev/null +++ b/stglibs/srvconf.lib/parsers/get_tariff.cpp @@ -0,0 +1,192 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#include "get_tariff.h" + +#include "parsers/property.h" + +#include "stg/common.h" + +#include +#include + +#include + +using namespace STG; + +namespace +{ + +template +class AOS_PARSER : public BASE_PROPERTY_PARSER +{ + public: + typedef bool (* FUNC)(const char **, A &, T A::value_type:: *); + AOS_PARSER(A & a, T A::value_type:: * fld, FUNC f) : array(a), field(fld), func(f) {} + virtual bool Parse(const char ** attr) { return func(attr, array, field); } + private: + A & array; + T A::value_type:: * field; + FUNC func; +}; + +template +inline +void AddAOSParser(PROPERTY_PARSERS & parsers, const std::string & name, A & array, T A::value_type:: * field, const typename AOS_PARSER::FUNC & func) +{ + parsers.insert(std::make_pair(ToLower(name), new AOS_PARSER(array, field, func))); +} + +bool GetTimeSpan(const char ** attr, DIRPRICE_DATA & value) +{ +int hb = 0; +int mb = 0; +int he = 0; +int me = 0; +if (CheckValue(attr)) + if (ParseTariffTimeStr(attr[1], hb, mb, he, me) == 0) + { + value.hDay = hb; + value.mDay = mb; + value.hNight = he; + value.mNight = me; + return true; + } +return false; +} + +template +bool GetTraffType(const char ** attr, T & value) +{ +if (!CheckValue(attr)) + return false; +std::string type(attr[1]); +if (type == "up") + value = TRAFF_UP; +else if (type == "down") + value = TRAFF_DOWN; +else if (type == "up+down") + value = TRAFF_UP_DOWN; +else if (type == "max") + value = TRAFF_MAX; +else + return false; +return true; +} + +template +bool GetSlashedValue(const char ** attr, A & array, T A::value_type:: * field) +{ +if (!CheckValue(attr)) + return false; +const char * start = attr[1]; +size_t item = 0; +const char * pos = NULL; +while ((pos = strchr(start, '/')) && item < array.size()) + { + if (str2x(std::string(start, pos), array[item++].*field)) + return false; + start = pos + 1; + } +if (item < array.size()) + if (str2x(start, array[item].*field)) + return false; +return true; +} + +} // namespace anonymous + +GET_TARIFF::PARSER::PARSER(CALLBACK f, void * d) + : callback(f), + data(d), + depth(0), + parsingAnswer(false) +{ + AddParser(propertyParsers, "fee", info.tariffConf.fee); + AddParser(propertyParsers, "passiveCost", info.tariffConf.passiveCost); + AddParser(propertyParsers, "free", info.tariffConf.free); + AddParser(propertyParsers, "traffType", info.tariffConf.traffType, GetTraffType); + for (size_t i = 0; i < DIR_NUM; ++i) + AddParser(propertyParsers, "time" + unsigned2str(i), info.dirPrice[i], GetTimeSpan); + AddAOSParser(propertyParsers, "priceDayA", info.dirPrice, &DIRPRICE_DATA::priceDayA, GetSlashedValue); + AddAOSParser(propertyParsers, "priceDayB", info.dirPrice, &DIRPRICE_DATA::priceDayB, GetSlashedValue); + AddAOSParser(propertyParsers, "priceNightA", info.dirPrice, &DIRPRICE_DATA::priceNightA, GetSlashedValue); + AddAOSParser(propertyParsers, "priceNightB", info.dirPrice, &DIRPRICE_DATA::priceNightB, GetSlashedValue); + AddAOSParser(propertyParsers, "singlePrice", info.dirPrice, &DIRPRICE_DATA::singlePrice, GetSlashedValue); + AddAOSParser(propertyParsers, "noDiscount", info.dirPrice, &DIRPRICE_DATA::noDiscount, GetSlashedValue); +} +//----------------------------------------------------------------------------- +GET_TARIFF::PARSER::~PARSER() +{ + PROPERTY_PARSERS::iterator it(propertyParsers.begin()); + while (it != propertyParsers.end()) + delete (it++)->second; +} +//----------------------------------------------------------------------------- +int GET_TARIFF::PARSER::ParseStart(const char * el, const char ** attr) +{ +depth++; +if (depth == 1) + ParseTariff(el, attr); + +if (depth == 2 && parsingAnswer) + ParseTariffParams(el, attr); + +return 0; +} +//----------------------------------------------------------------------------- +void GET_TARIFF::PARSER::ParseEnd(const char * /*el*/) +{ +depth--; +if (depth == 0 && parsingAnswer) + { + if (callback) + callback(error.empty(), error, info, data); + error.clear(); + parsingAnswer = false; + } +} +//----------------------------------------------------------------------------- +void GET_TARIFF::PARSER::ParseTariff(const char * el, const char ** attr) +{ +if (strcasecmp(el, "tariff") == 0) + { + if (attr && attr[0] && attr[1]) + { + if (strcasecmp(attr[1], "error") == 0) + { + if (attr[2] && attr[3]) + error = attr[3]; + else + error = "Tariff not found."; + } + else + parsingAnswer = true; + } + else + parsingAnswer = true; + } +} +//----------------------------------------------------------------------------- +void GET_TARIFF::PARSER::ParseTariffParams(const char * el, const char ** attr) +{ +if (!TryParse(propertyParsers, ToLower(el), attr)) + error = "Invalid parameter."; +} diff --git a/stglibs/srvconf.lib/parsers/get_tariff.h b/stglibs/srvconf.lib/parsers/get_tariff.h new file mode 100644 index 00000000..1c03d655 --- /dev/null +++ b/stglibs/srvconf.lib/parsers/get_tariff.h @@ -0,0 +1,61 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef __STG_STGLIBS_SRVCONF_PARSER_GET_TARIFF_H__ +#define __STG_STGLIBS_SRVCONF_PARSER_GET_TARIFF_H__ + +#include "base.h" +#include "property.h" + +#include "stg/tariff_conf.h" +#include "stg/servconf_types.h" + +#include + +namespace STG +{ +namespace GET_TARIFF +{ + +class PARSER: public STG::PARSER +{ +public: + PARSER(CALLBACK f, void * data); + virtual ~PARSER(); + int ParseStart(const char * el, const char ** attr); + void ParseEnd(const char * el); + +private: + PROPERTY_PARSERS propertyParsers; + CALLBACK callback; + void * data; + INFO info; + int depth; + bool parsingAnswer; + std::string error; + + void ParseTariff(const char * el, const char ** attr); + void ParseTariffParams(const char * el, const char ** attr); +}; + +} // namespace GET_TARIFF +} // namespace STG + +#endif diff --git a/stglibs/srvconf.lib/parsers/get_tariffs.cpp b/stglibs/srvconf.lib/parsers/get_tariffs.cpp new file mode 100644 index 00000000..cff51e4c --- /dev/null +++ b/stglibs/srvconf.lib/parsers/get_tariffs.cpp @@ -0,0 +1,78 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#include "get_tariffs.h" + +#include "stg/tariff_conf.h" + +#include + +using namespace STG; + +GET_TARIFFS::PARSER::PARSER(CALLBACK f, void * d) + : callback(f), + data(d), + tariffParser(&GET_TARIFFS::PARSER::TariffCallback, this), + depth(0), + parsingAnswer(false) +{ +} +//----------------------------------------------------------------------------- +int GET_TARIFFS::PARSER::ParseStart(const char * el, const char ** attr) +{ +depth++; +if (depth == 1 && strcasecmp(el, "tariffs") == 0) + parsingAnswer = true; + +if (depth > 1 && parsingAnswer) + tariffParser.ParseStart(el, attr); + +return 0; +} +//----------------------------------------------------------------------------- +void GET_TARIFFS::PARSER::ParseEnd(const char * el) +{ +depth--; +if (depth > 0 && parsingAnswer) + tariffParser.ParseEnd(el); + +if (depth == 0 && parsingAnswer) + { + if (callback) + callback(error.empty(), error, info, data); + error.clear(); + info.clear(); + parsingAnswer = false; + } +} +//----------------------------------------------------------------------------- +void GET_TARIFFS::PARSER::AddTariff(const GET_TARIFF::INFO & tariffInfo) +{ +info.push_back(tariffInfo); +} +//----------------------------------------------------------------------------- +void GET_TARIFFS::PARSER::TariffCallback(bool result, const std::string & error, const GET_TARIFF::INFO & info, void * data) +{ + GET_TARIFFS::PARSER * parser = static_cast(data); + if (!result) + parser->SetError(error); + else + parser->AddTariff(info); +} diff --git a/stglibs/srvconf.lib/parsers/get_tariffs.h b/stglibs/srvconf.lib/parsers/get_tariffs.h new file mode 100644 index 00000000..d011f9b8 --- /dev/null +++ b/stglibs/srvconf.lib/parsers/get_tariffs.h @@ -0,0 +1,61 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef __STG_STGLIBS_SRVCONF_PARSER_GET_TARIFFS_H__ +#define __STG_STGLIBS_SRVCONF_PARSER_GET_TARIFFS_H__ + +#include "base.h" +#include "get_tariff.h" + +#include "stg/servconf_types.h" + +#include + +namespace STG +{ +namespace GET_TARIFFS +{ + +class PARSER: public STG::PARSER +{ +public: + PARSER(CALLBACK f, void * data); + int ParseStart(const char * el, const char ** attr); + void ParseEnd(const char * el); + +private: + CALLBACK callback; + void * data; + GET_TARIFF::PARSER tariffParser; + INFO info; + int depth; + bool parsingAnswer; + std::string error; + + void AddTariff(const GET_TARIFF::INFO & tariffInfo); + void SetError(const std::string & e) { error = e; } + + static void TariffCallback(bool result, const std::string& reason, const GET_TARIFF::INFO & info, void * data); +}; + +} // namespace GET_TARIFFS +} // namespace STG + +#endif diff --git a/stglibs/srvconf.lib/servconf.cpp b/stglibs/srvconf.lib/servconf.cpp index 01f21790..92773d7f 100644 --- a/stglibs/srvconf.lib/servconf.cpp +++ b/stglibs/srvconf.lib/servconf.cpp @@ -30,6 +30,10 @@ #include "parsers/get_admin.h" #include "parsers/chg_admin.h" +#include "parsers/get_tariffs.h" +#include "parsers/get_tariff.h" +#include "parsers/chg_tariff.h" + #include "parsers/auth_by.h" #include "parsers/get_users.h" #include "parsers/get_user.h" @@ -99,7 +103,7 @@ if (XML_Parse(sc->parser, chunk.c_str(), chunk.length(), final) == XML_STATUS_ER return true; } -bool SERVCONF::IMPL::SimpleRecv(void * data, const std::string & chunk, bool final) +bool SERVCONF::IMPL::SimpleRecv(void * data, const std::string & chunk, bool /*final*/) { *static_cast(data) += chunk; return true; @@ -123,6 +127,7 @@ return pImpl->Exec("", f, data); int SERVCONF::RawXML(const std::string & request, RAW_XML::CALLBACK f, void * data) { +return pImpl->RawXML(request, f, data); } // -- Admins -- @@ -157,6 +162,38 @@ int SERVCONF::DelAdmin(const std::string & login, SIMPLE::CALLBACK f, void * dat return pImpl->Exec("DelAdmin", "", f, data); } +// -- Tariffs -- + +int SERVCONF::GetTariffs(GET_TARIFFS::CALLBACK f, void * data) +{ +return pImpl->Exec("", f, data); +} + +int SERVCONF::GetTariff(const std::string & name, GET_TARIFF::CALLBACK f, void * data) +{ +return pImpl->Exec("", f, data); +} + +int SERVCONF::ChgTariff(const TARIFF_DATA_RES & tariffData, SIMPLE::CALLBACK f, void * data) +{ +return pImpl->Exec("SetTariff", "" + CHG_TARIFF::Serialize(tariffData) + "", f, data); +} + +int SERVCONF::AddTariff(const std::string & name, + const TARIFF_DATA_RES & tariffData, + SIMPLE::CALLBACK f, void * data) +{ +int res = pImpl->Exec("AddTariff", "", f, data); +if (res != st_ok) + return res; +return pImpl->Exec("SetTariff", "" + CHG_TARIFF::Serialize(tariffData) + "", f, data); +} + +int SERVCONF::DelTariff(const std::string & name, SIMPLE::CALLBACK f, void * data) +{ +return pImpl->Exec("DelTariff", "", f, data); +} + // -- Users -- int SERVCONF::GetUsers(GET_USERS::CALLBACK f, void * data) @@ -259,7 +296,7 @@ if ((ret = nt.Disconnect()) != st_ok) return st_ok; } -int SERVCONF::RawXML(const std::string & request, RAW_XML::CALLBACK f, void * data) +int SERVCONF::IMPL::RawXML(const std::string & request, RAW_XML::CALLBACK f, void * data) { std::string response; nt.SetRxCallback(&response, SimpleRecv);