#include "wx/xml/xmlio.h"
#include <libxml/parser.h>
+#include <libxml/SAX.h>
+
+
+// wxWindows SAX handlers for bugs reporting:
+
+static void wxXmlParserError(void *ctx, const char *msg, ...)
+{
+ wxString text;
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ if (ctxt->input)
+ text.Printf( _("XML parser error at line %d: "), ctxt->input->line );
+ va_list args;
+ wxString tmp;
+ va_start(args, msg);
+ tmp.PrintfV( msg, args );
+ va_end(args);
+ text += tmp;
+ wxLogError( text.c_str() );
+}
+
+static void wxXmlParserWarning(void *ctx, const char *msg, ...)
+{
+ wxString text;
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ if (ctxt->input)
+ text.Printf( _("XML parser warning at line %d: "), ctxt->input->line );
+ va_list args;
+ wxString tmp;
+ va_start(args, msg);
+ tmp.PrintfV( msg, args );
+ va_end(args);
+ text += tmp;
+ wxLogWarning( text.c_str() );
+}
+
+static xmlSAXHandler gs_wxXmlSAXHandler;
+
+
// dynamically loaded functions from libxml:
typedef xmlParserCtxtPtr (*type_xmlCreatePushParserCtxt)
typedef xmlChar * (*type_xmlNodeListGetString)(xmlDocPtr, xmlNodePtr, int);
typedef xmlNodePtr (*type_xmlDocGetRootElement)(xmlDocPtr);
typedef xmlNodePtr (*type_xmlDocSetRootElement)(xmlDocPtr doc, xmlNodePtr root);
+typedef void (*(*type_xmlFree))(void *);
+typedef int (*type_xmlKeepBlanksDefault)(int);
+typedef void (*type_xmlInitParser)(void);
+typedef void (*type_xmlCleanupParser)(void);
+typedef xmlSAXHandler *type_xmlDefaultSAXHandler;
static struct
{
type_xmlNodeListGetString xmlNodeListGetString;
type_xmlDocGetRootElement xmlDocGetRootElement;
type_xmlDocSetRootElement xmlDocSetRootElement;
+ type_xmlFree xmlFree;
+ type_xmlKeepBlanksDefault xmlKeepBlanksDefault;
+ type_xmlInitParser xmlInitParser;
+ type_xmlCleanupParser xmlCleanupParser;
+ type_xmlDefaultSAXHandler xmlDefaultSAXHandler;
} gs_libxmlDLL;
static bool gs_libxmlLoaded = FALSE;
{
if (gs_libxmlLoaded)
{
- wxLogDebug("Releasing libxml.so.2");
+ gs_libxmlDLL.xmlCleanupParser();
wxDllLoader::UnloadLibrary(gs_libxmlDLL.Handle);
}
gs_libxmlLoaded = FALSE;
if (gs_libxmlLoadFailed) return FALSE;
gs_libxmlLoadFailed = TRUE;
- wxLogDebug("Loading libxml.so.2...");
+ {
+ wxLogNull lg;
#ifdef __UNIX__
gs_libxmlDLL.Handle =
+ wxDllLoader::LoadLibrary(_T("wxlibxml.so.2"), &gs_libxmlLoaded);
+ if (!gs_libxmlLoaded) gs_libxmlDLL.Handle =
wxDllLoader::LoadLibrary(_T("libxml.so.2"), &gs_libxmlLoaded);
#endif
+#ifdef __WXMSW__
+ gs_libxmlDLL.Handle =
+ wxDllLoader::LoadLibrary(_T("wxlibxml2.dll"), &gs_libxmlLoaded);
+ if (!gs_libxmlLoaded) gs_libxmlDLL.Handle =
+ wxDllLoader::LoadLibrary(_T("libxml2.dll"), &gs_libxmlLoaded);
+#endif
+ }
- if (!gs_libxmlLoaded) return FALSE;
+ if (!gs_libxmlLoaded)
+ {
+ wxLogError(_("Failed to load libxml shared library."));
+ return FALSE;
+ }
#define LOAD_SYMBOL(sym) \
gs_libxmlDLL.sym = \
(type_##sym)wxDllLoader::GetSymbol(gs_libxmlDLL.Handle, _T(#sym)); \
- if (!gs_libxmlDLL.sym) { ReleaseLibxml(); return FALSE; }
+ if (!gs_libxmlDLL.sym) \
+ { \
+ ReleaseLibxml(); \
+ wxLogError(_("Failed to load libxml shared library.")); \
+ return FALSE; \
+ }
LOAD_SYMBOL(xmlCreatePushParserCtxt)
LOAD_SYMBOL(xmlNewText)
LOAD_SYMBOL(xmlNodeListGetString)
LOAD_SYMBOL(xmlDocGetRootElement)
LOAD_SYMBOL(xmlDocSetRootElement)
+ LOAD_SYMBOL(xmlFree)
+ LOAD_SYMBOL(xmlKeepBlanksDefault)
+ LOAD_SYMBOL(xmlInitParser)
+ LOAD_SYMBOL(xmlCleanupParser)
+ LOAD_SYMBOL(xmlDefaultSAXHandler)
#undef LOAD_SYMBOL
gs_libxmlLoadFailed = FALSE;
+
+ gs_libxmlDLL.xmlInitParser();
+ memcpy(&gs_wxXmlSAXHandler, gs_libxmlDLL.xmlDefaultSAXHandler,
+ sizeof(xmlSAXHandler));
+ gs_wxXmlSAXHandler.error = wxXmlParserError;
+ gs_wxXmlSAXHandler.fatalError = wxXmlParserError;
+ gs_wxXmlSAXHandler.warning = wxXmlParserWarning;
- wxLogDebug("...succeed");
return TRUE;
}
gs_libxmlDLL.xmlNodeListGetString(doc, attr->children, 1);
wxXmlProperty *prop =
new wxXmlProperty(attr->name, val, CreateWXProperty(doc, attr->next));
- free(val);
+ (*gs_libxmlDLL.xmlFree)(val);
return prop;
}
if (res > 0)
{
bool okay = TRUE;
- ctxt = gs_libxmlDLL.xmlCreatePushParserCtxt(NULL, NULL,
- buffer, res, ""/*docname*/);
+ gs_libxmlDLL.xmlKeepBlanksDefault(0);
+ ctxt = gs_libxmlDLL.xmlCreatePushParserCtxt(&gs_wxXmlSAXHandler,
+ NULL, buffer, res, ""/*docname*/);
while ((res = stream.Read(buffer, 1024).LastRead()) > 0)
if (gs_libxmlDLL.xmlParseChunk(ctxt, buffer, res, 0) != 0)
okay = FALSE;
wxASSERT_MSG(doc.GetRoot() != NULL, _("Trying to save empty document!"));
+ gs_libxmlDLL.xmlKeepBlanksDefault(0);
dc = gs_libxmlDLL.xmlNewDoc((xmlChar*)doc.GetVersion().mb_str());
gs_libxmlDLL.xmlDocSetRootElement(dc,
gs_libxmlDLL.xmlDocDumpMemory(dc, &buffer, &size);
gs_libxmlDLL.xmlFreeDoc(dc);
stream.Write(buffer, size);
- free(buffer);
+ (*gs_libxmlDLL.xmlFree)(buffer);
return stream.LastWrite() == (unsigned)size;
}