From: Maxim Mamontov Date: Fri, 6 Sep 2013 17:41:27 +0000 (+0300) Subject: [NY Flight] Improved XML parsing. X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/ad7b95181d5d66817aac46801cd80adbc4f2fac7 [NY Flight] Improved XML parsing. --- diff --git a/stglibs/srvconf.lib/include/stg/netunit.h b/stglibs/srvconf.lib/include/stg/netunit.h index cc5eac27..9e120855 100644 --- a/stglibs/srvconf.lib/include/stg/netunit.h +++ b/stglibs/srvconf.lib/include/stg/netunit.h @@ -29,7 +29,6 @@ #include "stg/blowfish.h" -#include #include #include @@ -49,7 +48,7 @@ #define MAX_ERR_STR_LEN (64) -typedef int(*RxCallback_t)(void *, std::list *); +typedef bool (* RxCallback_t)(void *, const std::string &, bool); enum status { @@ -87,7 +86,6 @@ public: int Connect(); int Disconnect(); - void Reset(); private: int TxHeader(); int RxHeaderAnswer(); @@ -107,7 +105,6 @@ private: std::string login; std::string password; int outerSocket; - std::list answerList; RxCallback_t RxCallBack; void * dataRxCallBack; std::string errorMsg; diff --git a/stglibs/srvconf.lib/include/stg/servconf.h b/stglibs/srvconf.lib/include/stg/servconf.h index 87a93f89..7cc18c4a 100644 --- a/stglibs/srvconf.lib/include/stg/servconf.h +++ b/stglibs/srvconf.lib/include/stg/servconf.h @@ -98,7 +98,7 @@ private: int Exec(const char * request); - friend int AnsRecv(void * data, std::list * list); + friend bool AnsRecv(void * data, const std::string & chunk, bool final); }; //----------------------------------------------------------------------------- diff --git a/stglibs/srvconf.lib/netunit.cpp b/stglibs/srvconf.lib/netunit.cpp index 670c4522..4c3cc92e 100644 --- a/stglibs/srvconf.lib/netunit.cpp +++ b/stglibs/srvconf.lib/netunit.cpp @@ -38,6 +38,13 @@ #include #include +namespace +{ + +const std::string::size_type MAX_XML_CHUNK_LENGTH = 2048; + +} + //--------------------------------------------------------------------------- #define SEND_DATA_ERROR "Send data error!" @@ -400,6 +407,7 @@ int NETTRANSACT::RxDataAnswer() BLOWFISH_CTX ctx; EnDecodeInit(password.c_str(), PASSWD_LEN, &ctx); +std::string chunk; while (true) { char bufferS[ENC_MSG_LEN]; @@ -417,22 +425,28 @@ while (true) toRead -= ret; } - char buffer[ENC_MSG_LEN + 1]; + char buffer[ENC_MSG_LEN]; DecodeString(buffer, bufferS, &ctx); - buffer[ENC_MSG_LEN] = 0; - answerList.push_back(buffer); + bool final = false; + size_t pos = 0; + for (; pos < ENC_MSG_LEN && buffer[pos] != 0; pos++); + if (pos < ENC_MSG_LEN && buffer[pos] == 0) + final = true; + + if (pos > 0) + chunk.append(&buffer[0], &buffer[pos]); - for (size_t i = 0; i < ENC_MSG_LEN; i++) + if (chunk.length() > MAX_XML_CHUNK_LENGTH || final) { - if (buffer[i] == 0) - { - if (RxCallBack) - if (st_ok != RxCallBack(dataRxCallBack, &answerList)) - return st_xml_parse_error; - return st_ok; - } + if (RxCallBack != NULL) + if (!RxCallBack(dataRxCallBack, chunk, final)) + return st_xml_parse_error; + chunk.clear(); } + + if (final) + return st_ok; } } //--------------------------------------------------------------------------- @@ -447,8 +461,3 @@ const std::string & NETTRANSACT::GetError() const return errorMsg; } //--------------------------------------------------------------------------- -void NETTRANSACT::Reset() -{ -answerList.clear(); -} -//--------------------------------------------------------------------------- diff --git a/stglibs/srvconf.lib/servconf.cpp b/stglibs/srvconf.lib/servconf.cpp index 906277c3..06a31a81 100644 --- a/stglibs/srvconf.lib/servconf.cpp +++ b/stglibs/srvconf.lib/servconf.cpp @@ -29,13 +29,13 @@ namespace { //----------------------------------------------------------------------------- -void Start(void *data, const char *el, const char **attr) +void ElementStart(void *data, const char *el, const char **attr) { SERVCONF * sc = static_cast(data); sc->Start(el, attr); } //----------------------------------------------------------------------------- -void End(void * data, const char * el) +void ElementEnd(void * data, const char * el) { SERVCONF * sc = static_cast(data); sc->End(el); @@ -43,39 +43,21 @@ sc->End(el); } // namespace anonymous -int AnsRecv(void * data, std::list * list1) +bool AnsRecv(void * data, const std::string & chunk, bool final) { SERVCONF * sc = static_cast(data); +printf("Chunk: '%s', length: %d, final: %d\n", chunk.c_str(), chunk.length(), final); -XML_ParserReset(sc->parser, NULL); -XML_SetElementHandler(sc->parser, Start, End); -XML_SetUserData(sc->parser, data); - -char ans[ENC_MSG_LEN + 1]; -int len, done = 0; - -//loop parsing -std::list::iterator node; -node = list1->begin(); - -while (node != list1->end()) +if (XML_Parse(sc->parser, chunk.c_str(), chunk.length(), final) == XML_STATUS_ERROR) { - strncpy(ans, node->c_str(), ENC_MSG_LEN); - ans[ENC_MSG_LEN] = 0; - len = strlen(ans); - - if (XML_Parse(sc->parser, ans, len, done) == XML_STATUS_ERROR) - { - strprintf(&sc->errorMsg, "XML parse error at line %d: %s", - static_cast(XML_GetCurrentLineNumber(sc->parser)), - XML_ErrorString(XML_GetErrorCode(sc->parser))); - printf("%s\n", sc->errorMsg.c_str()); - return st_xml_parse_error; - } - ++node; + strprintf(&sc->errorMsg, "XML parse error at line %d: %s", + static_cast(XML_GetCurrentLineNumber(sc->parser)), + XML_ErrorString(XML_GetErrorCode(sc->parser))); + printf("%s\n", sc->errorMsg.c_str()); + return false; } -return st_ok; +return true; } //----------------------------------------------------------------------------- @@ -203,7 +185,9 @@ return errorMsg; //----------------------------------------------------------------------------- int SERVCONF::Exec(const char * request) { -nt.Reset(); +XML_ParserReset(parser, NULL); +XML_SetElementHandler(parser, ElementStart, ElementEnd); +XML_SetUserData(parser, this); int ret = 0; if ((ret = nt.Connect()) != st_ok)