From: Václav Slavík Date: Thu, 24 Jan 2002 21:14:42 +0000 (+0000) Subject: 1. added encodings handling to XRC, so that it is possible X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/480505bc6dd7343998d3a4de4908a14c4f6d1378 1. added encodings handling to XRC, so that it is possible 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 --- diff --git a/contrib/src/xrc/xml.cpp b/contrib/src/xrc/xml.cpp index bc3bc6af58..cf0f9630bf 100644 --- a/contrib/src/xrc/xml.cpp +++ b/contrib/src/xrc/xml.cpp @@ -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(); } diff --git a/contrib/src/xrc/xmlbin.cpp b/contrib/src/xrc/xmlbin.cpp index bbd98f7ab8..730d509590 100644 --- a/contrib/src/xrc/xmlbin.cpp +++ b/contrib/src/xrc/xmlbin.cpp @@ -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)); diff --git a/contrib/src/xrc/xmlbinz.cpp b/contrib/src/xrc/xmlbinz.cpp index 876ae334bc..5520b31161 100644 --- a/contrib/src/xrc/xmlbinz.cpp +++ b/contrib/src/xrc/xmlbinz.cpp @@ -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); } diff --git a/contrib/src/xrc/xmlexpat.cpp b/contrib/src/xrc/xmlexpat.cpp index 9eaa5c7310..6d4de6fe39 100644 --- a/contrib/src/xrc/xmlexpat.cpp +++ b/contrib/src/xrc/xmlexpat.cpp @@ -30,23 +30,32 @@ /* 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; } diff --git a/contrib/src/xrc/xmlres.cpp b/contrib/src/xrc/xmlres.cpp index ade30b6039..2da69a6491 100644 --- a/contrib/src/xrc/xmlres.cpp +++ b/contrib/src/xrc/xmlres.cpp @@ -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")) diff --git a/contrib/src/xrc/xmlwrite.cpp b/contrib/src/xrc/xmlwrite.cpp index f256c1ba96..3b634c7cc3 100644 --- a/contrib/src/xrc/xmlwrite.cpp +++ b/contrib/src/xrc/xmlwrite.cpp @@ -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("<")); break; - case '>': OutputString(stream, wxT(">")); break; - case '&': OutputString(stream, wxT("&")); break; + case wxT('<'): OutputString(stream, wxT("<")); break; + case wxT('>'): OutputString(stream, wxT(">")); break; + case wxT('&'): OutputString(stream, wxT("&")); break; default: break; } last = i + 1; diff --git a/src/xrc/xml.cpp b/src/xrc/xml.cpp index bc3bc6af58..cf0f9630bf 100644 --- a/src/xrc/xml.cpp +++ b/src/xrc/xml.cpp @@ -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(); } diff --git a/src/xrc/xmlbin.cpp b/src/xrc/xmlbin.cpp index bbd98f7ab8..730d509590 100644 --- a/src/xrc/xmlbin.cpp +++ b/src/xrc/xmlbin.cpp @@ -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)); diff --git a/src/xrc/xmlbinz.cpp b/src/xrc/xmlbinz.cpp index 876ae334bc..5520b31161 100644 --- a/src/xrc/xmlbinz.cpp +++ b/src/xrc/xmlbinz.cpp @@ -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); } diff --git a/src/xrc/xmlexpat.cpp b/src/xrc/xmlexpat.cpp index 9eaa5c7310..6d4de6fe39 100644 --- a/src/xrc/xmlexpat.cpp +++ b/src/xrc/xmlexpat.cpp @@ -30,23 +30,32 @@ /* 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; } diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index ade30b6039..2da69a6491 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -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")) diff --git a/src/xrc/xmlwrite.cpp b/src/xrc/xmlwrite.cpp index f256c1ba96..3b634c7cc3 100644 --- a/src/xrc/xmlwrite.cpp +++ b/src/xrc/xmlwrite.cpp @@ -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("<")); break; - case '>': OutputString(stream, wxT(">")); break; - case '&': OutputString(stream, wxT("&")); break; + case wxT('<'): OutputString(stream, wxT("<")); break; + case wxT('>'): OutputString(stream, wxT(">")); break; + case wxT('&'): OutputString(stream, wxT("&")); break; default: break; } last = i + 1;