From: Maxim Mamontov Date: Thu, 8 Aug 2013 06:04:05 +0000 (+0300) Subject: Factored out user's parser. X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/a8689998a9b2cfc17dc260b423cce8ff2e407adb?ds=sidebyside Factored out user's parser. --- diff --git a/stglibs/common.lib/common.cpp b/stglibs/common.lib/common.cpp index 787b813d..c02f675c 100644 --- a/stglibs/common.lib/common.cpp +++ b/stglibs/common.lib/common.cpp @@ -819,6 +819,22 @@ std::string & Trim(std::string & val) return TrimR(TrimL(val)); } //--------------------------------------------------------------------------- +std::string ToLower(const std::string & value) +{ + std::string res; + for (std::string::size_type pos = 0; pos < value.length(); ++pos) + res += tolower(value[pos]); + return value; +} +//--------------------------------------------------------------------------- +std::string ToUpper(const std::string & value) +{ + std::string res; + for (std::string::size_type pos = 0; pos < value.length(); ++pos) + res += toupper(value[pos]); + return value; +} +//--------------------------------------------------------------------------- #ifdef WIN32 static int is_leap(unsigned y) { diff --git a/stglibs/common.lib/include/stg/common.h b/stglibs/common.lib/include/stg/common.h index eb0d14a6..6df89f73 100644 --- a/stglibs/common.lib/include/stg/common.h +++ b/stglibs/common.lib/include/stg/common.h @@ -96,6 +96,9 @@ std::string & TrimL(std::string & val); std::string & TrimR(std::string & val); std::string & Trim(std::string & val); +std::string ToLower(const std::string & value); +std::string ToUpper(const std::string & value); + std::string IconvString(const std::string & source, const std::string & from, const std::string & to); int ParseInt(const std::string & str, int * val); diff --git a/stglibs/srvconf.lib/Makefile b/stglibs/srvconf.lib/Makefile index a2b0dc4a..a2f12771 100644 --- a/stglibs/srvconf.lib/Makefile +++ b/stglibs/srvconf.lib/Makefile @@ -13,6 +13,7 @@ SRCS = netunit.cpp \ parser_auth_by.cpp \ parser_server_info.cpp \ parser_check_user.cpp \ + parser_get_user.cpp \ servconf.cpp INCS = servconf.h \ diff --git a/stglibs/srvconf.lib/include/stg/parser_get_user.h b/stglibs/srvconf.lib/include/stg/parser_get_user.h new file mode 100644 index 00000000..8fc894a4 --- /dev/null +++ b/stglibs/srvconf.lib/include/stg/parser_get_user.h @@ -0,0 +1,111 @@ +/* + * 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 : Boris Mikhailenko + * Author : Maxim Mamontov + */ + +#ifndef __STG_STGLIBS_SRVCONF_PARSER_GET_USER_H__ +#define __STG_STGLIBS_SRVCONF_PARSER_GET_USER_H__ + +#include "stg/parser.h" + +#include "stg/os_int.h" + +#include +#include + +#include + +class BASE_PROPERTY_PARSER +{ + public: + virtual bool Parse(const char ** attr) = 0; +} + +template +class PROPERTY_PARSER +{ + public: + typedef T (* FUNC)(const char **); + PROPERTY_PARSER(T & v, FUNC f) : value(v), func(f) {} + virtual void Parse(const char ** attr) { value = func(attr); } + private: + T & value; + FUNC func; +}; + +typedef std::map PROPERTY_PARSERS; + +class PARSER_GET_USER: public PARSER +{ +public: + struct STAT + { + long long su[DIR_NUM]; + long long sd[DIR_NUM]; + long long mu[DIR_NUM]; + long long md[DIR_NUM]; + double freeMb; + }; + + struct INFO + { + std::string login; + std::string password; + double cash; + double credit; + time_t creditExpire; + double lastCash; + double prepaidTraff; + int down; + int passive; + int disableDetailStat; + int connected; + int alwaysOnline; + uint32_t ip; + std::string ips; + std::string tariff; + std::string group; + std::string note; + std::string email; + std::string name; + std::string address; + std::string phone; + STAT stat; + std::string userData[USERDATA_NUM]; + }; + + typedef void (* CALLBACK)(const INFO & info, void * data); + + PARSER_GET_USER(); + virtual ~PARSER_GET_USER(); + int ParseStart(const char *el, const char **attr); + void ParseEnd(const char *el); + void SetCallback(CALLBACK f, void * data); +private: + PROPERTY_PARSERS propertyParsers; + CALLBACK callback; + void * data; + INFO info; + int depth; + + void ParseUser(const char *el, const char **attr); + void ParseUserParams(const char *el, const char **attr); +}; + +#endif diff --git a/stglibs/srvconf.lib/include/stg/servconf.h b/stglibs/srvconf.lib/include/stg/servconf.h index 69513d08..9248fb0f 100644 --- a/stglibs/srvconf.lib/include/stg/servconf.h +++ b/stglibs/srvconf.lib/include/stg/servconf.h @@ -47,48 +47,7 @@ void End(void *data, const char *el); #define MAX_ERR_STR_LEN (64) #define IP_STRING_LEN (255) - -//----------------------------------------------------------------------------- -struct STAT -{ - long long su[DIR_NUM]; - long long sd[DIR_NUM]; - long long mu[DIR_NUM]; - long long md[DIR_NUM]; - double freeMb; -}; -//----------------------------------------------------------------------------- -struct USERDATA -{ - std::string login; - std::string password; - double cash; - double credit; - time_t creditExpire; - double lastCash; - double prepaidTraff; - int down; - int passive; - int disableDetailStat; - int connected; - int alwaysOnline; - uint32_t ip; - std::string ips; - std::string tariff; - std::string iface; - std::string group; - std::string note; - std::string email; - std::string name; - std::string address; - std::string phone; - STAT stat; - std::string userData[USERDATA_NUM]; - - struct USERDATA * next; -}; //----------------------------------------------------------------------------- -typedef void(*RecvUserDataCb_t)(USERDATA * ud, void * data); typedef int(*RecvChgUserCb_t)(const char * asnwer, void * data); typedef int(*RecvSendMessageCb_t)(const char * answer, void * data); //----------------------------------------------------------------------------- @@ -131,25 +90,6 @@ private: bool error; }; //----------------------------------------------------------------------------- -class PARSER_GET_USER: public PARSER -{ -public: - PARSER_GET_USER(); - int ParseStart(const char *el, const char **attr); - void ParseEnd(const char *el); - void ParseUsers(const char *el, const char **attr); - void ParseUser(const char *el, const char **attr); - void ParseUserParams(const char *el, const char **attr); - void ParseUserLoadStat(const char * el, const char ** attr); - void SetUserDataRecvCb(RecvUserDataCb_t, void * data); -private: - RecvUserDataCb_t RecvUserDataCb; - void * userDataCb; - USERDATA user; - int depth; - bool error; -}; -//----------------------------------------------------------------------------- class PARSER_SEND_MESSAGE: public PARSER { public: @@ -180,7 +120,7 @@ public: void SetServerInfoCallback(PARSER_SERVER_INFO::CALLBACK f, void * data); void SetChgUserCb(RecvChgUserCb_t, void * data); void SetCheckUserCallback(PARSER_CHECK_USER::CALLBACK f, void * data); - void SetGetUserDataRecvCb(RecvUserDataCb_t, void * data); + void SetGetUserCallback(PARSER_GET_USER::CALLBACK f, void * data); void SetSendMessageCb(RecvSendMessageCb_t, void * data); int GetUsers(); @@ -217,14 +157,14 @@ private: XML_Parser parser; RecvUserDataCb_t RecvUserDataCb; - RecvUserDataCb_t RecvGetUserDataCb; + PARSER_GET_USER::CALLBACK getUserCallback; PARSER_AUTH_BY::CALLBACK authByCallback; PARSER_SERVER_INFO::CALLBACK serverInfoCallback; RecvChgUserCb_t RecvChgUserCb; PARSER_CHECK_USER::CALLBACK checkUserCallback; RecvSendMessageCb_t RecvSendMessageCb; - void * getUserDataDataCb; + void * getUserData; void * authByData; void * getUsersDataDataCb; void * serverInfoData; diff --git a/stglibs/srvconf.lib/parser.cpp b/stglibs/srvconf.lib/parser.cpp index bd6bb62e..f3f3278e 100644 --- a/stglibs/srvconf.lib/parser.cpp +++ b/stglibs/srvconf.lib/parser.cpp @@ -384,284 +384,6 @@ userDataCb = data; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -PARSER_GET_USER::PARSER_GET_USER() - : RecvUserDataCb(NULL), - userDataCb(NULL), - user(), - depth(0), - error(false) -{ -} -//----------------------------------------------------------------------------- -int PARSER_GET_USER::ParseStart(const char *el, const char **attr) -{ -depth++; -if (depth == 1) - { - ParseUser(el, attr); - } - -if (depth == 2) - { - ParseUserParams(el, attr); - } -return 0; -} -//----------------------------------------------------------------------------- -void PARSER_GET_USER::ParseEnd(const char *) -{ -depth--; -if (depth == 0) - { - if (RecvUserDataCb) - { - RecvUserDataCb(&user, userDataCb); - } - } -} -//----------------------------------------------------------------------------- -void PARSER_GET_USER::ParseUser(const char * el, const char ** attr) -{ -if (strcasecmp(el, "user") == 0) - { - if (strcasecmp(attr[1], "error") == 0) - user.login = ""; - return; - } -} -//----------------------------------------------------------------------------- -struct ParsedStringParams -{ -string * param; -string paramName; -}; -//----------------------------------------------------------------------------- -struct ParsedDoubleParams -{ -double * param; -string paramName; -}; -//----------------------------------------------------------------------------- -void PARSER_GET_USER::ParseUserParams(const char * el, const char ** attr) -{ -//printf("PARSER_GET_USER::ParseUserParams el=%s attr[1]=%s\n", el, attr[1]); - -if (strcasecmp(el, "login") == 0) - { - user.login = attr[1]; - } - - -/*if (strcasecmp(el, "LastActivityTime") == 0) - { - if (strtol(attr[1], user.lastActivityTime) < 0) - { - MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0); - return 0; - } - } - - -if (strcasecmp(el, "LastTimeCash") == 0) - { - if (strtol(attr[1], user.lastTimeCash) < 0) - { - MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0); - return 0; - } - } - -if (strcasecmp(el, "CashExpire") == 0) - { - if (strtol(attr[1], user.cashExpire) < 0) - { - MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0); - return 0; - } - } -*/ - -if (strcasecmp(el, "down") == 0) - { - if (str2x(attr[1], user.down) < 0) - { - return; - } - } - -if (strcasecmp(el, "passive") == 0) - { - if (str2x(attr[1], user.passive) < 0) - { - return; - } - } - -if (strcasecmp(el, "disableDetailStat") == 0) - { - if (str2x(attr[1], user.disableDetailStat) < 0) - { - return; - } - } - - -if (strcasecmp(el, "status") == 0) - { - if (str2x(attr[1], user.connected) < 0) - { - return; - } - } - -if (strcasecmp(el, "aonline") == 0) - { - if (str2x(attr[1], user.alwaysOnline) < 0) - { - return; - } - } - -if (strcasecmp(el, "currip") == 0) - { - user.ip = inet_addr(attr[1]); - } - -if (strcasecmp(el, "creditExpire") == 0) - { - if (str2x(attr[1], user.creditExpire) < 0) - { - return; - } - } - -for (int i = 0; i < USERDATA_NUM; i++) - { - string num; - x2str(i, num); - string udName = "UserData" + num; - if (strcasecmp(el, udName.c_str()) == 0) - { - Decode21str(user.userData[i], attr[1]); - return; - } - } - -ParsedStringParams psp[] = -{ - {&user.ips, "ip"}, - {&user.tariff, "tariff"}, - {&user.password, "password"}, - {&user.iface, "iface"}, -}; - -for (unsigned i = 0; i < sizeof(psp)/sizeof(ParsedStringParams); i++) - { - if (strcasecmp(el, psp[i].paramName.c_str()) == 0) - { - *psp[i].param = attr[1]; - return; - } - } - -ParsedStringParams pspEnc[] = -{ - {&user.note, "note"}, - {&user.email, "email"}, - {&user.group, "group"}, - {&user.name, "name"}, - {&user.address, "address"}, - {&user.phone, "phone"} -}; - -for (unsigned i = 0; i < sizeof(pspEnc)/sizeof(ParsedStringParams); i++) - { - if (strcasecmp(el, pspEnc[i].paramName.c_str()) == 0) - { - Decode21str(*pspEnc[i].param, attr[1]); - return; - } - } - -ParsedDoubleParams pdp[] = -{ - {&user.cash, "cash"}, - {&user.credit, "credit"}, - {&user.lastCash, "lastCash"}, - {&user.prepaidTraff, "freemb"}, -}; - -for (unsigned i = 0; i < sizeof(pdp)/sizeof(ParsedDoubleParams); i++) - { - if (strcasecmp(el, pdp[i].paramName.c_str()) == 0) - { - strtodouble2(attr[1], *pdp[i].param); - return; - } - } - -if (strcasecmp(el, "traff") == 0) - { - ParseUserLoadStat(el, attr); - return; - } -} -//----------------------------------------------------------------------------- -void PARSER_GET_USER::ParseUserLoadStat(const char *, const char ** attr) -{ -int i = 0; -char dir[6]; -while (attr[i]) - { - for (int j = 0; j < DIR_NUM; j++) - { - sprintf(dir, "MU%d", j); - if (strcasecmp(dir, attr[i]) == 0) - { - str2x(attr[i+1], user.stat.mu[j]); - break; - } - } - for (int j = 0; j < DIR_NUM; j++) - { - sprintf(dir, "MD%d", j); - if (strcasecmp(dir, attr[i]) == 0) - { - str2x(attr[i+1], user.stat.md[j]); - break; - } - } - for (int j = 0; j < DIR_NUM; j++) - { - sprintf(dir, "SU%d", j); - if (strcasecmp(dir, attr[i]) == 0) - { - str2x(attr[i+1], user.stat.su[j]); - break; - } - } - for (int j = 0; j < DIR_NUM; j++) - { - sprintf(dir, "SD%d", j); - if (strcasecmp(dir, attr[i]) == 0) - { - str2x(attr[i+1], user.stat.sd[j]); - break; - } - } - i+=2; - } -return; -} -//----------------------------------------------------------------------------- -void PARSER_GET_USER::SetUserDataRecvCb(RecvUserDataCb_t f, void * data) -{ -RecvUserDataCb = f; -userDataCb = data; -} -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- PARSER_CHG_USER::PARSER_CHG_USER() : RecvChgUserCb(NULL), chgUserCbData(NULL), diff --git a/stglibs/srvconf.lib/parser_get_user.cpp b/stglibs/srvconf.lib/parser_get_user.cpp new file mode 100644 index 00000000..cef40da2 --- /dev/null +++ b/stglibs/srvconf.lib/parser_get_user.cpp @@ -0,0 +1,193 @@ +/* + * 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 : Boris Mikhailenko + * Author : Maxim Mamontov + */ + +#include "stg/parser_get_user.h" + +#include "stg/common.h" + +namespace +{ + +bool checkValue(const char ** attr) +{ +return attr && attr[0] && attr[1] && strcasecmp(attr[0], "value") == 0; +} + +template +T getValue(const char ** attr) +{ +T value = 0; +if (checkValue(attr)) + if (str2x(attr[1], value) < 0) + return 0; +return value; +} + +template <> +std::string getValue(const char ** attr) +{ +if (checkValue(attr)) + return attr[1]; +return ""; +} + +template <> +double getValue(const char ** attr) +{ +double value = 0; +if (checkValue(attr)) + if (strtodouble2(attr[1], value) == EINVAL) + return 0; +return value; +} + +template <> +STAT getValue(const char ** attr) +{ +STAT value; +if (!attr) + return value; +std::map props; +for (size_t i = 0; i < DIR_NUM; ++i) + { + props.insert("su" + x2str(i), value.su[i]); + props.insert("sd" + x2str(i), value.sd[i]); + props.insert("mu" + x2str(i), value.mu[i]); + props.insert("md" + x2str(i), value.md[i]); + } +size_t pos = 0; +while (attr[pos]) + { + std::string name(ToLower(attr[pos++])); + std::map::iterator it(props.find(name)); + if (it != props.end()) + str2x(attr[pos++], it->second); + } +return value; +} + +std::string getEncodedValue(const char ** attr) +{ +if (checkValue(attr)) + return Decode21str(attr[1]); +return ""; +} + +template +void addParser(PROPERTY_PARSERS & parsers, const std::string & name, T & value, bool /*encoded*/) +{ + parsers.insert(ToLower(name), new PROPERTY_PARSER(value, getValue)); +} + +template <> +void addParser(PROPERTY_PARSERS & parsers, const std::string & name, std::string & value, bool encoded) +{ + if (encoded) + parsers.insert(ToLower(name), new PROPERTY_PARSER(value, getEncodedValue)); + else + parsers.insert(ToLower(name), new PROPERTY_PARSER(value, getValue)); +} + +void tryParse(PROPERTY_PARSERS & parsers, const std::string & name, const char ** attr) +{ + PROPERTY_PARSERS::iterator it(parsers.find(name)); + if (it != parsers.end()) + it->second->Parse(attr); +} + +} // namespace anonymous + +PARSER_GET_USER::PARSER_GET_USER() + : callback(NULL), + data(NULL), + depth(0) +{ + addParser(propertyParsers, "login", info.login); + addParser(propertyParsers, "password", info.password); + addParser(propertyParsers, "cash", info.cash); + addParser(propertyParsers, "credit", info.credit); + addParser(propertyParsers, "creditExpire", info.creditExpire); + addParser(propertyParsers, "lastCash", info.lastCash); + addParser(propertyParsers, "prepaidTraff", info.prepaidTraff); + addParser(propertyParsers, "down", info.down); + addParser(propertyParsers, "passive", info.passive); + addParser(propertyParsers, "disableDetailStat", info.disableDetailStat); + addParser(propertyParsers, "connected", info.connected); + addParser(propertyParsers, "alwaysOnline", info.alwaysOnline); + addParser(propertyParsers, "ip", info.ip); + addParser(propertyParsers, "ips", info.ips); + addParser(propertyParsers, "tariff", info.tariff); + addParser(propertyParsers, "group", info.group, true); + addParser(propertyParsers, "note", info.note, true); + addParser(propertyParsers, "email", info.email, true); + addParser(propertyParsers, "name", info.name, true); + addParser(propertyParsers, "address", info.address, true); + addParser(propertyParsers, "phone", info.phone, true); + addParser(propertyParsers, "traff", info.stat); + + for (size_t i = 0; i < USERDATA_NUM; ++i) + addParser(propertyParsers, "userData" + x2str(i), info.userData[i], true); +} +//----------------------------------------------------------------------------- +PARSER_GET_USER::~PARSER_GET_USER() +{ + PROPERTY_PARSERS::iterator it(propertyParsers.begin()); + while (it != propertyParsers.end()) + delete (it++)->second; +} +//----------------------------------------------------------------------------- +int PARSER_GET_USER::ParseStart(const char *el, const char **attr) +{ +depth++; +if (depth == 1) + ParseUser(el, attr); + +if (depth == 2) + ParseUserParams(el, attr); + +return 0; +} +//----------------------------------------------------------------------------- +void PARSER_GET_USER::ParseEnd(const char *) +{ +depth--; +if (depth == 0) + if (callback) + callback(info, data); +} +//----------------------------------------------------------------------------- +void PARSER_GET_USER::ParseUser(const char * el, const char ** attr) +{ +if (strcasecmp(el, "user") == 0) + if (strcasecmp(attr[1], "error") == 0) + user.login = ""; +} +//----------------------------------------------------------------------------- +void PARSER_GET_USER::ParseUserParams(const char * el, const char ** attr) +{ +tryParse(propertyParsers, ToLower(el), attr); +} +//----------------------------------------------------------------------------- +void PARSER_GET_USER::SetCallback(CALLBACK f, void * d) +{ +callback = f; +data = d; +} diff --git a/stglibs/srvconf.lib/servconf.cpp b/stglibs/srvconf.lib/servconf.cpp index 9d7e35f2..83f087b3 100644 --- a/stglibs/srvconf.lib/servconf.cpp +++ b/stglibs/srvconf.lib/servconf.cpp @@ -395,10 +395,10 @@ RecvUserDataCb = f; getUsersDataDataCb = data; } //----------------------------------------------------------------------------- -void SERVCONF::SetGetUserDataRecvCb(RecvUserDataCb_t f, void * data) +void SERVCONF::SetGetUserCallback(PARSER_GET_USER::CALLBACK f, void * data) { -RecvGetUserDataCb = f; //GET_USER -getUserDataDataCb = data; +getUserCallback = f; +getUserData = data; } //----------------------------------------------------------------------------- void SERVCONF::SetAuthByCallback(PARSER_AUTH_BY::CALLBACK f, void * data)