Changeset 56215
- Timestamp:
- 10/10/08 09:13:53 (6 weeks ago)
- Location:
- wxWidgets/trunk
- Files:
-
- 2 modified
-
src/xml/xml.cpp (modified) (11 diffs)
-
tests/xml/xmltest.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wxWidgets/trunk/src/xml/xml.cpp
r54721 r56215 30 30 #include "wx/zstream.h" 31 31 #include "wx/strconv.h" 32 #include "wx/ptr_scpd.h" 32 33 33 34 #include "expat.h" // from Expat … … 393 394 394 395 wxXmlDocument::wxXmlDocument() 395 : m_version(wx T("1.0")), m_fileEncoding(wxT("utf-8")), m_root(NULL)396 : m_version(wxS("1.0")), m_fileEncoding(wxS("utf-8")), m_root(NULL) 396 397 { 397 398 #if !wxUSE_UNICODE 398 m_encoding = wx T("UTF-8");399 m_encoding = wxS("UTF-8"); 399 400 #endif 400 401 } … … 495 496 { 496 497 wxChar c = *i; 497 if ( c != wx T(' ') && c != wxT('\t') && c != wxT('\n') && c != wxT('\r'))498 if ( c != wxS(' ') && c != wxS('\t') && c != wxS('\n') && c != wxS('\r')) 498 499 return false; 499 500 } … … 595 596 { 596 597 wxXmlNode *textnode = 597 new wxXmlNode(wxXML_TEXT_NODE, wx T("text"), str,598 new wxXmlNode(wxXML_TEXT_NODE, wxS("text"), str, 598 599 XML_GetCurrentLineNumber(ctx->parser)); 599 600 … … 610 611 611 612 wxXmlNode *textnode = 612 new wxXmlNode(wxXML_CDATA_SECTION_NODE, wx T("cdata"), wxT(""),613 new wxXmlNode(wxXML_CDATA_SECTION_NODE, wxS("cdata"), wxS(""), 613 614 XML_GetCurrentLineNumber(ctx->parser)); 614 615 … … 626 627 wxXmlNode *commentnode = 627 628 new wxXmlNode(wxXML_COMMENT_NODE, 628 wx T("comment"), CharToString(ctx->conv, data),629 wxS("comment"), CharToString(ctx->conv, data), 629 630 XML_GetCurrentLineNumber(ctx->parser)); 630 631 … … 649 650 wxString buf = CharToString(ctx->conv, s, (size_t)len); 650 651 int pos; 651 pos = buf.Find(wx T("encoding="));652 pos = buf.Find(wxS("encoding=")); 652 653 if (pos != wxNOT_FOUND) 653 654 ctx->encoding = buf.Mid(pos + 10).BeforeFirst(buf[(size_t)pos+9]); 654 pos = buf.Find(wx T("version="));655 pos = buf.Find(wxS("version=")); 655 656 if (pos != wxNOT_FOUND) 656 657 ctx->version = buf.Mid(pos + 9).BeforeFirst(buf[(size_t)pos+8]); … … 705 706 XML_Parser parser = XML_ParserCreate(NULL); 706 707 707 ctx.encoding = wx T("UTF-8"); // default in absence of encoding=""708 ctx.encoding = wxS("UTF-8"); // default in absence of encoding="" 708 709 ctx.conv = NULL; 709 710 #if !wxUSE_UNICODE 710 if ( encoding.CmpNoCase(wx T("UTF-8")) != 0 )711 if ( encoding.CmpNoCase(wxS("UTF-8")) != 0 ) 711 712 ctx.conv = new wxCSConv(encoding); 712 713 #endif … … 768 769 //----------------------------------------------------------------------------- 769 770 771 // helpers for XML generation 772 namespace 773 { 774 770 775 // write string to output: 771 inline static void OutputString(wxOutputStream& stream, const wxString& str, 772 wxMBConv *convMem = NULL, 773 wxMBConv *convFile = NULL) 776 bool OutputString(wxOutputStream& stream, 777 const wxString& str, 778 wxMBConv *convMem, 779 wxMBConv *convFile) 774 780 { 775 781 if (str.empty()) 776 return ;782 return true; 777 783 778 784 #if wxUSE_UNICODE 779 785 wxUnusedVar(convMem); 780 786 781 const wxWX2MBbuf buf(str.mb_str(*(convFile ? convFile : &wxConvUTF8))); 782 stream.Write((const char*)buf, strlen((const char*)buf)); 787 const wxWX2MBbuf buf(str.mb_str(convFile ? *convFile : wxConvUTF8)); 788 if ( !buf ) 789 return false; 790 791 stream.Write(buf, strlen(buf)); 783 792 #else // !wxUSE_UNICODE 784 793 if ( convFile && convMem ) 785 794 { 786 795 wxString str2(str.wc_str(*convMem), *convFile); 787 stream.Write(str2.mb_str(), str2. Len());796 stream.Write(str2.mb_str(), str2.length()); 788 797 } 789 798 else // no conversions to do 790 799 { 791 stream.Write(str.mb_str(), str. Len());800 stream.Write(str.mb_str(), str.length()); 792 801 } 793 802 #endif // wxUSE_UNICODE/!wxUSE_UNICODE 803 804 return stream.IsOk(); 794 805 } 795 806 … … 802 813 // Same as above, but create entities first. 803 814 // Translates '<' to "<", '>' to ">" and '&' to "&" 804 static void OutputStringEnt(wxOutputStream& stream, const wxString& str, 805 wxMBConv *convMem = NULL, 806 wxMBConv *convFile = NULL, 807 int flags = 0) 808 { 809 wxString buf; 810 size_t i, last, len; 811 wxChar c; 812 813 len = str.Len(); 814 last = 0; 815 bool OutputStringEnt(wxOutputStream& stream, 816 const wxString& str, 817 wxMBConv *convMem, 818 wxMBConv *convFile, 819 int flags = 0) 820 { 821 const size_t len = str.length(); 822 size_t i, 823 last = 0; 815 824 for (i = 0; i < len; i++) 816 825 { 817 c = str.GetChar(i);818 if (c == wx T('<') || c == wxT('>') ||819 (c == wx T('&') && str.Mid(i+1, 4) != wxT("amp;")) ||820 ((flags & XML_ESCAPE_QUOTES) && c == wx T('"')))826 wxChar c = str.GetChar(i); 827 if (c == wxS('<') || c == wxS('>') || 828 (c == wxS('&') && str.Mid(i+1, 4) != wxS("amp;")) || 829 ((flags & XML_ESCAPE_QUOTES) && c == wxS('"'))) 821 830 { 822 OutputString(stream, str.Mid(last, i - last), convMem, convFile); 823 switch (c) 831 if ( !OutputString(stream, str.substr(last, i), convMem, convFile) ) 832 return false; 833 834 const char *escaped; 835 switch ( c ) 824 836 { 825 case wx T('<'):826 OutputString(stream, wxT("<"));837 case wxS('<'): 838 escaped = "<"; 827 839 break; 828 case wx T('>'):829 OutputString(stream, wxT(">"));840 case wxS('>'): 841 escaped = ">"; 830 842 break; 831 case wx T('&'):832 OutputString(stream, wxT("&"));843 case wxS('&'): 844 escaped = "&"; 833 845 break; 834 case wx T('"'):835 OutputString(stream, wxT("""));846 case wxS('"'): 847 escaped = """; 836 848 break; 837 849 default: 838 break; 850 wxFAIL_MSG( "logic error in the code" ); 851 return false; 839 852 } 853 854 if ( !OutputString(stream, escaped, convMem, convFile) ) 855 return false; 856 840 857 last = i + 1; 841 858 } 842 859 } 843 OutputString(stream, str.Mid(last, i - last), convMem, convFile); 844 } 845 846 inline static void OutputIndentation(wxOutputStream& stream, int indent) 847 { 848 wxString str = wxT("\n"); 849 for (int i = 0; i < indent; i++) 850 str << wxT(' ') << wxT(' '); 851 OutputString(stream, str); 852 } 853 854 static void OutputNode(wxOutputStream& stream, wxXmlNode *node, int indent, 855 wxMBConv *convMem, wxMBConv *convFile, int indentstep) 856 { 857 wxXmlNode *n, *prev; 858 wxXmlAttribute *attr; 859 860 861 return OutputString(stream, str.substr(last, i), convMem, convFile); 862 } 863 864 bool OutputIndentation(wxOutputStream& stream, 865 int indent, 866 wxMBConv *convMem, 867 wxMBConv *convFile) 868 { 869 wxString str(wxS("\n")); 870 str += wxString(2*indent, wxS(' ')); 871 return OutputString(stream, str, convMem, convFile); 872 } 873 874 bool OutputNode(wxOutputStream& stream, 875 wxXmlNode *node, 876 int indent, 877 wxMBConv *convMem, 878 wxMBConv *convFile, 879 int indentstep) 880 { 881 bool rc; 860 882 switch (node->GetType()) 861 883 { 862 884 case wxXML_CDATA_SECTION_NODE: 863 OutputString( stream, wxT("<![CDATA["));864 OutputString( stream, node->GetContent() );865 OutputString( stream, wxT("]]>"));885 rc = OutputString(stream, wxS("<![CDATA["), convMem, convFile) && 886 OutputString(stream, node->GetContent(), convMem, convFile) && 887 OutputString(stream, wxS("]]>"), convMem, convFile); 866 888 break; 867 889 868 890 case wxXML_TEXT_NODE: 869 OutputStringEnt(stream, node->GetContent(), convMem, convFile);891 rc = OutputStringEnt(stream, node->GetContent(), convMem, convFile); 870 892 break; 871 893 872 894 case wxXML_ELEMENT_NODE: 873 OutputString(stream, wxT("<")); 874 OutputString(stream, node->GetName()); 875 876 attr = node->GetAttributes(); 877 while (attr) 895 rc = OutputString(stream, wxS("<"), convMem, convFile) && 896 OutputString(stream, node->GetName(), convMem, convFile); 897 898 if ( rc ) 878 899 { 879 OutputString(stream, wxT(" ") + attr->GetName() + wxT("=\"")); 880 OutputStringEnt(stream, attr->GetValue(), convMem, convFile, 881 XML_ESCAPE_QUOTES); 882 OutputString(stream, wxT("\"")); 883 attr = attr->GetNext(); 900 for ( wxXmlAttribute *attr = node->GetAttributes(); 901 attr && rc; 902 attr = attr->GetNext() ) 903 { 904 rc = OutputString(stream, 905 wxS(" ") + attr->GetName() + wxS("=\""), 906 convMem, convFile) && 907 OutputStringEnt(stream, attr->GetValue(), 908 convMem, convFile, 909 XML_ESCAPE_QUOTES) && 910 OutputString(stream, wxS("\""), convMem, convFile); 911 } 884 912 } 885 913 886 if ( node->GetChildren())914 if ( node->GetChildren() ) 887 915 { 888 OutputString(stream, wxT(">")); 889 prev = NULL; 890 n = node->GetChildren(); 891 while (n) 916 rc = OutputString(stream, wxS(">"), convMem, convFile); 917 918 wxXmlNode *prev = NULL; 919 for ( wxXmlNode *n = node->GetChildren(); 920 n && rc; 921 n = n->GetNext() ) 892 922 { 893 if (indentstep >= 0 && n && n->GetType() != wxXML_TEXT_NODE) 894 OutputIndentation(stream, indent + indentstep); 895 OutputNode(stream, n, indent + indentstep, convMem, convFile, indentstep); 923 if ( indentstep >= 0 && n->GetType() != wxXML_TEXT_NODE ) 924 { 925 rc = OutputIndentation(stream, indent + indentstep, 926 convMem, convFile); 927 } 928 929 if ( rc ) 930 rc = OutputNode(stream, n, indent + indentstep, 931 convMem, convFile, indentstep); 932 896 933 prev = n; 897 n = n->GetNext();898 934 } 899 if (indentstep >= 0 && prev && prev->GetType() != wxXML_TEXT_NODE) 900 OutputIndentation(stream, indent); 901 OutputString(stream, wxT("</")); 902 OutputString(stream, node->GetName()); 903 OutputString(stream, wxT(">")); 935 936 if ( rc && indentstep >= 0 && 937 prev && prev->GetType() != wxXML_TEXT_NODE ) 938 { 939 rc = OutputIndentation(stream, indent, convMem, convFile); 940 } 941 942 if ( rc ) 943 { 944 rc = OutputString(stream, wxS("</"), convMem, convFile) && 945 OutputString(stream, node->GetName(), 946 convMem, convFile) && 947 OutputString(stream, wxS(">"), convMem, convFile); 948 } 904 949 } 905 else 906 OutputString(stream, wxT("/>")); 950 else // no children, output "<foo/>" 951 { 952 rc = OutputString(stream, wxS("/>"), convMem, convFile); 953 } 907 954 break; 908 955 909 956 case wxXML_COMMENT_NODE: 910 OutputString(stream, wxT("<!--"));911 OutputString(stream, node->GetContent(), convMem, convFile);912 OutputString(stream, wxT("-->"));957 rc = OutputString(stream, wxS("<!--"), convMem, convFile) && 958 OutputString(stream, node->GetContent(), convMem, convFile) && 959 OutputString(stream, wxS("-->"), convMem, convFile); 913 960 break; 914 961 915 962 default: 916 wxFAIL_MSG(wxT("unsupported node type")); 917 } 918 } 963 wxFAIL_MSG("unsupported node type"); 964 rc = false; 965 } 966 967 return rc; 968 } 969 970 } // anonymous namespace 919 971 920 972 bool wxXmlDocument::Save(wxOutputStream& stream, int indentstep) const … … 923 975 return false; 924 976 925 wxString s; 926 927 wxMBConv *convMem = NULL, 928 *convFile; 977 wxScopedPtr<wxMBConv> convMem, convFile; 929 978 930 979 #if wxUSE_UNICODE 931 convFile = new wxCSConv(GetFileEncoding()); 932 convMem = NULL; 980 convFile.reset(new wxCSConv(GetFileEncoding())); 933 981 #else 934 982 if ( GetFileEncoding().CmpNoCase(GetEncoding()) != 0 ) 935 983 { 936 convFile = new wxCSConv(GetFileEncoding()); 937 convMem = new wxCSConv(GetEncoding()); 938 } 939 else // file and in-memory encodings are the same, no conversion needed 940 { 941 convFile = 942 convMem = NULL; 943 } 984 convFile.reset(new wxCSConv(GetFileEncoding())); 985 convMem.reset(new wxCSConv(GetEncoding())); 986 } 987 //else: file and in-memory encodings are the same, no conversion needed 944 988 #endif 945 989 946 s.Printf(wxT("<?xml version=\"%s\" encoding=\"%s\"?>\n"),947 GetVersion().c_str(), GetFileEncoding().c_str());948 OutputString(stream, s);949 950 OutputNode(stream, GetRoot(), 0, convMem, convFile, indentstep);951 OutputString(stream, wxT("\n"));952 953 delete convFile;954 delete convMem;955 956 return true;990 return OutputString(stream, 991 wxString::Format 992 ( 993 wxS("<?xml version=\"%s\" encoding=\"%s\"?>\n"), 994 GetVersion(), GetFileEncoding() 995 ), 996 convMem.get(), 997 convFile.get()) && 998 OutputNode(stream, GetRoot(), 0, 999 convMem.get(), convFile.get(), indentstep) && 1000 OutputString(stream, wxS("\n"), convMem.get(), convFile.get()); 957 1001 } 958 1002 -
wxWidgets/trunk/tests/xml/xmltest.cpp
r56212 r56215 164 164 165 165 CPPUNIT_ASSERT_EQUAL( xmlText, sos.GetString() ); 166 167 168 const char *utf8xmlText = 169 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 170 "<word>\n" 171 " <lang name=\"fr\">\xc3\xa9t\xc3\xa9</lang>\n" 172 " <lang name=\"ru\">\xd0\xbb\xd0\xb5\xd1\x82\xd0\xbe</lang>\n" 173 "</word>\n" 174 ; 175 176 wxStringInputStream sis8(wxString::FromUTF8(utf8xmlText)); 177 CPPUNIT_ASSERT( doc.Load(sis8) ); 178 179 // this contents can't be represented in Latin-1 as it contains Cyrillic 180 // letters 181 doc.SetFileEncoding("ISO-8859-1"); 182 CPPUNIT_ASSERT( !doc.Save(sos) ); 183 184 // but it should work in UTF-8 185 wxStringOutputStream sos8; 186 doc.SetFileEncoding("UTF-8"); 187 CPPUNIT_ASSERT( doc.Save(sos8) ); 188 CPPUNIT_ASSERT_EQUAL( utf8xmlText, sos8.GetString().ToUTF8() ); 166 189 } 167 190
