Add optional wxXmlParseError to wxXmlDocument::Load()

If a pointer to the structure is passed in to Load(), it will be filled
in if a parsing error occurs.

Closes #24215.
This commit is contained in:
Randalphwa 2024-01-14 07:09:24 -08:00 committed by Vadim Zeitlin
parent 30b98c81b1
commit 38d8980283
3 changed files with 54 additions and 12 deletions

View file

@ -20,6 +20,7 @@
#include "wx/list.h"
#include "wx/textbuf.h"
#include "wx/versioninfo.h"
#include "wx/filefn.h"
#include <memory>
@ -222,6 +223,15 @@ enum wxXmlDocumentLoadFlag
wxXMLDOC_KEEP_WHITESPACE_NODES = 1
};
// Create an instance of this and pass it to wxXmlDocument::Load()
// to get detailed error information in case of failure.
struct wxXmlParseError
{
wxString message;
int line = 0;
int column = 0;
wxFileOffset offset = 0;
};
// This class holds XML data/document as parsed by XML parser.
@ -238,8 +248,8 @@ public:
// Parses .xml file and loads data. Returns TRUE on success, FALSE
// otherwise.
bool Load(const wxString& filename, int flags = wxXMLDOC_NONE);
bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE);
bool Load(const wxString& filename, int flags = wxXMLDOC_NONE, wxXmlParseError* err = nullptr);
bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE, wxXmlParseError* err = nullptr);
// Saves document as .xml file.
virtual bool Save(const wxString& filename, int indentstep = 2) const;

View file

@ -557,6 +557,20 @@ enum wxXmlDocumentLoadFlag
};
/**
Pass this structure to wxXmlDocument::Load() to get more information
if an error occurred during XML parsing.
@since 3.3.0
*/
struct wxXmlParseError
{
wxString message; ///< Error description
int line; ///< Line number where error occurred
int column; ///< Column number where error occurred
int byte_offset; ///< Byte offset where error occurred
};
/**
@class wxXmlDocument
@ -827,15 +841,21 @@ public:
less memory however makes impossible to recreate exactly the loaded text with a
Save() call later. Read the initial description of this class for more info.
Create an wxXmlParseError object and pass it to this function to get more
information if an error occurred during XML parsing (this parameter is
only available since wxWidgets 3.3.0).
Returns true on success, false otherwise.
*/
bool Load(const wxString& filename, int flags = wxXMLDOC_NONE);
bool Load(const wxString& filename, int flags = wxXMLDOC_NONE,
wxXmlParseError* err = nullptr);
/**
Like Load(const wxString&, int) but takes the data from given input
stream.
*/
bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE);
bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE,
wxXmlParseError* err = nullptr);
/**
Saves XML tree creating a file named with given string.

View file

@ -482,12 +482,13 @@ void wxXmlDocument::DoCopy(const wxXmlDocument& doc)
m_docNode.reset();
}
bool wxXmlDocument::Load(const wxString& filename, int flags)
bool wxXmlDocument::Load(const wxString& filename, int flags,
wxXmlParseError* err)
{
wxFileInputStream stream(filename);
if (!stream.IsOk())
return false;
return Load(stream, flags);
return Load(stream, flags, err);
}
bool wxXmlDocument::Save(const wxString& filename, int indentstep) const
@ -820,7 +821,8 @@ static int UnknownEncodingHnd(void * WXUNUSED(encodingHandlerData),
} // extern "C"
bool wxXmlDocument::Load(wxInputStream& stream, int flags)
bool wxXmlDocument::Load(wxInputStream& stream, int flags,
wxXmlParseError* err)
{
const size_t BUFSIZE = 16384;
char buf[BUFSIZE];
@ -851,12 +853,22 @@ bool wxXmlDocument::Load(wxInputStream& stream, int flags)
size_t len = stream.Read(buf, BUFSIZE).LastRead();
done = (len < BUFSIZE);
if (!XML_Parse(parser, buf, len, done))
{
if (err)
{
err->message = XML_ErrorString(XML_GetErrorCode(parser));
err->line = (int)XML_GetCurrentLineNumber(parser);
err->column = (int)XML_GetCurrentColumnNumber(parser);
err->offset = XML_GetCurrentByteIndex(parser);
}
else
{
wxString error(XML_ErrorString(XML_GetErrorCode(parser)),
*wxConvCurrent);
wxLogError(_("XML parsing error: '%s' at line %d"),
error.c_str(),
(int)XML_GetCurrentLineNumber(parser));
}
ok = false;
break;
}