X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a6cf6bcfb46c8ba3ef5d8daef8ff1e60caaf41ac..90fae9d2cfd82625c8c8279660237514470bc31a:/src/xml/xml.cpp diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index 1917c27ba8..922332b1d6 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -30,6 +30,7 @@ #include "wx/zstream.h" #include "wx/strconv.h" #include "wx/scopedptr.h" +#include "wx/versioninfo.h" #include "expat.h" // from Expat @@ -54,7 +55,8 @@ wxXmlNode::wxXmlNode(wxXmlNode *parent,wxXmlNodeType type, : m_type(type), m_name(name), m_content(content), m_attrs(attrs), m_parent(parent), m_children(NULL), m_next(next), - m_lineNo(lineNo) + m_lineNo(lineNo), + m_noConversion(false) { if (m_parent) { @@ -74,7 +76,7 @@ wxXmlNode::wxXmlNode(wxXmlNodeType type, const wxString& name, : m_type(type), m_name(name), m_content(content), m_attrs(NULL), m_parent(NULL), m_children(NULL), m_next(NULL), - m_lineNo(lineNo) + m_lineNo(lineNo), m_noConversion(false) {} wxXmlNode::wxXmlNode(const wxXmlNode& node) @@ -115,6 +117,7 @@ void wxXmlNode::DoCopy(const wxXmlNode& node) m_name = node.m_name; m_content = node.m_content; m_lineNo = node.m_lineNo; + m_noConversion = node.m_noConversion; m_children = NULL; wxXmlNode *n = node.m_children; @@ -744,7 +747,7 @@ bool wxXmlDocument::Load(wxInputStream& stream, const wxString& encoding, int fl *wxConvCurrent); wxLogError(_("XML parsing error: '%s' at line %d"), error.c_str(), - XML_GetCurrentLineNumber(parser)); + (int)XML_GetCurrentLineNumber(parser)); ok = false; break; } @@ -821,62 +824,69 @@ bool OutputString(wxOutputStream& stream, return stream.IsOk(); } -// flags for OutputStringEnt() -enum +enum EscapingMode { - XML_ESCAPE_QUOTES = 1 + Escape_Text, + Escape_Attribute }; // Same as above, but create entities first. -// Translates '<' to "<", '>' to ">" and '&' to "&" -bool OutputStringEnt(wxOutputStream& stream, - const wxString& str, - wxMBConv *convMem, - wxMBConv *convFile, - int flags = 0) -{ - const size_t len = str.length(); - size_t i, - last = 0; - for (i = 0; i < len; i++) - { - wxChar c = str.GetChar(i); - if (c == wxS('<') || c == wxS('>') || - (c == wxS('&') && str.substr(i+1, 4) != wxS("amp;")) || - ((flags & XML_ESCAPE_QUOTES) && c == wxS('"'))) - { - if ( !OutputString(stream, str.substr(last, i - last), - convMem, convFile) ) - return false; +// Translates '<' to "<", '>' to ">" and so on, according to the spec: +// http://www.w3.org/TR/2000/WD-xml-c14n-20000119.html#charescaping +bool OutputEscapedString(wxOutputStream& stream, + const wxString& str, + wxMBConv *convMem, + wxMBConv *convFile, + EscapingMode mode) +{ + wxString escaped; + escaped.reserve(str.length()); - const char *escaped; - switch ( c ) - { - case wxS('<'): - escaped = "<"; - break; - case wxS('>'): - escaped = ">"; - break; - case wxS('&'): - escaped = "&"; - break; - case wxS('"'): - escaped = """; - break; - default: - wxFAIL_MSG( "logic error in the code" ); - return false; - } + for ( wxString::const_iterator i = str.begin(); i != str.end(); ++i ) + { + const wxChar c = *i; - if ( !OutputString(stream, escaped, convMem, convFile) ) - return false; + switch ( c ) + { + case wxS('<'): + escaped.append(wxS("<")); + break; + case wxS('>'): + escaped.append(wxS(">")); + break; + case wxS('&'): + escaped.append(wxS("&")); + break; + case wxS('\r'): + escaped.append(wxS(" ")); + break; + default: + if ( mode == Escape_Attribute ) + { + switch ( c ) + { + case wxS('"'): + escaped.append(wxS(""")); + break; + case wxS('\t'): + escaped.append(wxS(" ")); + break; + case wxS('\n'): + escaped.append(wxS(" ")); + break; + default: + escaped.append(c); + } - last = i + 1; + } + else + { + escaped.append(c); + } } } - return OutputString(stream, str.substr(last, i - last), convMem, convFile); + return OutputString(stream, escaped, convMem, convFile); } bool OutputIndentation(wxOutputStream& stream, @@ -885,7 +895,7 @@ bool OutputIndentation(wxOutputStream& stream, wxMBConv *convFile) { wxString str(wxS("\n")); - str += wxString(2*indent, wxS(' ')); + str += wxString(indent, wxS(' ')); return OutputString(stream, str, convMem, convFile); } @@ -906,7 +916,15 @@ bool OutputNode(wxOutputStream& stream, break; case wxXML_TEXT_NODE: - rc = OutputStringEnt(stream, node->GetContent(), convMem, convFile); + if (node->GetNoConversion()) + { + stream.Write(node->GetContent().c_str(), node->GetContent().Length()); + rc = true; + } + else + rc = OutputEscapedString(stream, node->GetContent(), + convMem, convFile, + Escape_Text); break; case wxXML_ELEMENT_NODE: @@ -922,9 +940,9 @@ bool OutputNode(wxOutputStream& stream, rc = OutputString(stream, wxS(" ") + attr->GetName() + wxS("=\""), convMem, convFile) && - OutputStringEnt(stream, attr->GetValue(), - convMem, convFile, - XML_ESCAPE_QUOTES) && + OutputEscapedString(stream, attr->GetValue(), + convMem, convFile, + Escape_Attribute) && OutputString(stream, wxS("\""), convMem, convFile); } } @@ -1018,4 +1036,12 @@ bool wxXmlDocument::Save(wxOutputStream& stream, int indentstep) const OutputString(stream, wxS("\n"), convMem.get(), convFile.get()); } +/*static*/ wxVersionInfo wxXmlDocument::GetLibraryVersionInfo() +{ + return wxVersionInfo("expat", + XML_MAJOR_VERSION, + XML_MINOR_VERSION, + XML_MICRO_VERSION); +} + #endif // wxUSE_XML