From dccce9eae10e099d791cc055dd02d3dda731778e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 31 May 2001 20:27:37 +0000 Subject: [PATCH] added wxLocale::GetSystemEncoding git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10394 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/font.tex | 62 +++++++++ docs/latex/wx/fontmap.tex | 5 +- docs/latex/wx/locale.tex | 20 +++ include/wx/intl.h | 26 ++-- include/wx/strconv.h | 3 + samples/console/console.cpp | 12 +- src/common/intl.cpp | 114 ++++++++++++++--- src/common/strconv.cpp | 242 +++++++++++++++++------------------- 8 files changed, 326 insertions(+), 158 deletions(-) diff --git a/docs/latex/wx/font.tex b/docs/latex/wx/font.tex index 1c02b9bc44..1c3682a2f5 100644 --- a/docs/latex/wx/font.tex +++ b/docs/latex/wx/font.tex @@ -13,6 +13,68 @@ a window's text. +\wxheading{Constants} + +\begin{verbatim} +enum wxFontEncoding +{ + wxFONTENCODING_SYSTEM = -1, // system default + wxFONTENCODING_DEFAULT, // current default encoding + + // ISO8859 standard defines a number of single-byte charsets + wxFONTENCODING_ISO8859_1, // West European (Latin1) + wxFONTENCODING_ISO8859_2, // Central and East European (Latin2) + wxFONTENCODING_ISO8859_3, // Esperanto (Latin3) + wxFONTENCODING_ISO8859_4, // Baltic (old) (Latin4) + wxFONTENCODING_ISO8859_5, // Cyrillic + wxFONTENCODING_ISO8859_6, // Arabic + wxFONTENCODING_ISO8859_7, // Greek + wxFONTENCODING_ISO8859_8, // Hebrew + wxFONTENCODING_ISO8859_9, // Turkish (Latin5) + wxFONTENCODING_ISO8859_10, // Variation of Latin4 (Latin6) + wxFONTENCODING_ISO8859_11, // Thai + wxFONTENCODING_ISO8859_12, // doesn't exist currently, but put it + // here anyhow to make all ISO8859 + // consecutive numbers + wxFONTENCODING_ISO8859_13, // Baltic (Latin7) + wxFONTENCODING_ISO8859_14, // Latin8 + wxFONTENCODING_ISO8859_15, // Latin9 (a.k.a. Latin0, includes euro) + wxFONTENCODING_ISO8859_MAX, + + // Cyrillic charset soup (see http://czyborra.com/charsets/cyrillic.html) + wxFONTENCODING_KOI8, // we don't support any of KOI8 variants + wxFONTENCODING_ALTERNATIVE, // same as MS-DOS CP866 + wxFONTENCODING_BULGARIAN, // used under Linux in Bulgaria + + // what would we do without Microsoft? They have their own encodings + // for DOS + wxFONTENCODING_CP437, // original MS-DOS codepage + wxFONTENCODING_CP850, // CP437 merged with Latin1 + wxFONTENCODING_CP852, // CP437 merged with Latin2 + wxFONTENCODING_CP855, // another cyrillic encoding + wxFONTENCODING_CP866, // and another one + // and for Windows + wxFONTENCODING_CP874, // WinThai + wxFONTENCODING_CP1250, // WinLatin2 + wxFONTENCODING_CP1251, // WinCyrillic + wxFONTENCODING_CP1252, // WinLatin1 + wxFONTENCODING_CP1253, // WinGreek (8859-7) + wxFONTENCODING_CP1254, // WinTurkish + wxFONTENCODING_CP1255, // WinHebrew + wxFONTENCODING_CP1256, // WinArabic + wxFONTENCODING_CP1257, // WinBaltic (same as Latin 7) + wxFONTENCODING_CP12_MAX, + + wxFONTENCODING_UTF7, // UTF-7 Unicode encoding + wxFONTENCODING_UTF8, // UTF-8 Unicode encoding + + wxFONTENCODING_UNICODE, // Unicode - currently used only by + // wxEncodingConverter class + + wxFONTENCODING_MAX +}; +\end{verbatim} + \wxheading{Predefined objects} Objects: diff --git a/docs/latex/wx/fontmap.tex b/docs/latex/wx/fontmap.tex index c9460d4a53..fbf85fdf19 100644 --- a/docs/latex/wx/fontmap.tex +++ b/docs/latex/wx/fontmap.tex @@ -31,10 +31,9 @@ for "equivalent" encodings (e.g. iso8859-2 and cp1250) and tries them. If you need to display text in encoding which is not available at host system (see \helpref{IsEncodingAvailable}{wxfontmapperisencodingavailable}), -you may use these two classes to a) find font in some similar encoding +you may use these two classes to find font in some similar encoding (see \helpref{GetAltForEncoding}{wxfontmappergetaltforencoding}) -and -b) convert the text to this encoding +and convert the text to this encoding (\helpref{wxEncodingConverter::Convert}{wxencodingconverterconvert}). Following code snippet demonstrates it: diff --git a/docs/latex/wx/locale.tex b/docs/latex/wx/locale.tex index d4ef2d3254..4f529eb69a 100644 --- a/docs/latex/wx/locale.tex +++ b/docs/latex/wx/locale.tex @@ -438,6 +438,26 @@ Returns current platform-specific locale name as passed to setlocale(). Compare \helpref{GetCanonicalName}{wxlocalegetcanonicalname}. +\membersection{wxLocale::GetSystemEncoding}\label{wxlocalegetsystemencoding} + +\constfunc{static wxFontEncoding}{GetSystemEncoding}{\void} + +Tries to detect the user's default font encoding. +Returns \helpref{wxFontEncoding}{wxfont} value or +{\bf wxFONTENCODING\_SYSTEM} if it couldn't be determined. + +\membersection{wxLocale::GetSystemEncodingName}\label{wxlocalegetsystemencodingname} + +\constfunc{static wxString}{GetSystemEncodingName}{\void} + +Tries to detect the name of the user's default font encoding. This string isn't +particularly useful for the application as its form is platform-dependent and +so you should probably use +\helpref{GetSystemEncoding}{wxlocalegetsystemencoding} instead. + +Returns a user-readable string value or an empty string if it couldn't be +determined. + \membersection{wxLocale::GetSystemLanguage}\label{wxlocalegetsystemlanguage} \constfunc{static int}{GetSystemLanguage}{\void} diff --git a/include/wx/intl.h b/include/wx/intl.h index aaf724eacd..a8e8233277 100644 --- a/include/wx/intl.h +++ b/include/wx/intl.h @@ -9,8 +9,8 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// -#ifndef __INTLH__ -#define __INTLH__ +#ifndef _WX_INTL_H_ +#define _WX_INTL_H_ #ifdef __GNUG__ #pragma interface "intl.h" @@ -21,6 +21,8 @@ #if wxUSE_INTL +#include "wx/fontenc.h" + // ============================================================================ // global decls // ============================================================================ @@ -301,8 +303,6 @@ enum wxLanguage // --- --- --- generated code ends here --- --- --- - - // ---------------------------------------------------------------------------- // wxLanguageInfo: encapsulates wxLanguage to OS native lang.desc. // translation information @@ -313,8 +313,9 @@ struct WXDLLEXPORT wxLanguageInfo int Language; // wxLanguage id wxString CanonicalName; // Canonical name, e.g. fr_FR #ifdef __WIN32__ - wxUint32 WinLang, WinSublang; // Win32 language identifiers -#endif + wxUint32 WinLang, // Win32 language identifiers + WinSublang; +#endif // __WIN32__ wxString Description; // human-readable name of the language }; @@ -329,7 +330,6 @@ enum wxLocaleInitFlags wxLOCALE_CONV_ENCODING = 0x0002 // convert encoding on the fly? }; - class WXDLLEXPORT wxLocale { public: @@ -370,6 +370,14 @@ public: // Return wxLANGUAGE_UNKNOWN if language-guessing algorithm failed static int GetSystemLanguage(); + // get the encoding used by default for text on this system, returns + // wxFONTENCODING_SYSTEM if it couldn't be determined + static wxFontEncoding GetSystemEncoding(); + + // get the string describing the system encoding, return empty string if + // couldn't be determined + static wxString GetSystemEncodingName(); + // return TRUE if the locale was set successfully bool IsOk() const { return m_pszOldLocale != NULL; } @@ -492,5 +500,5 @@ inline const wxChar *wxGetTranslation(const wxChar *sz) { return sz; } #define gettext_noop(str) _T(str) #endif -#endif - // _WX_INTLH__ +#endif // _WX_INTL_H_ + diff --git a/include/wx/strconv.h b/include/wx/strconv.h index 92d5729370..9ed3790af0 100644 --- a/include/wx/strconv.h +++ b/include/wx/strconv.h @@ -23,6 +23,7 @@ #if defined(__VISAGECPP__) && __IBMCPP__ >= 400 # undef __BSEXCPT__ #endif + #include #if wxUSE_WCHAR_T @@ -133,6 +134,8 @@ public: private: void SetName(const wxChar *charset); + // note that we can't use wxString here because of compilation + // dependencies: we're included from wx/string.h wxChar *m_name; wxCharacterSet *m_cset; bool m_deferred; diff --git a/samples/console/console.cpp b/samples/console/console.cpp index c89655a181..6af976b9fe 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -39,7 +39,7 @@ //#define TEST_CHARSET //#define TEST_CMDLINE //#define TEST_DATETIME -#define TEST_DIR +//#define TEST_DIR //#define TEST_DLLLOADER //#define TEST_ENVIRON //#define TEST_EXECUTE @@ -50,7 +50,7 @@ //#define TEST_HASH //#define TEST_INFO_FUNCTIONS //#define TEST_LIST -//#define TEST_LOCALE +#define TEST_LOCALE //#define TEST_LOG //#define TEST_LONGLONG //#define TEST_MIME @@ -1173,11 +1173,19 @@ static void TestDefaultLang() _T("klingonese"), // I bet on some systems it does exist... }; + wxPrintf(_T("The default system encoding is %s (%d)\n"), + wxLocale::GetSystemEncodingName().c_str(), + wxLocale::GetSystemEncoding()); + for ( size_t n = 0; n < WXSIZEOF(langStrings); n++ ) { const char *langStr = langStrings[n]; if ( langStr ) + { + // FIXME: this doesn't do anything at all under Windows, we need + // to create a new wxLocale! wxSetEnv(_T("LC_ALL"), langStr); + } int lang = gs_localeDefault.GetSystemLanguage(); printf("Locale for '%s' is %s.\n", diff --git a/src/common/intl.cpp b/src/common/intl.cpp index c3e563c245..42e01b6274 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: intl.cpp +// Name: src/common/intl.cpp // Purpose: Internationalization and localisation for wxWindows // Author: Vadim Zeitlin // Modified by: @@ -31,27 +31,30 @@ #if wxUSE_INTL // standard headers -#include -#include +#include +#include +#include // wxWindows -#include "wx/defs.h" -#include "wx/string.h" -#include "wx/tokenzr.h" -#include "wx/intl.h" +#ifndef WX_PRECOMP + #include "wx/string.h" + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/debug.h" + #include "wx/utils.h" + #include "wx/dynarray.h" +#endif // WX_PRECOMP + #include "wx/file.h" -#include "wx/log.h" -#include "wx/debug.h" -#include "wx/utils.h" -#include "wx/dynarray.h" +#include "wx/tokenzr.h" #include "wx/module.h" + #ifdef __WIN32__ -#include "wx/msw/private.h" + #include "wx/msw/private.h" +#elif defined(__UNIX_LIKE__) + #include "wx/fontmap.h" // for CharsetToEncoding() #endif - -#include - // ---------------------------------------------------------------------------- // simple types // ---------------------------------------------------------------------------- @@ -930,6 +933,87 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) return wxLANGUAGE_UNKNOWN; } +// ---------------------------------------------------------------------------- +// encoding stuff +// ---------------------------------------------------------------------------- + +// this is a bit strange as under Windows we get the encoding name using its +// numeric value and under Unix we do it the other way round, but this just +// reflects the way different systems provide he encoding info + +/* static */ +wxString wxLocale::GetSystemEncodingName() +{ + wxString encname; + +#ifdef __WIN32__ + // FIXME: what is the error return value for GetACP()? + UINT codepage = ::GetACP(); + encname.Printf(_T("cp%u"), codepage); +#elif defined(__UNIX_LIKE__) + +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + // GNU libc provides current character set this way (this conforms + // to Unix98) + char *alang = nl_langinfo(CODESET); + if (alang) + { + encname = wxConvLibc.cMB2WX(alang); + } + else +#endif // HAVE_LANGINFO_H + { + // if we can't get at the character set directly, try to see if it's in + // the environment variables (in most cases this won't work, but I was + // out of ideas) + wxChar *lang = wxGetenv(wxT("LC_ALL")); + wxChar *dot = lang ? wxStrchr(lang, wxT('.')) : (wxChar *)NULL; + if (!dot) + { + lang = wxGetenv(wxT("LC_CTYPE")); + if ( lang ) + dot = wxStrchr(lang, wxT('.')); + } + if (!dot) + { + lang = wxGetenv(wxT("LANG")); + if ( lang ) + dot = wxStrchr(lang, wxT('.')); + } + + if ( dot ) + { + encname = dot+1; + } + } +#endif // Win32/Unix + + return encname; +} + +/* static */ +wxFontEncoding wxLocale::GetSystemEncoding() +{ +#ifdef __WIN32__ + UINT codepage = ::GetACP(); + + // wxWindows only knows about CP1250-1257 + if ( codepage >= 1250 && codepage <= 1257 ) + { + return (wxFontEncoding)(wxFONTENCODING_CP1250 + codepage - 1250); + } +#elif defined(__UNIX_LIKE__) + wxString encname = GetSystemEncodingName(); + if ( !encname.empty() ) + { + return wxFontMapper::CharsetToEncoding(encname, + FALSE /* not interactive */); + } +#endif // Win32/Unix + + return wxFONTENCODING_SYSTEM; +} + /*static*/ void wxLocale::AddLanguage(const wxLanguageInfo& info) { CreateLanguagesDB(); diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index 1b69297e1d..33b934ef9f 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -93,18 +93,18 @@ WXDLLEXPORT_DATA(wxMBConv *) wxConvCurrent = &wxConvLibc; static size_t encode_utf16(wxUint32 input,wxUint16*output) { - if (input<=0xffff) + if (input<=0xffff) { if (output) *output++ = input; return 1; - } - else if (input>=0x110000) + } + else if (input>=0x110000) { return (size_t)-1; - } - else + } + else { - if (output) + if (output) { *output++ = (input >> 10)+0xd7c0; *output++ = (input&0x3ff)+0xdc00; @@ -115,17 +115,17 @@ static size_t encode_utf16(wxUint32 input,wxUint16*output) static size_t decode_utf16(wxUint16*input,wxUint32&output) { - if ((*input<0xd800) || (*input>0xdfff)) + if ((*input<0xd800) || (*input>0xdfff)) { output = *input; return 1; - } - else if ((input[1]<0xdc00) || (input[1]>=0xdfff)) + } + else if ((input[1]<0xdc00) || (input[1]>=0xdfff)) { output = *input; return (size_t)-1; - } - else + } + else { output = ((input[0] - 0xd7c0) << 10) + (input[1] - 0xdc00); return 2; @@ -209,11 +209,11 @@ WXDLLEXPORT_DATA(wxMBConvGdk) wxConvGdk; size_t wxMBConvGdk::MB2WC(wchar_t *buf, const char *psz, size_t n) const { - if (buf) + if (buf) { return gdk_mbstowcs((GdkWChar *)buf, psz, n); - } - else + } + else { GdkWChar *nbuf = new GdkWChar[n=strlen(psz)]; size_t len = gdk_mbstowcs(nbuf, psz, n); @@ -226,12 +226,12 @@ size_t wxMBConvGdk::WC2MB(char *buf, const wchar_t *psz, size_t n) const { char *mbstr = gdk_wcstombs((GdkWChar *)psz); size_t len = mbstr ? strlen(mbstr) : 0; - if (buf) + if (buf) { - if (len > n) + if (len > n) len = n; memcpy(buf, psz, len); - if (len < n) + if (len < n) buf[len] = 0; } return len; @@ -276,49 +276,49 @@ size_t wxMBConvUTF7::WC2MB(char * WXUNUSED(buf), WXDLLEXPORT_DATA(wxMBConvUTF8) wxConvUTF8; -static wxUint32 utf8_max[]= +static wxUint32 utf8_max[]= { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff, 0xffffffff }; size_t wxMBConvUTF8::MB2WC(wchar_t *buf, const char *psz, size_t n) const { size_t len = 0; - while (*psz && ((!buf) || (len < n))) + while (*psz && ((!buf) || (len < n))) { unsigned char cc = *psz++, fc = cc; unsigned cnt; - for (cnt = 0; fc & 0x80; cnt++) + for (cnt = 0; fc & 0x80; cnt++) fc <<= 1; - if (!cnt) + if (!cnt) { // plain ASCII char - if (buf) + if (buf) *buf++ = cc; len++; - } - else + } + else { cnt--; - if (!cnt) + if (!cnt) { // invalid UTF-8 sequence return (size_t)-1; - } - else + } + else { unsigned ocnt = cnt - 1; wxUint32 res = cc & (0x3f >> cnt); - while (cnt--) + while (cnt--) { cc = *psz++; - if ((cc & 0xC0) != 0x80) + if ((cc & 0xC0) != 0x80) { // invalid UTF-8 sequence return (size_t)-1; } res = (res << 6) | (cc & 0x3f); } - if (res <= utf8_max[ocnt]) + if (res <= utf8_max[ocnt]) { // illegal UTF-8 encoding return (size_t)-1; @@ -327,18 +327,18 @@ size_t wxMBConvUTF8::MB2WC(wchar_t *buf, const char *psz, size_t n) const size_t pa = encode_utf16(res, buf); if (pa == (size_t)-1) return (size_t)-1; - if (buf) + if (buf) buf += pa; len += pa; #else - if (buf) + if (buf) *buf++ = res; len++; #endif } } } - if (buf && (len < n)) + if (buf && (len < n)) *buf = 0; return len; } @@ -347,7 +347,7 @@ size_t wxMBConvUTF8::WC2MB(char *buf, const wchar_t *psz, size_t n) const { size_t len = 0; - while (*psz && ((!buf) || (len < n))) + while (*psz && ((!buf) || (len < n))) { wxUint32 cc; #ifdef WC_UTF16 @@ -358,18 +358,18 @@ size_t wxMBConvUTF8::WC2MB(char *buf, const wchar_t *psz, size_t n) const #endif unsigned cnt; for (cnt = 0; cc > utf8_max[cnt]; cnt++) {} - if (!cnt) + if (!cnt) { // plain ASCII char - if (buf) + if (buf) *buf++ = cc; len++; - } - - else + } + + else { len += cnt + 1; - if (buf) + if (buf) { *buf++ = (-128 >> cnt) | ((cc >> (cnt * 6)) & (0x3f >> cnt)); while (cnt--) @@ -401,11 +401,11 @@ WXDLLEXPORT_DATA(wxCSConv) wxConvLocal((const wxChar *)NULL); // this should work if M$ Internet Exploiter is installed static long CharsetToCodepage(const wxChar *name) { - if (!name) + if (!name) return GetACP(); - + long CP=-1; - + wxString cn(name); do { wxString path(wxT("MIME\\Database\\Charset\\")); @@ -413,7 +413,7 @@ static long CharsetToCodepage(const wxChar *name) wxRegKey key(wxRegKey::HKCR, path); if (!key.Exists()) continue; - + // two cases: either there's an AliasForCharset string, // or there are Codepage and InternetEncoding dwords. // The InternetEncoding gives us the actual encoding, @@ -421,12 +421,12 @@ static long CharsetToCodepage(const wxChar *name) // use when displaying the data. if (key.HasValue(wxT("InternetEncoding")) && key.QueryValue(wxT("InternetEncoding"), &CP)) break; - + // no encoding, see if it's an alias if (!key.HasValue(wxT("AliasForCharset")) || !key.QueryValue(wxT("AliasForCharset"), cn)) break; } while (1); - + return CP; } #endif @@ -438,7 +438,7 @@ public: : cname(name) {} virtual ~wxCharacterSet() {} - virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) + virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) { return (size_t)-1; } virtual size_t WC2MB(char *buf, const wchar_t *psz, size_t n) { return (size_t)-1; } @@ -453,13 +453,13 @@ class ID_CharSet : public wxCharacterSet public: ID_CharSet(const wxChar *name,wxMBConv *cnv) : wxCharacterSet(name), work(cnv) {} - + size_t MB2WC(wchar_t *buf, const char *psz, size_t n) { return work ? work->MB2WC(buf,psz,n) : (size_t)-1; } - + size_t WC2MB(char *buf, const wchar_t *psz, size_t n) { return work ? work->WC2MB(buf,psz,n) : (size_t)-1; } - + bool usable() { return work!=NULL; } public: @@ -486,21 +486,21 @@ public: class IC_CharSet : public wxCharacterSet { public: - IC_CharSet(const wxChar *name) + IC_CharSet(const wxChar *name) : wxCharacterSet(name) { m2w = iconv_open(WC_NAME, wxConvLibc.cWX2MB(cname)); w2m = iconv_open(wxConvLibc.cWX2MB(cname), WC_NAME); } - + ~IC_CharSet() { - if ( m2w != (iconv_t)-1 ) + if ( m2w != (iconv_t)-1 ) iconv_close(m2w); - if ( w2m != (iconv_t)-1 ) + if ( w2m != (iconv_t)-1 ) iconv_close(w2m); } - + size_t MB2WC(wchar_t *buf, const char *psz, size_t n) { size_t inbuf = strlen(psz); @@ -540,13 +540,13 @@ public: res += 8-(outbuf/SIZEOF_WCHAR_T); } while ((cres==(size_t)-1) && (errno==E2BIG)); } - + if (ICONV_FAILED(cres, inbuf)) return (size_t)-1; return res; } - + size_t WC2MB(char *buf, const wchar_t *psz, size_t n) { #if defined(__BORLANDC__) && (__BORLANDC__ > 0x530) @@ -598,13 +598,13 @@ public: #endif if (ICONV_FAILED(cres, inbuf)) return (size_t)-1; - + return res; } - + bool usable() { return (m2w != (iconv_t)-1) && (w2m != (iconv_t)-1); } - + public: iconv_t m2w, w2m; }; @@ -614,23 +614,23 @@ public: class CP_CharSet : public wxCharacterSet { public: - CP_CharSet(const wxChar*name) + CP_CharSet(const wxChar*name) : wxCharacterSet(name), CodePage(CharsetToCodepage(name)) {} - + size_t MB2WC(wchar_t *buf, const char *psz, size_t n) { - size_t len = + size_t len = MultiByteToWideChar(CodePage, 0, psz, -1, buf, buf ? n : 0); return len ? len : (size_t)-1; } - + size_t WC2MB(char *buf, const wchar_t *psz, size_t n) { size_t len = WideCharToMultiByte(CodePage, 0, psz, -1, buf, buf ? n : 0, NULL, NULL); return len ? len : (size_t)-1; } - + bool usable() { return CodePage != -1; } @@ -644,7 +644,7 @@ class EC_CharSet : public wxCharacterSet public: // temporarily just use wxEncodingConverter stuff, // so that it works while a better implementation is built - EC_CharSet(const wxChar*name) : wxCharacterSet(name), + EC_CharSet(const wxChar*name) : wxCharacterSet(name), enc(wxFONTENCODING_SYSTEM) { if (name) @@ -652,15 +652,15 @@ public: m2w.Init(enc, wxFONTENCODING_UNICODE); w2m.Init(wxFONTENCODING_UNICODE, enc); } - + size_t MB2WC(wchar_t *buf, const char *psz, size_t n) { size_t inbuf = strlen(psz); - if (buf) + if (buf) m2w.Convert(psz,buf); return inbuf; } - + size_t WC2MB(char *buf, const wchar_t *psz, size_t n) { #if defined(__BORLANDC__) && (__BORLANDC__ > 0x530) @@ -670,10 +670,10 @@ public: #endif if (buf) w2m.Convert(psz,buf); - + return inbuf; } - + bool usable() { return (enc!=wxFONTENCODING_SYSTEM) && (enc!=wxFONTENCODING_DEFAULT); } @@ -698,17 +698,26 @@ static wxCharacterSet *wxGetCharacterSet(const wxChar *name) #endif } } - + if (cset && cset->usable()) return cset; - if (cset) delete cset; - cset = NULL; + if (cset) + { + delete cset; + cset = NULL; + } + #ifdef __WIN32__ cset = new CP_CharSet(name); // may take NULL - if (cset->usable()) return cset; -#endif - if (cset) delete cset; + if (cset->usable()) + return cset; + + delete cset; +#endif // __WIN32__ + cset = new EC_CharSet(name); - if (cset->usable()) return cset; + if (cset->usable()) + return cset; + delete cset; wxLogError(_("Unknown encoding '%s'!"), name); return NULL; @@ -716,16 +725,15 @@ static wxCharacterSet *wxGetCharacterSet(const wxChar *name) wxCSConv::wxCSConv(const wxChar *charset) { - m_name = (wxChar *) NULL; + m_name = (wxChar *)NULL; m_cset = (wxCharacterSet *) NULL; - m_deferred = TRUE; SetName(charset); } wxCSConv::~wxCSConv() { - if (m_name) free(m_name); - if (m_cset) delete m_cset; + free(m_name); + delete m_cset; } void wxCSConv::SetName(const wxChar *charset) @@ -741,39 +749,13 @@ void wxCSConv::LoadNow() { if (m_deferred) { - if (!m_name) + if ( !m_name ) { -#ifdef __UNIX__ -#if defined(HAVE_LANGINFO_H) && defined(CODESET) - // GNU libc provides current character set this way - char *alang = nl_langinfo(CODESET); - if (alang) - { - SetName(wxConvLibc.cMB2WX(alang)); - } - else -#endif - { - // if we can't get at the character set directly, - // try to see if it's in the environment variables - // (in most cases this won't work, but I was out of ideas) - wxChar *lang = wxGetenv(wxT("LC_ALL")); - wxChar *dot = lang ? wxStrchr(lang, wxT('.')) : (wxChar *)NULL; - if (!dot) - { - lang = wxGetenv(wxT("LC_CTYPE")); - dot = lang ? wxStrchr(lang, wxT('.')) : (wxChar *)NULL; - } - if (!dot) - { - lang = wxGetenv(wxT("LANG")); - dot = lang ? wxStrchr(lang, wxT('.')) : (wxChar *)NULL; - } - if (dot) - SetName(dot+1); - } -#endif + wxString name = wxLocale::GetSystemEncodingName(); + if ( !name.empty() ) + SetName(name); } + m_cset = wxGetCharacterSet(m_name); m_deferred = FALSE; } @@ -782,26 +764,26 @@ void wxCSConv::LoadNow() size_t wxCSConv::MB2WC(wchar_t *buf, const char *psz, size_t n) const { ((wxCSConv *)this)->LoadNow(); // discard constness - + if (m_cset) return m_cset->MB2WC(buf, psz, n); // latin-1 (direct) size_t len = strlen(psz); - + if (buf) { for (size_t c = 0; c <= len; c++) buf[c] = (unsigned char)(psz[c]); } - + return len; } size_t wxCSConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const { ((wxCSConv *)this)->LoadNow(); // discard constness - + if (m_cset) return m_cset->WC2MB(buf, psz, n); @@ -816,26 +798,27 @@ size_t wxCSConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const for (size_t c = 0; c <= len; c++) buf[c] = (psz[c] > 0xff) ? '?' : psz[c]; } - + return len; } #ifdef HAVE_ICONV_H + class IC_CharSetConverter { public: IC_CharSetConverter(IC_CharSet *from, IC_CharSet *to) { - cnv = iconv_open(wxConvLibc.cWX2MB(to->cname), - wxConvLibc.cWX2MB(from->cname)); + cnv = iconv_open(wxConvLibc.cWX2MB(to->cname), + wxConvLibc.cWX2MB(from->cname)); } - + ~IC_CharSetConverter() - { - if (cnv != (iconv_t)-1) - iconv_close(cnv); + { + if (cnv != (iconv_t)-1) + iconv_close(cnv); } - + size_t Convert(char *buf, const char *psz, size_t n) { size_t inbuf = strlen(psz); @@ -845,7 +828,7 @@ public: #else size_t res = iconv( cnv, &psz, &inbuf, &buf, &outbuf ); #endif - if (res == (size_t)-1) + if (res == (size_t)-1) return (size_t)-1; return (n - outbuf); } @@ -853,21 +836,22 @@ public: public: iconv_t cnv; }; -#endif + +#endif // HAVE_ICONV_H class EC_CharSetConverter { public: EC_CharSetConverter(EC_CharSet*from,EC_CharSet*to) { cnv.Init(from->enc,to->enc); } - + size_t Convert(char*buf, const char*psz, size_t n) { size_t inbuf = strlen(psz); if (buf) cnv.Convert(psz,buf); return inbuf; } - + public: wxEncodingConverter cnv; }; -- 2.47.2