X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/759f72726133ce3bdbe1c3a2f444aa816c7f46c9..f2c88494b6978bee502f4c856ba9dc7e3b7c3954:/src/xml/xml.cpp diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index 1df50a7f8a..990d6aa81f 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: xml.cpp +// Name: src/xml/xml.cpp // Purpose: wxXmlDocument - XML parser & data holder class // Author: Vaclav Slavik // Created: 2000/03/05 @@ -8,10 +8,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "xml.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -19,23 +15,31 @@ #pragma hdrstop #endif +#if wxUSE_XML + #include "wx/xml/xml.h" -#if wxUSE_XML +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/app.h" +#endif #include "wx/wfstream.h" #include "wx/datstrm.h" #include "wx/zstream.h" -#include "wx/log.h" -#include "wx/intl.h" #include "wx/strconv.h" #include "expat.h" // from Expat // DLL options compatibility check: -#include "wx/app.h" WX_CHECK_BUILD_OPTIONS("wxXML") + +IMPLEMENT_CLASS(wxXmlDocument, wxObject) + + + //----------------------------------------------------------------------------- // wxXmlNode //----------------------------------------------------------------------------- @@ -272,6 +276,20 @@ bool wxXmlNode::DeleteProperty(const wxString& name) } } +wxString wxXmlNode::GetNodeContent() const +{ + wxXmlNode *n = GetChildren(); + + while (n) + { + if (n->GetType() == wxXML_TEXT_NODE || + n->GetType() == wxXML_CDATA_SECTION_NODE) + return n->GetContent(); + n = n->GetNext(); + } + return wxEmptyString; +} + //----------------------------------------------------------------------------- @@ -330,12 +348,16 @@ void wxXmlDocument::DoCopy(const wxXmlDocument& doc) bool wxXmlDocument::Load(const wxString& filename, const wxString& encoding) { wxFileInputStream stream(filename); + if (!stream.Ok()) + return false; return Load(stream, encoding); } bool wxXmlDocument::Save(const wxString& filename) const { wxFileOutputStream stream(filename); + if (!stream.Ok()) + return false; return Save(stream); } @@ -350,29 +372,30 @@ bool wxXmlDocument::Save(const wxString& filename) const - process all elements, including CDATA */ -// converts Expat-produced string in UTF-8 into wxString. -inline static wxString CharToString(wxMBConv *conv, +// converts Expat-produced string in UTF-8 into wxString using the specified +// conv or keep in UTF-8 if conv is NULL +static wxString CharToString(wxMBConv *conv, const char *s, size_t len = wxSTRING_MAXLEN) { #if wxUSE_UNICODE - (void)conv; + wxUnusedVar(conv); + return wxString(s, wxConvUTF8, len); -#else +#else // !wxUSE_UNICODE if ( conv ) { - size_t nLen = (len != wxSTRING_MAXLEN) ? len : - wxConvUTF8.MB2WC((wchar_t*) NULL, s, 0); + // there can be no embedded NULs in this string so we don't need the + // output length, it will be NUL-terminated + const wxWCharBuffer wbuf( + wxConvUTF8.cMB2WC(s, len == wxSTRING_MAXLEN ? wxNO_LEN : len, NULL)); - wchar_t *buf = new wchar_t[nLen+1]; - wxConvUTF8.MB2WC(buf, s, nLen); - buf[nLen] = 0; - wxString str(buf, *conv, len); - delete[] buf; - return str; + return wxString(wbuf, *conv); } - else + else // already in UTF-8, no conversion needed + { return wxString(s, len != wxSTRING_MAXLEN ? len : strlen(s)); -#endif + } +#endif // wxUSE_UNICODE/!wxUSE_UNICODE } struct wxXmlParsingContext @@ -598,33 +621,42 @@ bool wxXmlDocument::Load(wxInputStream& stream, const wxString& encoding) // write string to output: inline static void OutputString(wxOutputStream& stream, const wxString& str, -#if wxUSE_UNICODE - wxMBConv * WXUNUSED(convMem), -#else - wxMBConv *convMem, -#endif - wxMBConv *convFile) + wxMBConv *convMem = NULL, + wxMBConv *convFile = NULL) { - if (str.empty()) return; + if (str.empty()) + return; + #if wxUSE_UNICODE + wxUnusedVar(convMem); + const wxWX2MBbuf buf(str.mb_str(*(convFile ? convFile : &wxConvUTF8))); stream.Write((const char*)buf, strlen((const char*)buf)); -#else - if ( convFile == NULL ) - stream.Write(str.mb_str(), str.Len()); - else +#else // !wxUSE_UNICODE + if ( convFile && convMem ) { wxString str2(str.wc_str(*convMem), *convFile); stream.Write(str2.mb_str(), str2.Len()); } -#endif + else // no conversions to do + { + stream.Write(str.mb_str(), str.Len()); + } +#endif // wxUSE_UNICODE/!wxUSE_UNICODE } +// flags for OutputStringEnt() +enum +{ + XML_ESCAPE_QUOTES = 1 +}; + // Same as above, but create entities first. // Translates '<' to "<", '>' to ">" and '&' to "&" static void OutputStringEnt(wxOutputStream& stream, const wxString& str, - wxMBConv *convMem, wxMBConv *convFile, - bool escapeQuotes = false) + wxMBConv *convMem = NULL, + wxMBConv *convFile = NULL, + int flags = 0) { wxString buf; size_t i, last, len; @@ -637,24 +669,25 @@ static void OutputStringEnt(wxOutputStream& stream, const wxString& str, c = str.GetChar(i); if (c == wxT('<') || c == wxT('>') || (c == wxT('&') && str.Mid(i+1, 4) != wxT("amp;")) || - (escapeQuotes && c == wxT('"'))) + ((flags & XML_ESCAPE_QUOTES) && c == wxT('"'))) { OutputString(stream, str.Mid(last, i - last), convMem, convFile); switch (c) { case wxT('<'): - OutputString(stream, wxT("<"), NULL, NULL); + OutputString(stream, wxT("<")); break; case wxT('>'): - OutputString(stream, wxT(">"), NULL, NULL); + OutputString(stream, wxT(">")); break; case wxT('&'): - OutputString(stream, wxT("&"), NULL, NULL); + OutputString(stream, wxT("&")); break; case wxT('"'): - OutputString(stream, wxT("""), NULL, NULL); + OutputString(stream, wxT(""")); + break; + default: break; - default: break; } last = i + 1; } @@ -667,7 +700,7 @@ inline static void OutputIndentation(wxOutputStream& stream, int indent) wxString str = wxT("\n"); for (int i = 0; i < indent; i++) str << wxT(' ') << wxT(' '); - OutputString(stream, str, NULL, NULL); + OutputString(stream, str); } static void OutputNode(wxOutputStream& stream, wxXmlNode *node, int indent, @@ -683,23 +716,22 @@ static void OutputNode(wxOutputStream& stream, wxXmlNode *node, int indent, break; case wxXML_ELEMENT_NODE: - OutputString(stream, wxT("<"), NULL, NULL); - OutputString(stream, node->GetName(), NULL, NULL); + OutputString(stream, wxT("<")); + OutputString(stream, node->GetName()); prop = node->GetProperties(); while (prop) { - OutputString(stream, wxT(" ") + prop->GetName() + wxT("=\""), - NULL, NULL); - OutputStringEnt(stream, prop->GetValue(), NULL, NULL, - true/*escapeQuotes*/); - OutputString(stream, wxT("\""), NULL, NULL); + OutputString(stream, wxT(" ") + prop->GetName() + wxT("=\"")); + OutputStringEnt(stream, prop->GetValue(), convMem, convFile, + XML_ESCAPE_QUOTES); + OutputString(stream, wxT("\"")); prop = prop->GetNext(); } if (node->GetChildren()) { - OutputString(stream, wxT(">"), NULL, NULL); + OutputString(stream, wxT(">")); prev = NULL; n = node->GetChildren(); while (n) @@ -712,18 +744,18 @@ static void OutputNode(wxOutputStream& stream, wxXmlNode *node, int indent, } if (prev && prev->GetType() != wxXML_TEXT_NODE) OutputIndentation(stream, indent); - OutputString(stream, wxT("GetName(), NULL, NULL); - OutputString(stream, wxT(">"), NULL, NULL); + OutputString(stream, wxT("GetName()); + OutputString(stream, wxT(">")); } else - OutputString(stream, wxT("/>"), NULL, NULL); + OutputString(stream, wxT("/>")); break; case wxXML_COMMENT_NODE: - OutputString(stream, wxT(""), NULL, NULL); + OutputString(stream, wxT("-->")); break; default: @@ -753,10 +785,10 @@ bool wxXmlDocument::Save(wxOutputStream& stream) const s.Printf(wxT("\n"), GetVersion().c_str(), GetFileEncoding().c_str()); - OutputString(stream, s, NULL, NULL); + OutputString(stream, s); OutputNode(stream, GetRoot(), 0, convMem, convFile); - OutputString(stream, wxT("\n"), NULL, NULL); + OutputString(stream, wxT("\n")); if ( convFile ) delete convFile;