]> git.stg.codes - stg.git/commitdiff
[NY Flight] Improved XML parsing.
authorMaxim Mamontov <faust.madf@gmail.com>
Fri, 6 Sep 2013 17:41:27 +0000 (20:41 +0300)
committerMaxim Mamontov <faust.madf@gmail.com>
Fri, 6 Sep 2013 17:41:27 +0000 (20:41 +0300)
stglibs/srvconf.lib/include/stg/netunit.h
stglibs/srvconf.lib/include/stg/servconf.h
stglibs/srvconf.lib/netunit.cpp
stglibs/srvconf.lib/servconf.cpp

index cc5eac273d16ce86e53fb1c3e57c85792f3d5240..9e120855ea5e788cd89f9f896d3dc02cdaaedc1f 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "stg/blowfish.h"
 
-#include <list>
 #include <string>
 
 #include <sys/types.h>
@@ -49,7 +48,7 @@
 
 #define MAX_ERR_STR_LEN (64)
 
-typedef int(*RxCallback_t)(void *, std::list<std::string> *);
+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<std::string>   answerList;
     RxCallback_t RxCallBack;
     void *  dataRxCallBack;
     std::string errorMsg;
index 87a93f89b1abcd518d9d598f86dd39779c535395..7cc18c4a7fd16c78bfef5c71f6891b0fa0295cd6 100644 (file)
@@ -98,7 +98,7 @@ private:
 
     int Exec(const char * request);
 
-    friend int AnsRecv(void * data, std::list<std::string> * list);
+    friend bool AnsRecv(void * data, const std::string & chunk, bool final);
 };
 //-----------------------------------------------------------------------------
 
index 670c452242a00d565b57c5a3636a7ec813224c81..4c3cc92ed8bf7626b1f25e40b46e2d1c161317ab 100644 (file)
 #include <arpa/inet.h>
 #include <unistd.h>
 
+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();
-}
-//---------------------------------------------------------------------------
index 906277c3afcc3fed33e2860735ea08c2f3ef9d47..06a31a81801e4f3733b694594f96d534c1e58ae3 100644 (file)
@@ -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<SERVCONF *>(data);
 sc->Start(el, attr);
 }
 //-----------------------------------------------------------------------------
-void End(void * data, const char * el)
+void ElementEnd(void * data, const char * el)
 {
 SERVCONF * sc = static_cast<SERVCONF *>(data);
 sc->End(el);
@@ -43,39 +43,21 @@ sc->End(el);
 
 } // namespace anonymous
 
-int AnsRecv(void * data, std::list<std::string> * list1)
+bool AnsRecv(void * data, const std::string & chunk, bool final)
 {
 SERVCONF * sc = static_cast<SERVCONF *>(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<std::string>::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<int>(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<int>(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)