From e94b06066fa4f0a9dc449e490de74fb070c4f5a0 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 22 Apr 2017 18:15:43 +0200 Subject: [PATCH] Fixed: LibXml must be initialized only once and xmlSetGenericErrorFunc set a global function (calling it for each instance of CIXml is a mistake) --HG-- branch : develop --- code/nel/include/nel/misc/i_xml.h | 17 +++++++++-- code/nel/include/nel/misc/o_xml.h | 6 +--- code/nel/src/misc/i_xml.cpp | 47 ++++++++++++++++++++++++++----- code/nel/src/misc/o_xml.cpp | 22 ++++----------- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/code/nel/include/nel/misc/i_xml.h b/code/nel/include/nel/misc/i_xml.h index f750c3265..75d4e9bde 100644 --- a/code/nel/include/nel/misc/i_xml.h +++ b/code/nel/include/nel/misc/i_xml.h @@ -110,6 +110,11 @@ public: */ bool init (IStream &stream); + /** Return the error string. + * if not empty, something wrong appends + */ + static std::string getErrorString(); + /** Release the resources used by the stream. */ void release (); @@ -172,7 +177,12 @@ public: static bool getContentString (std::string &result, xmlNodePtr node); /** - * Release meory used by libxml2, to only call before exit. + * Init all structures used by libxml2, to only call once. + */ + static void initLibXml(); + + /** + * Release memory used by libxml2, to only call before exit. */ static void releaseLibXml(); @@ -234,13 +244,16 @@ private: uint _ContentStringIndex; // Error message - std::string _ErrorString; + static std::string _ErrorString; // Try binary mode bool _TryBinaryMode; // If not NULL, binary mode detected, use this stream in serials IStream *_BinaryStream; + + // LibXml has been initialized + static bool _LibXmlIntialized; }; diff --git a/code/nel/include/nel/misc/o_xml.h b/code/nel/include/nel/misc/o_xml.h index 179534bb9..80b60149d 100644 --- a/code/nel/include/nel/misc/o_xml.h +++ b/code/nel/include/nel/misc/o_xml.h @@ -80,7 +80,6 @@ class COXml : public IStream { friend int xmlOutputWriteCallbackForNeL ( void *context, const char *buffer, int len ); friend int xmlOutputCloseCallbackForNeL ( void *context ); - friend void xmlGenericErrorFuncWrite (void *ctx, const char *msg, ...); public: /** Stream ctor @@ -100,7 +99,7 @@ public: /** Return the error string. * if not empty, something wrong appends */ - const char *getErrorString () const; + static std::string getErrorString (); /** Default dstor * @@ -178,9 +177,6 @@ private: // Current content string std::string _ContentString; - - // Error message - std::string _ErrorString; }; diff --git a/code/nel/src/misc/i_xml.cpp b/code/nel/src/misc/i_xml.cpp index e3d6f19a6..5615d81d5 100644 --- a/code/nel/src/misc/i_xml.cpp +++ b/code/nel/src/misc/i_xml.cpp @@ -39,6 +39,10 @@ namespace NLMISC const char SEPARATOR = ' '; +std::string CIXml::_ErrorString; + +bool CIXml::_LibXmlIntialized = false; + // *************************************************************************** #define readnumber(dest,digits) \ @@ -124,7 +128,7 @@ void xmlGenericErrorFuncRead (void *ctx, const char *msg, ...) // Get the error string string str; NLMISC_CONVERT_VARGS (str, msg, NLMISC::MaxCStringSize); - ((CIXml*)ctx)->_ErrorString += str; + CIXml::_ErrorString += str; } // *************************************************************************** @@ -134,7 +138,7 @@ bool CIXml::init (IStream &stream) // Release release (); - xmlInitParser(); + initLibXml(); // Default : XML mode _BinaryStream = NULL; @@ -190,12 +194,7 @@ bool CIXml::init (IStream &stream) } } - // Set error handler _ErrorString.clear(); - xmlSetGenericErrorFunc (this, xmlGenericErrorFuncRead); - - // Ask to get debug info - xmlLineNumbersDefault(1); // The parser context _Parser = xmlCreatePushParserCtxt(NULL, NULL, buffer, 4, NULL); @@ -1141,9 +1140,43 @@ bool CIXml::getContentString (std::string &result, xmlNodePtr node) // *************************************************************************** +void CIXml::initLibXml() +{ + if (_LibXmlIntialized) return; + + _ErrorString.clear(); + + // Set error handler + xmlSetGenericErrorFunc (NULL, xmlGenericErrorFuncRead); + + LIBXML_TEST_VERSION + + // an error occured during initialization + if (!_ErrorString.empty()) + { + throw EXmlParsingError (_ErrorString); + } + + // Ask to get debug info + xmlLineNumbersDefault(1); + + _LibXmlIntialized = true; +} + +// *************************************************************************** + void CIXml::releaseLibXml() { + if (!_LibXmlIntialized) return; + xmlCleanupParser(); + + _LibXmlIntialized = false; +} + +std::string CIXml::getErrorString() +{ + return _ErrorString; } } // NLMISC diff --git a/code/nel/src/misc/o_xml.cpp b/code/nel/src/misc/o_xml.cpp index 2228b24dc..5458ebf4c 100644 --- a/code/nel/src/misc/o_xml.cpp +++ b/code/nel/src/misc/o_xml.cpp @@ -17,6 +17,7 @@ #include "stdmisc.h" #include "nel/misc/o_xml.h" +#include "nel/misc/i_xml.h" #ifndef NL_DONT_USE_EXTERNAL_CODE @@ -142,27 +143,15 @@ COXml::COXml () : IStream (false /* Output mode */) // *************************************************************************** -void xmlGenericErrorFuncWrite (void *ctx, const char *msg, ...) -{ - // Get the error string - string str; - NLMISC_CONVERT_VARGS (str, msg, NLMISC::MaxCStringSize); - ((COXml*)ctx)->_ErrorString += str; -} - -// *************************************************************************** - bool COXml::init (IStream *stream, const std::string &version) { resetPtrTable(); + CIXml::initLibXml(); + // Output stream ? if (!stream->isReading()) { - // Set error handler - _ErrorString.clear(); - xmlSetGenericErrorFunc (this, xmlGenericErrorFuncWrite); - // Set XML mode setXMLMode (true); @@ -673,9 +662,10 @@ bool COXml::isStringValidForProperties (const std::string &str) // *************************************************************************** -const char *COXml::getErrorString () const +std::string COXml::getErrorString() { - return _ErrorString.c_str (); + // error string is managed by CIXml + return CIXml::getErrorString(); } } // NLMISC