]> git.saurik.com Git - wxWidgets.git/commitdiff
1. added encodings handling to XRC, so that it is possible
authorVáclav Slavík <vslavik@fastmail.fm>
Thu, 24 Jan 2002 21:14:42 +0000 (21:14 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Thu, 24 Jan 2002 21:14:42 +0000 (21:14 +0000)
to load resources that don't use English+wxLocale for i18n
2. expat interface can now read non-utf-8 encodings as well

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13783 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

12 files changed:
contrib/src/xrc/xml.cpp
contrib/src/xrc/xmlbin.cpp
contrib/src/xrc/xmlbinz.cpp
contrib/src/xrc/xmlexpat.cpp
contrib/src/xrc/xmlres.cpp
contrib/src/xrc/xmlwrite.cpp
src/xrc/xml.cpp
src/xrc/xmlbin.cpp
src/xrc/xmlbinz.cpp
src/xrc/xmlexpat.cpp
src/xrc/xmlres.cpp
src/xrc/xmlwrite.cpp

index bc3bc6af58c389cd41e217954ad1ef797e569444..cf0f9630bf41894411a49df5f14e280a7e5c36ac 100644 (file)
@@ -300,10 +300,11 @@ wxList *wxXmlDocument::sm_handlers = NULL;
 
 
 
-wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type)
+wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type,
+                             const wxString& encoding)
                           : wxObject(), m_root(NULL)
 {
-    if (!Load(filename, io_type))
+    if (!Load(filename, io_type, encoding))
     {
         wxDELETE(m_root);
     }
@@ -311,10 +312,11 @@ wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type)
 
 
 
-wxXmlDocument::wxXmlDocument(wxInputStream& stream, wxXmlIOType io_type)
+wxXmlDocument::wxXmlDocument(wxInputStream& stream, wxXmlIOType io_type,
+                             const wxString& encoding)
                           : wxObject(), m_root(NULL)
 {
-    if (!Load(stream, io_type))
+    if (!Load(stream, io_type, encoding))
     {
         wxDELETE(m_root);
     }
@@ -341,22 +343,33 @@ wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc)
 void wxXmlDocument::DoCopy(const wxXmlDocument& doc)
 {
     m_version = doc.m_version;
+#if !wxUSE_UNICODE
     m_encoding = doc.m_encoding;
+#endif
+    m_fileEncoding = doc.m_fileEncoding;
     m_root = new wxXmlNode(*doc.m_root);
 }
 
 
 
-bool wxXmlDocument::Load(const wxString& filename, wxXmlIOType io_type)
+bool wxXmlDocument::Load(const wxString& filename, wxXmlIOType io_type,
+                         const wxString& encoding)
 {
     wxFileInputStream stream(filename);
-    return Load(stream, io_type);
+    return Load(stream, io_type, encoding);
 }
 
 
 
-bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type)
+bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type,
+                         const wxString& encoding)
 {
+#if wxUSE_UNICODE
+    (void)encoding;
+#else
+    m_encoding = encoding;
+#endif
+
     wxNode *n = sm_handlers->GetFirst();
     while (n)
     {
@@ -365,7 +378,7 @@ bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type)
         if ((io_type == wxXML_IO_AUTO || io_type == h->GetType()) &&
             h->CanLoad(stream))
         {
-            return h->Load(stream, *this);
+            return h->Load(stream, *this, encoding);
         }
         n = n->GetNext();
     }
index bbd98f7ab855d1d5071c4b5cea10cfe840e42990..730d509590350d1b8c4896123b6ec5b08ab9756c 100644 (file)
@@ -101,7 +101,12 @@ bool wxXmlIOHandlerBin::Save(wxOutputStream& stream, const wxXmlDocument& doc)
 {
     WriteHeader(stream, "XMLBIN ");
     wxDataOutputStream ds(stream);
-    ds << doc.GetVersion() << doc.GetEncoding();
+    ds << doc.GetVersion();
+#if wxUSE_UNICODE
+    ds << wxString(wxT("UTF-8"));
+#else
+    ds << doc.GetEncoding();
+#endif
     SaveBinNode(ds, doc.GetRoot());
     return stream.LastError() == wxSTREAM_NOERROR;
 }
@@ -142,7 +147,8 @@ static wxXmlNode *LoadBinNode(wxDataInputStream& ds, wxXmlNode *parent)
 
 
 
-bool wxXmlIOHandlerBin::Load(wxInputStream& stream, wxXmlDocument& doc)
+bool wxXmlIOHandlerBin::Load(wxInputStream& stream, wxXmlDocument& doc,
+                             const wxString& encoding)
 {
     ReadHeader(stream);
     wxDataInputStream ds(stream);
@@ -151,7 +157,7 @@ bool wxXmlIOHandlerBin::Load(wxInputStream& stream, wxXmlDocument& doc)
     ds >> tmp;
     doc.SetVersion(tmp);
     ds >> tmp;
-    doc.SetEncoding(tmp);
+    doc.SetFileEncoding(tmp);
 
     doc.SetRoot(LoadBinNode(ds, NULL));
         
index 876ae334bc2e15d51348a0e21542f497d247be15..5520b311617992ca33afcb1690f70950d91c0062 100644 (file)
@@ -48,11 +48,12 @@ bool wxXmlIOHandlerBinZ::Save(wxOutputStream& stream, const wxXmlDocument& doc)
 
 
 
-bool wxXmlIOHandlerBinZ::Load(wxInputStream& stream, wxXmlDocument& doc)
+bool wxXmlIOHandlerBinZ::Load(wxInputStream& stream, wxXmlDocument& doc,
+                              const wxString& encoding)
 {
     ReadHeader(stream);
     wxZlibInputStream costr(stream);
-    return wxXmlIOHandlerBin::Load(costr, doc);
+    return wxXmlIOHandlerBin::Load(costr, doc, encoding);
 }
 
 
index 9eaa5c73100e7be7f3a84258136a1f04ac9e9edb..6d4de6fe39483c075ad71641baf4a65b30666fba 100644 (file)
 /*
 
     FIXME:
-
-     - handle unknown encodings
      - process all elements, including CDATA
-     - XRC resources should automatically select desired encoding based on
-       runtime environment (?) (would need BIN and BINZ formats modification,
-       too)
 
  */
 
 
 // converts Expat-produced string in UTF-8 into wxString.
-inline static wxString CharToString(const char *s, size_t len = wxSTRING_MAXLEN)
+inline static wxString CharToString(wxMBConv *conv,
+                                    const char *s, size_t len = wxSTRING_MAXLEN)
 {
 #if wxUSE_UNICODE
+    (void)conv;
     return wxString(s, wxConvUTF8, len);
 #else
-    return wxString(s, len);
+    if ( conv )
+    {
+        size_t nLen = (len != wxSTRING_MAXLEN) ? len :
+                          nLen = wxConvUTF8.MB2WC((wchar_t*) NULL, s, 0);
+    
+        wchar_t *buf = new wchar_t[nLen+1];
+        wxConvUTF8.MB2WC(buf, s, nLen);
+        buf[nLen] = 0;
+        return wxString(buf, *conv, len);
+        delete[] buf;
+    }
+    else
+        return wxString(s, len);
 #endif
 }
 
@@ -62,21 +71,23 @@ bool wxXmlIOHandlerExpat::CanLoad(wxInputStream& stream)
 
 struct wxXmlParsingContext
 {
+    wxMBConv  *conv;
+
     wxXmlNode *root;
     wxXmlNode *node;
     wxXmlNode *lastAsText;
-    wxString encoding;
-    wxString version;
+    wxString   encoding;
+    wxString   version;
 };
 
 static void StartElementHnd(void *userData, const char *name, const char **atts)
 {
     wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
-    wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, CharToString(name));
+    wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, CharToString(ctx->conv, name));
     const char **a = atts;
     while (*a)
     {
-        node->AddProperty(CharToString(a[0]), CharToString(a[1]));
+        node->AddProperty(CharToString(ctx->conv, a[0]), CharToString(ctx->conv, a[1]));
         a += 2;
     }
     if (ctx->root == NULL)
@@ -106,7 +117,7 @@ static void TextHnd(void *userData, const char *s, int len)
     if (ctx->lastAsText)
     {
         ctx->lastAsText->SetContent(ctx->lastAsText->GetContent() +
-                                    CharToString(buf));
+                                    CharToString(ctx->conv, buf));
     }
     else
     {
@@ -120,7 +131,7 @@ static void TextHnd(void *userData, const char *s, int len)
         if (!whiteOnly)
         {
             ctx->lastAsText = new wxXmlNode(wxXML_TEXT_NODE, wxT("text"),
-                                            CharToString(buf));
+                                            CharToString(ctx->conv, buf));
             ctx->node->AddChild(ctx->lastAsText);
         }
     }
@@ -138,7 +149,7 @@ static void CommentHnd(void *userData, const char *data)
         //     the root element (e.g. wxDesigner's output). We ignore such
         //     comments, no big deal...
         ctx->node->AddChild(new wxXmlNode(wxXML_COMMENT_NODE,
-                            wxT("comment"), CharToString(data)));
+                            wxT("comment"), CharToString(ctx->conv, data)));
     }
     ctx->lastAsText = NULL;
 }
@@ -150,7 +161,7 @@ static void DefaultHnd(void *userData, const char *s, int len)
     {
         wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
 
-        wxString buf = CharToString(s, (size_t)len);
+        wxString buf = CharToString(ctx->conv, s, (size_t)len);
         int pos;
         pos = buf.Find(wxT("encoding="));
         if (pos != wxNOT_FOUND)
@@ -161,7 +172,36 @@ static void DefaultHnd(void *userData, const char *s, int len)
     }
 }
 
-bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc)
+static int UnknownEncodingHnd(void * WXUNUSED(encodingHandlerData),
+                               const XML_Char *name, XML_Encoding *info)
+{
+    // We must build conversion table for expat. The easiest way to do so
+    // is to let wxCSConv convert as string containing all characters to
+    // wide character representation:
+    wxCSConv conv(name);
+    char mbBuf[255];
+    wchar_t wcBuf[255];
+    size_t i;
+    
+    for (i = 0; i < 255; i++)
+        mbBuf[i] = i+1;
+    mbBuf[255] = 0;
+    conv.MB2WC(wcBuf, mbBuf, 255);
+    wcBuf[255] = 0;
+    
+    info->map[0] = 0;
+    for (i = 0; i < 255; i++)
+        info->map[i+1] = (int)wcBuf[i];
+    
+    info->data = NULL;
+    info->convert = NULL;
+    info->release = NULL;
+    
+    return 1;
+}
+
+bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc,
+                               const wxString& encoding)
 {
     const size_t BUFSIZE = 1024;
     char buf[BUFSIZE];
@@ -170,11 +210,19 @@ bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc)
     XML_Parser parser = XML_ParserCreate(NULL);
 
     ctx.root = ctx.node = NULL;
+    ctx.encoding = wxT("UTF-8"); // default in absence of encoding=""
+    ctx.conv = NULL;
+#if !wxUSE_UNICODE
+    if ( encoding != wxT("UTF-8") && encoding != wxT("utf-8") )
+        ctx.conv = new wxCSConv(encoding);
+#endif
+    
     XML_SetUserData(parser, (void*)&ctx);
     XML_SetElementHandler(parser, StartElementHnd, EndElementHnd);
     XML_SetCharacterDataHandler(parser, TextHnd);
     XML_SetCommentHandler(parser, CommentHnd);
     XML_SetDefaultHandler(parser, DefaultHnd);
+    XML_SetUnknownEncodingHandler(parser, UnknownEncodingHnd, NULL);
 
     do
     {
@@ -190,9 +238,14 @@ bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc)
     } while (!done);
 
     doc.SetVersion(ctx.version);
-    doc.SetEncoding(ctx.encoding);
+    doc.SetFileEncoding(ctx.encoding);
     doc.SetRoot(ctx.root);
 
     XML_ParserFree(parser);
+#if !wxUSE_UNICODE
+    if ( ctx.conv )
+        delete ctx.conv;
+#endif
+    
     return TRUE;
 }
index ade30b60395046eb4a00322f81af7f1908ca1fba..2da69a6491770a99704b653c1933358abe2ebae2 100644 (file)
@@ -100,9 +100,9 @@ bool wxXmlResource::Load(const wxString& filemask)
     {
 #if wxUSE_FILESYSTEM
         if (filemask.Lower().Matches(wxT("*.zip")) ||
-            filemask.Lower().Matches(wxT("*.rsc")))
+            filemask.Lower().Matches(wxT("*.xrs")))
         {
-            rt = rt && Load(fnd + wxT("#zip:*.xmb"));
+            rt = rt && Load(fnd + wxT("#zip:*.xmlbin"));
             rt = rt && Load(fnd + wxT("#zip:*.xrc"));
         }
         else
@@ -286,6 +286,17 @@ void wxXmlResource::UpdateResources()
     wxFileSystem fsys;
 #   endif
 
+    wxString encoding(wxT("UTF-8"));
+#if !wxUSE_UNICODE && wxUSE_INTL
+    if ( (GetFlags() & wxXRC_USE_LOCALE) == 0 )
+    {
+        // In case we are not using wxLocale to translate strings, convert the strings
+        // GUI's charset. This must not be done when wxXRC_USE_LOCALE is on, because
+        // it could break wxGetTranslation lookup.
+        encoding = wxLocale::GetSystemEncodingName();
+    }
+#endif
+
     for (size_t i = 0; i < m_data.GetCount(); i++)
     {
         modif = (m_data[i].Doc == NULL);
@@ -305,7 +316,7 @@ void wxXmlResource::UpdateResources()
 
         if (modif)
         {
-                       wxInputStream *stream = NULL;
+            wxInputStream *stream = NULL;
 
 #           if wxUSE_FILESYSTEM
             file = fsys.OpenFile(m_data[i].File);
@@ -320,9 +331,10 @@ void wxXmlResource::UpdateResources()
                 delete m_data[i].Doc;
                 m_data[i].Doc = new wxXmlDocument;
             }
-            if (!stream || !m_data[i].Doc->Load(*stream))
+            if (!stream || !m_data[i].Doc->Load(*stream, wxXML_IO_AUTO, encoding))
             {
-                wxLogError(_("Cannot load resources from file '%s'."), m_data[i].File.c_str());
+                wxLogError(_("Cannot load resources from file '%s'."),
+                           m_data[i].File.c_str());
                 wxDELETE(m_data[i].Doc);
             }
             else if (m_data[i].Doc->GetRoot()->GetName() != wxT("resource"))
index f256c1ba9692bc8c9e7891e10632749e7f415f6d..3b634c7cc3c150874bdc37db42036acbef929ab3 100644 (file)
@@ -44,22 +44,22 @@ static void OutputStringEnt(wxOutputStream& stream, const wxString& str)
 {
     wxString buf;
     size_t i, last, len;
-    char c;
+    wxChar c;
     
     len = str.Len();
     last = 0;
     for (i = 0; i < len; i++)
     {
         c = str.GetChar(i);
-        if (c == '<' || c == '>' || 
-            (c == '&' && str.Mid(i+1, 4) != wxT("amp;")))
+        if (c == wxT('<') || c == wxT('>') || 
+            (c == wxT('&') && str.Mid(i+1, 4) != wxT("amp;")))
         {
             OutputString(stream, str.Mid(last, i - last));
             switch (c)
             {
-                case '<': OutputString(stream, wxT("&lt;")); break;
-                case '>': OutputString(stream, wxT("&gt;")); break;
-                case '&': OutputString(stream, wxT("&amp;")); break;
+                case wxT('<'): OutputString(stream, wxT("&lt;")); break;
+                case wxT('>'): OutputString(stream, wxT("&gt;")); break;
+                case wxT('&'): OutputString(stream, wxT("&amp;")); break;
                 default: break;
             }
             last = i + 1;
index bc3bc6af58c389cd41e217954ad1ef797e569444..cf0f9630bf41894411a49df5f14e280a7e5c36ac 100644 (file)
@@ -300,10 +300,11 @@ wxList *wxXmlDocument::sm_handlers = NULL;
 
 
 
-wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type)
+wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type,
+                             const wxString& encoding)
                           : wxObject(), m_root(NULL)
 {
-    if (!Load(filename, io_type))
+    if (!Load(filename, io_type, encoding))
     {
         wxDELETE(m_root);
     }
@@ -311,10 +312,11 @@ wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type)
 
 
 
-wxXmlDocument::wxXmlDocument(wxInputStream& stream, wxXmlIOType io_type)
+wxXmlDocument::wxXmlDocument(wxInputStream& stream, wxXmlIOType io_type,
+                             const wxString& encoding)
                           : wxObject(), m_root(NULL)
 {
-    if (!Load(stream, io_type))
+    if (!Load(stream, io_type, encoding))
     {
         wxDELETE(m_root);
     }
@@ -341,22 +343,33 @@ wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc)
 void wxXmlDocument::DoCopy(const wxXmlDocument& doc)
 {
     m_version = doc.m_version;
+#if !wxUSE_UNICODE
     m_encoding = doc.m_encoding;
+#endif
+    m_fileEncoding = doc.m_fileEncoding;
     m_root = new wxXmlNode(*doc.m_root);
 }
 
 
 
-bool wxXmlDocument::Load(const wxString& filename, wxXmlIOType io_type)
+bool wxXmlDocument::Load(const wxString& filename, wxXmlIOType io_type,
+                         const wxString& encoding)
 {
     wxFileInputStream stream(filename);
-    return Load(stream, io_type);
+    return Load(stream, io_type, encoding);
 }
 
 
 
-bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type)
+bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type,
+                         const wxString& encoding)
 {
+#if wxUSE_UNICODE
+    (void)encoding;
+#else
+    m_encoding = encoding;
+#endif
+
     wxNode *n = sm_handlers->GetFirst();
     while (n)
     {
@@ -365,7 +378,7 @@ bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type)
         if ((io_type == wxXML_IO_AUTO || io_type == h->GetType()) &&
             h->CanLoad(stream))
         {
-            return h->Load(stream, *this);
+            return h->Load(stream, *this, encoding);
         }
         n = n->GetNext();
     }
index bbd98f7ab855d1d5071c4b5cea10cfe840e42990..730d509590350d1b8c4896123b6ec5b08ab9756c 100644 (file)
@@ -101,7 +101,12 @@ bool wxXmlIOHandlerBin::Save(wxOutputStream& stream, const wxXmlDocument& doc)
 {
     WriteHeader(stream, "XMLBIN ");
     wxDataOutputStream ds(stream);
-    ds << doc.GetVersion() << doc.GetEncoding();
+    ds << doc.GetVersion();
+#if wxUSE_UNICODE
+    ds << wxString(wxT("UTF-8"));
+#else
+    ds << doc.GetEncoding();
+#endif
     SaveBinNode(ds, doc.GetRoot());
     return stream.LastError() == wxSTREAM_NOERROR;
 }
@@ -142,7 +147,8 @@ static wxXmlNode *LoadBinNode(wxDataInputStream& ds, wxXmlNode *parent)
 
 
 
-bool wxXmlIOHandlerBin::Load(wxInputStream& stream, wxXmlDocument& doc)
+bool wxXmlIOHandlerBin::Load(wxInputStream& stream, wxXmlDocument& doc,
+                             const wxString& encoding)
 {
     ReadHeader(stream);
     wxDataInputStream ds(stream);
@@ -151,7 +157,7 @@ bool wxXmlIOHandlerBin::Load(wxInputStream& stream, wxXmlDocument& doc)
     ds >> tmp;
     doc.SetVersion(tmp);
     ds >> tmp;
-    doc.SetEncoding(tmp);
+    doc.SetFileEncoding(tmp);
 
     doc.SetRoot(LoadBinNode(ds, NULL));
         
index 876ae334bc2e15d51348a0e21542f497d247be15..5520b311617992ca33afcb1690f70950d91c0062 100644 (file)
@@ -48,11 +48,12 @@ bool wxXmlIOHandlerBinZ::Save(wxOutputStream& stream, const wxXmlDocument& doc)
 
 
 
-bool wxXmlIOHandlerBinZ::Load(wxInputStream& stream, wxXmlDocument& doc)
+bool wxXmlIOHandlerBinZ::Load(wxInputStream& stream, wxXmlDocument& doc,
+                              const wxString& encoding)
 {
     ReadHeader(stream);
     wxZlibInputStream costr(stream);
-    return wxXmlIOHandlerBin::Load(costr, doc);
+    return wxXmlIOHandlerBin::Load(costr, doc, encoding);
 }
 
 
index 9eaa5c73100e7be7f3a84258136a1f04ac9e9edb..6d4de6fe39483c075ad71641baf4a65b30666fba 100644 (file)
 /*
 
     FIXME:
-
-     - handle unknown encodings
      - process all elements, including CDATA
-     - XRC resources should automatically select desired encoding based on
-       runtime environment (?) (would need BIN and BINZ formats modification,
-       too)
 
  */
 
 
 // converts Expat-produced string in UTF-8 into wxString.
-inline static wxString CharToString(const char *s, size_t len = wxSTRING_MAXLEN)
+inline static wxString CharToString(wxMBConv *conv,
+                                    const char *s, size_t len = wxSTRING_MAXLEN)
 {
 #if wxUSE_UNICODE
+    (void)conv;
     return wxString(s, wxConvUTF8, len);
 #else
-    return wxString(s, len);
+    if ( conv )
+    {
+        size_t nLen = (len != wxSTRING_MAXLEN) ? len :
+                          nLen = wxConvUTF8.MB2WC((wchar_t*) NULL, s, 0);
+    
+        wchar_t *buf = new wchar_t[nLen+1];
+        wxConvUTF8.MB2WC(buf, s, nLen);
+        buf[nLen] = 0;
+        return wxString(buf, *conv, len);
+        delete[] buf;
+    }
+    else
+        return wxString(s, len);
 #endif
 }
 
@@ -62,21 +71,23 @@ bool wxXmlIOHandlerExpat::CanLoad(wxInputStream& stream)
 
 struct wxXmlParsingContext
 {
+    wxMBConv  *conv;
+
     wxXmlNode *root;
     wxXmlNode *node;
     wxXmlNode *lastAsText;
-    wxString encoding;
-    wxString version;
+    wxString   encoding;
+    wxString   version;
 };
 
 static void StartElementHnd(void *userData, const char *name, const char **atts)
 {
     wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
-    wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, CharToString(name));
+    wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, CharToString(ctx->conv, name));
     const char **a = atts;
     while (*a)
     {
-        node->AddProperty(CharToString(a[0]), CharToString(a[1]));
+        node->AddProperty(CharToString(ctx->conv, a[0]), CharToString(ctx->conv, a[1]));
         a += 2;
     }
     if (ctx->root == NULL)
@@ -106,7 +117,7 @@ static void TextHnd(void *userData, const char *s, int len)
     if (ctx->lastAsText)
     {
         ctx->lastAsText->SetContent(ctx->lastAsText->GetContent() +
-                                    CharToString(buf));
+                                    CharToString(ctx->conv, buf));
     }
     else
     {
@@ -120,7 +131,7 @@ static void TextHnd(void *userData, const char *s, int len)
         if (!whiteOnly)
         {
             ctx->lastAsText = new wxXmlNode(wxXML_TEXT_NODE, wxT("text"),
-                                            CharToString(buf));
+                                            CharToString(ctx->conv, buf));
             ctx->node->AddChild(ctx->lastAsText);
         }
     }
@@ -138,7 +149,7 @@ static void CommentHnd(void *userData, const char *data)
         //     the root element (e.g. wxDesigner's output). We ignore such
         //     comments, no big deal...
         ctx->node->AddChild(new wxXmlNode(wxXML_COMMENT_NODE,
-                            wxT("comment"), CharToString(data)));
+                            wxT("comment"), CharToString(ctx->conv, data)));
     }
     ctx->lastAsText = NULL;
 }
@@ -150,7 +161,7 @@ static void DefaultHnd(void *userData, const char *s, int len)
     {
         wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
 
-        wxString buf = CharToString(s, (size_t)len);
+        wxString buf = CharToString(ctx->conv, s, (size_t)len);
         int pos;
         pos = buf.Find(wxT("encoding="));
         if (pos != wxNOT_FOUND)
@@ -161,7 +172,36 @@ static void DefaultHnd(void *userData, const char *s, int len)
     }
 }
 
-bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc)
+static int UnknownEncodingHnd(void * WXUNUSED(encodingHandlerData),
+                               const XML_Char *name, XML_Encoding *info)
+{
+    // We must build conversion table for expat. The easiest way to do so
+    // is to let wxCSConv convert as string containing all characters to
+    // wide character representation:
+    wxCSConv conv(name);
+    char mbBuf[255];
+    wchar_t wcBuf[255];
+    size_t i;
+    
+    for (i = 0; i < 255; i++)
+        mbBuf[i] = i+1;
+    mbBuf[255] = 0;
+    conv.MB2WC(wcBuf, mbBuf, 255);
+    wcBuf[255] = 0;
+    
+    info->map[0] = 0;
+    for (i = 0; i < 255; i++)
+        info->map[i+1] = (int)wcBuf[i];
+    
+    info->data = NULL;
+    info->convert = NULL;
+    info->release = NULL;
+    
+    return 1;
+}
+
+bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc,
+                               const wxString& encoding)
 {
     const size_t BUFSIZE = 1024;
     char buf[BUFSIZE];
@@ -170,11 +210,19 @@ bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc)
     XML_Parser parser = XML_ParserCreate(NULL);
 
     ctx.root = ctx.node = NULL;
+    ctx.encoding = wxT("UTF-8"); // default in absence of encoding=""
+    ctx.conv = NULL;
+#if !wxUSE_UNICODE
+    if ( encoding != wxT("UTF-8") && encoding != wxT("utf-8") )
+        ctx.conv = new wxCSConv(encoding);
+#endif
+    
     XML_SetUserData(parser, (void*)&ctx);
     XML_SetElementHandler(parser, StartElementHnd, EndElementHnd);
     XML_SetCharacterDataHandler(parser, TextHnd);
     XML_SetCommentHandler(parser, CommentHnd);
     XML_SetDefaultHandler(parser, DefaultHnd);
+    XML_SetUnknownEncodingHandler(parser, UnknownEncodingHnd, NULL);
 
     do
     {
@@ -190,9 +238,14 @@ bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc)
     } while (!done);
 
     doc.SetVersion(ctx.version);
-    doc.SetEncoding(ctx.encoding);
+    doc.SetFileEncoding(ctx.encoding);
     doc.SetRoot(ctx.root);
 
     XML_ParserFree(parser);
+#if !wxUSE_UNICODE
+    if ( ctx.conv )
+        delete ctx.conv;
+#endif
+    
     return TRUE;
 }
index ade30b60395046eb4a00322f81af7f1908ca1fba..2da69a6491770a99704b653c1933358abe2ebae2 100644 (file)
@@ -100,9 +100,9 @@ bool wxXmlResource::Load(const wxString& filemask)
     {
 #if wxUSE_FILESYSTEM
         if (filemask.Lower().Matches(wxT("*.zip")) ||
-            filemask.Lower().Matches(wxT("*.rsc")))
+            filemask.Lower().Matches(wxT("*.xrs")))
         {
-            rt = rt && Load(fnd + wxT("#zip:*.xmb"));
+            rt = rt && Load(fnd + wxT("#zip:*.xmlbin"));
             rt = rt && Load(fnd + wxT("#zip:*.xrc"));
         }
         else
@@ -286,6 +286,17 @@ void wxXmlResource::UpdateResources()
     wxFileSystem fsys;
 #   endif
 
+    wxString encoding(wxT("UTF-8"));
+#if !wxUSE_UNICODE && wxUSE_INTL
+    if ( (GetFlags() & wxXRC_USE_LOCALE) == 0 )
+    {
+        // In case we are not using wxLocale to translate strings, convert the strings
+        // GUI's charset. This must not be done when wxXRC_USE_LOCALE is on, because
+        // it could break wxGetTranslation lookup.
+        encoding = wxLocale::GetSystemEncodingName();
+    }
+#endif
+
     for (size_t i = 0; i < m_data.GetCount(); i++)
     {
         modif = (m_data[i].Doc == NULL);
@@ -305,7 +316,7 @@ void wxXmlResource::UpdateResources()
 
         if (modif)
         {
-                       wxInputStream *stream = NULL;
+            wxInputStream *stream = NULL;
 
 #           if wxUSE_FILESYSTEM
             file = fsys.OpenFile(m_data[i].File);
@@ -320,9 +331,10 @@ void wxXmlResource::UpdateResources()
                 delete m_data[i].Doc;
                 m_data[i].Doc = new wxXmlDocument;
             }
-            if (!stream || !m_data[i].Doc->Load(*stream))
+            if (!stream || !m_data[i].Doc->Load(*stream, wxXML_IO_AUTO, encoding))
             {
-                wxLogError(_("Cannot load resources from file '%s'."), m_data[i].File.c_str());
+                wxLogError(_("Cannot load resources from file '%s'."),
+                           m_data[i].File.c_str());
                 wxDELETE(m_data[i].Doc);
             }
             else if (m_data[i].Doc->GetRoot()->GetName() != wxT("resource"))
index f256c1ba9692bc8c9e7891e10632749e7f415f6d..3b634c7cc3c150874bdc37db42036acbef929ab3 100644 (file)
@@ -44,22 +44,22 @@ static void OutputStringEnt(wxOutputStream& stream, const wxString& str)
 {
     wxString buf;
     size_t i, last, len;
-    char c;
+    wxChar c;
     
     len = str.Len();
     last = 0;
     for (i = 0; i < len; i++)
     {
         c = str.GetChar(i);
-        if (c == '<' || c == '>' || 
-            (c == '&' && str.Mid(i+1, 4) != wxT("amp;")))
+        if (c == wxT('<') || c == wxT('>') || 
+            (c == wxT('&') && str.Mid(i+1, 4) != wxT("amp;")))
         {
             OutputString(stream, str.Mid(last, i - last));
             switch (c)
             {
-                case '<': OutputString(stream, wxT("&lt;")); break;
-                case '>': OutputString(stream, wxT("&gt;")); break;
-                case '&': OutputString(stream, wxT("&amp;")); break;
+                case wxT('<'): OutputString(stream, wxT("&lt;")); break;
+                case wxT('>'): OutputString(stream, wxT("&gt;")); break;
+                case wxT('&'): OutputString(stream, wxT("&amp;")); break;
                 default: break;
             }
             last = i + 1;