1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Unicode conversion classes 
   4 // Author:      Ove Kaaven, Robert Roebling, Vadim Zeitlin, Vaclav Slavik 
   8 // Copyright:   (c) 1999 Ove Kaaven, Robert Roebling, Vaclav Slavik 
   9 //              (c) 2000-2003 Vadim Zeitlin 
  10 // Licence:     wxWindows licence 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 // ============================================================================ 
  15 // ============================================================================ 
  17 // ---------------------------------------------------------------------------- 
  19 // ---------------------------------------------------------------------------- 
  21 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  22   #pragma implementation "strconv.h" 
  25 // For compilers that support precompilation, includes "wx.h". 
  26 #include "wx/wxprec.h" 
  37 #include "wx/strconv.h" 
  42     #include "wx/msw/private.h" 
  46     #include "wx/msw/missing.h" 
  57 #if defined(__WIN32__) && !defined(__WXMICROWIN__) 
  58     #define wxHAVE_WIN32_MB2WC 
  59 #endif // __WIN32__ but !__WXMICROWIN__ 
  61 // ---------------------------------------------------------------------------- 
  63 // ---------------------------------------------------------------------------- 
  73 #include "wx/encconv.h" 
  74 #include "wx/fontmap.h" 
  78 #include <ATSUnicode.h> 
  79 #include <TextCommon.h> 
  80 #include <TextEncodingConverter.h> 
  82 #include  "wx/mac/private.h"  // includes mac headers 
  84 // ---------------------------------------------------------------------------- 
  86 // ---------------------------------------------------------------------------- 
  88 #define BSWAP_UCS4(str, len) { unsigned _c; for (_c=0; _c<len; _c++) str[_c]=wxUINT32_SWAP_ALWAYS(str[_c]); } 
  89 #define BSWAP_UTF16(str, len) { unsigned _c; for (_c=0; _c<len; _c++) str[_c]=wxUINT16_SWAP_ALWAYS(str[_c]); } 
  91 #if SIZEOF_WCHAR_T == 4 
  92     #define WC_NAME         "UCS4" 
  93     #define WC_BSWAP         BSWAP_UCS4 
  94     #ifdef WORDS_BIGENDIAN 
  95       #define WC_NAME_BEST  "UCS-4BE" 
  97       #define WC_NAME_BEST  "UCS-4LE" 
  99 #elif SIZEOF_WCHAR_T == 2 
 100     #define WC_NAME         "UTF16" 
 101     #define WC_BSWAP         BSWAP_UTF16 
 103     #ifdef WORDS_BIGENDIAN 
 104       #define WC_NAME_BEST  "UTF-16BE" 
 106       #define WC_NAME_BEST  "UTF-16LE" 
 108 #else // sizeof(wchar_t) != 2 nor 4 
 109     // does this ever happen? 
 110     #error "Unknown sizeof(wchar_t): please report this to wx-dev@lists.wxwindows.org" 
 113 // ============================================================================ 
 115 // ============================================================================ 
 117 // ---------------------------------------------------------------------------- 
 118 // UTF-16 en/decoding to/from UCS-4 
 119 // ---------------------------------------------------------------------------- 
 122 static size_t encode_utf16(wxUint32 input
, wxUint16 
*output
) 
 127             *output 
= (wxUint16
) input
; 
 130     else if (input
>=0x110000) 
 138             *output
++ = (wxUint16
) ((input 
>> 10)+0xd7c0); 
 139             *output 
= (wxUint16
) ((input
&0x3ff)+0xdc00); 
 145 static size_t decode_utf16(const wxUint16
* input
, wxUint32
& output
) 
 147     if ((*input
<0xd800) || (*input
>0xdfff)) 
 152     else if ((input
[1]<0xdc00) || (input
[1]>=0xdfff)) 
 159         output 
= ((input
[0] - 0xd7c0) << 10) + (input
[1] - 0xdc00); 
 165 // ---------------------------------------------------------------------------- 
 167 // ---------------------------------------------------------------------------- 
 169 wxMBConv::~wxMBConv() 
 171     // nothing to do here (necessary for Darwin linking probably) 
 174 const wxWCharBuffer 
wxMBConv::cMB2WC(const char *psz
) const 
 178         // calculate the length of the buffer needed first 
 179         size_t nLen 
= MB2WC(NULL
, psz
, 0); 
 180         if ( nLen 
!= (size_t)-1 ) 
 182             // now do the actual conversion 
 183             wxWCharBuffer 
buf(nLen
); 
 184             nLen 
= MB2WC(buf
.data(), psz
, nLen 
+ 1); // with the trailing NULL 
 185             if ( nLen 
!= (size_t)-1 ) 
 192     wxWCharBuffer 
buf((wchar_t *)NULL
); 
 197 const wxCharBuffer 
wxMBConv::cWC2MB(const wchar_t *pwz
) const 
 201         size_t nLen 
= WC2MB(NULL
, pwz
, 0); 
 202         if ( nLen 
!= (size_t)-1 ) 
 204             wxCharBuffer 
buf(nLen
+3);       // space for a wxUint32 trailing zero 
 205             nLen 
= WC2MB(buf
.data(), pwz
, nLen 
+ 4); 
 206             if ( nLen 
!= (size_t)-1 ) 
 213     wxCharBuffer 
buf((char *)NULL
); 
 218 // ---------------------------------------------------------------------------- 
 220 // ---------------------------------------------------------------------------- 
 222 size_t wxMBConvLibc::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 224     return wxMB2WC(buf
, psz
, n
); 
 227 size_t wxMBConvLibc::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 229     return wxWC2MB(buf
, psz
, n
); 
 232 // ---------------------------------------------------------------------------- 
 234 // ---------------------------------------------------------------------------- 
 237 static char utf7_setD
[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
 238                         "abcdefghijklmnopqrstuvwxyz" 
 239                         "0123456789'(),-./:?"; 
 240 static char utf7_setO
[]="!\"#$%&*;<=>@[]^_`{|}"; 
 241 static char utf7_setB
[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
 242                         "abcdefghijklmnopqrstuvwxyz" 
 246 // TODO: write actual implementations of UTF-7 here 
 247 size_t wxMBConvUTF7::MB2WC(wchar_t * WXUNUSED(buf
), 
 248                            const char * WXUNUSED(psz
), 
 249                            size_t WXUNUSED(n
)) const 
 254 size_t wxMBConvUTF7::WC2MB(char * WXUNUSED(buf
), 
 255                            const wchar_t * WXUNUSED(psz
), 
 256                            size_t WXUNUSED(n
)) const 
 261 // ---------------------------------------------------------------------------- 
 263 // ---------------------------------------------------------------------------- 
 265 static wxUint32 utf8_max
[]= 
 266     { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff, 0xffffffff }; 
 268 size_t wxMBConvUTF8::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 272     while (*psz 
&& ((!buf
) || (len 
< n
))) 
 274         unsigned char cc 
= *psz
++, fc 
= cc
; 
 276         for (cnt 
= 0; fc 
& 0x80; cnt
++) 
 290                 // invalid UTF-8 sequence 
 295                 unsigned ocnt 
= cnt 
- 1; 
 296                 wxUint32 res 
= cc 
& (0x3f >> cnt
); 
 300                     if ((cc 
& 0xC0) != 0x80) 
 302                         // invalid UTF-8 sequence 
 305                     res 
= (res 
<< 6) | (cc 
& 0x3f); 
 307                 if (res 
<= utf8_max
[ocnt
]) 
 309                     // illegal UTF-8 encoding 
 313                 // cast is ok because wchar_t == wxUuint16 if WC_UTF16 
 314                 size_t pa 
= encode_utf16(res
, (wxUint16 
*)buf
); 
 315                 if (pa 
== (size_t)-1) 
 324 #endif // WC_UTF16/!WC_UTF16 
 328     if (buf 
&& (len 
< n
)) 
 333 size_t wxMBConvUTF8::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 337     while (*psz 
&& ((!buf
) || (len 
< n
))) 
 341         // cast is ok for WC_UTF16 
 342         size_t pa 
= decode_utf16((const wxUint16 
*)psz
, cc
); 
 343         psz 
+= (pa 
== (size_t)-1) ? 1 : pa
; 
 345         cc
=(*psz
++) & 0x7fffffff; 
 348         for (cnt 
= 0; cc 
> utf8_max
[cnt
]; cnt
++) {} 
 362                 *buf
++ = (char) ((-128 >> cnt
) | ((cc 
>> (cnt 
* 6)) & (0x3f >> cnt
))); 
 364                     *buf
++ = (char) (0x80 | ((cc 
>> (cnt 
* 6)) & 0x3f)); 
 369     if (buf 
&& (len
<n
)) *buf 
= 0; 
 377 // ---------------------------------------------------------------------------- 
 379 // ---------------------------------------------------------------------------- 
 381 #ifdef WORDS_BIGENDIAN 
 382     #define wxMBConvUTF16straight wxMBConvUTF16BE 
 383     #define wxMBConvUTF16swap     wxMBConvUTF16LE 
 385     #define wxMBConvUTF16swap     wxMBConvUTF16BE 
 386     #define wxMBConvUTF16straight wxMBConvUTF16LE 
 392 // copy 16bit MB to 16bit String 
 393 size_t wxMBConvUTF16straight::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 397     while (*(wxUint16
*)psz 
&& (!buf 
|| len 
< n
)) 
 400             *buf
++ = *(wxUint16
*)psz
; 
 403         psz 
+= sizeof(wxUint16
); 
 405     if (buf 
&& len
<n
)   *buf
=0; 
 411 // copy 16bit String to 16bit MB 
 412 size_t wxMBConvUTF16straight::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 416     while (*psz 
&& (!buf 
|| len 
< n
)) 
 420             *(wxUint16
*)buf 
= *psz
; 
 421             buf 
+= sizeof(wxUint16
); 
 423         len 
+= sizeof(wxUint16
); 
 426     if (buf 
&& len
<=n
-sizeof(wxUint16
))   *(wxUint16
*)buf
=0; 
 432 // swap 16bit MB to 16bit String 
 433 size_t wxMBConvUTF16swap::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 437     while (*(wxUint16
*)psz 
&& (!buf 
|| len 
< n
)) 
 441             ((char *)buf
)[0] = psz
[1]; 
 442             ((char *)buf
)[1] = psz
[0]; 
 446         psz 
+= sizeof(wxUint16
); 
 448     if (buf 
&& len
<n
)   *buf
=0; 
 454 // swap 16bit MB to 16bit String 
 455 size_t wxMBConvUTF16swap::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 459     while (*psz 
&& (!buf 
|| len 
< n
)) 
 463             *buf
++ = ((char*)psz
)[1]; 
 464             *buf
++ = ((char*)psz
)[0]; 
 466         len 
+= sizeof(wxUint16
); 
 469     if (buf 
&& len
<=n
-sizeof(wxUint16
))   *(wxUint16
*)buf
=0; 
 478 // copy 16bit MB to 32bit String 
 479 size_t wxMBConvUTF16straight::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 483     while (*(wxUint16
*)psz 
&& (!buf 
|| len 
< n
)) 
 486         size_t pa
=decode_utf16((wxUint16
*)psz
, cc
); 
 487         if (pa 
== (size_t)-1) 
 493         psz 
+= pa 
* sizeof(wxUint16
); 
 495     if (buf 
&& len
<n
)   *buf
=0; 
 501 // copy 32bit String to 16bit MB 
 502 size_t wxMBConvUTF16straight::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 506     while (*psz 
&& (!buf 
|| len 
< n
)) 
 509         size_t pa
=encode_utf16(*psz
, cc
); 
 511         if (pa 
== (size_t)-1) 
 516             *(wxUint16
*)buf 
= cc
[0]; 
 517             buf 
+= sizeof(wxUint16
); 
 520                 *(wxUint16
*)buf 
= cc
[1]; 
 521                 buf 
+= sizeof(wxUint16
); 
 525         len 
+= pa
*sizeof(wxUint16
); 
 528     if (buf 
&& len
<=n
-sizeof(wxUint16
))   *(wxUint16
*)buf
=0; 
 534 // swap 16bit MB to 32bit String 
 535 size_t wxMBConvUTF16swap::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 539     while (*(wxUint16
*)psz 
&& (!buf 
|| len 
< n
)) 
 543         tmp
[0]=psz
[1];  tmp
[1]=psz
[0]; 
 544         tmp
[2]=psz
[3];  tmp
[3]=psz
[2]; 
 546         size_t pa
=decode_utf16((wxUint16
*)tmp
, cc
); 
 547         if (pa 
== (size_t)-1) 
 554         psz 
+= pa 
* sizeof(wxUint16
); 
 556     if (buf 
&& len
<n
)   *buf
=0; 
 562 // swap 32bit String to 16bit MB 
 563 size_t wxMBConvUTF16swap::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 567     while (*psz 
&& (!buf 
|| len 
< n
)) 
 570         size_t pa
=encode_utf16(*psz
, cc
); 
 572         if (pa 
== (size_t)-1) 
 577             *buf
++ = ((char*)cc
)[1]; 
 578             *buf
++ = ((char*)cc
)[0]; 
 581                 *buf
++ = ((char*)cc
)[3]; 
 582                 *buf
++ = ((char*)cc
)[2]; 
 586         len 
+= pa
*sizeof(wxUint16
); 
 589     if (buf 
&& len
<=n
-sizeof(wxUint16
))   *(wxUint16
*)buf
=0; 
 597 // ---------------------------------------------------------------------------- 
 599 // ---------------------------------------------------------------------------- 
 601 #ifdef WORDS_BIGENDIAN 
 602 #define wxMBConvUTF32straight  wxMBConvUTF32BE 
 603 #define wxMBConvUTF32swap      wxMBConvUTF32LE 
 605 #define wxMBConvUTF32swap      wxMBConvUTF32BE 
 606 #define wxMBConvUTF32straight  wxMBConvUTF32LE 
 610 WXDLLIMPEXP_DATA_BASE(wxMBConvUTF32LE
) wxConvUTF32LE
; 
 611 WXDLLIMPEXP_DATA_BASE(wxMBConvUTF32BE
) wxConvUTF32BE
; 
 616 // copy 32bit MB to 16bit String 
 617 size_t wxMBConvUTF32straight::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 621     while (*(wxUint32
*)psz 
&& (!buf 
|| len 
< n
)) 
 625         size_t pa
=encode_utf16(*(wxUint32
*)psz
, cc
); 
 626         if (pa 
== (size_t)-1) 
 636         psz 
+= sizeof(wxUint32
); 
 638     if (buf 
&& len
<n
)   *buf
=0; 
 644 // copy 16bit String to 32bit MB 
 645 size_t wxMBConvUTF32straight::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 649     while (*psz 
&& (!buf 
|| len 
< n
)) 
 653         // cast is ok for WC_UTF16 
 654         size_t pa 
= decode_utf16((const wxUint16 
*)psz
, cc
); 
 655         if (pa 
== (size_t)-1) 
 660             *(wxUint32
*)buf 
= cc
; 
 661             buf 
+= sizeof(wxUint32
); 
 663         len 
+= sizeof(wxUint32
); 
 667     if (buf 
&& len
<=n
-sizeof(wxUint32
)) 
 675 // swap 32bit MB to 16bit String 
 676 size_t wxMBConvUTF32swap::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 680     while (*(wxUint32
*)psz 
&& (!buf 
|| len 
< n
)) 
 683         tmp
[0] = psz
[3];   tmp
[1] = psz
[2]; 
 684         tmp
[2] = psz
[1];   tmp
[3] = psz
[0]; 
 689         size_t pa
=encode_utf16(*(wxUint32
*)tmp
, cc
); 
 690         if (pa 
== (size_t)-1) 
 700         psz 
+= sizeof(wxUint32
); 
 710 // swap 16bit String to 32bit MB 
 711 size_t wxMBConvUTF32swap::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 715     while (*psz 
&& (!buf 
|| len 
< n
)) 
 719         // cast is ok for WC_UTF16 
 720         size_t pa
=decode_utf16((const wxUint16 
*)psz
, *(wxUint32
*)cc
); 
 721         if (pa 
== (size_t)-1) 
 731         len 
+= sizeof(wxUint32
); 
 735     if (buf 
&& len
<=n
-sizeof(wxUint32
)) 
 744 // copy 32bit MB to 32bit String 
 745 size_t wxMBConvUTF32straight::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 749     while (*(wxUint32
*)psz 
&& (!buf 
|| len 
< n
)) 
 752             *buf
++ = *(wxUint32
*)psz
; 
 754         psz 
+= sizeof(wxUint32
); 
 764 // copy 32bit String to 32bit MB 
 765 size_t wxMBConvUTF32straight::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 769     while (*psz 
&& (!buf 
|| len 
< n
)) 
 773             *(wxUint32
*)buf 
= *psz
; 
 774             buf 
+= sizeof(wxUint32
); 
 777         len 
+= sizeof(wxUint32
); 
 781     if (buf 
&& len
<=n
-sizeof(wxUint32
)) 
 788 // swap 32bit MB to 32bit String 
 789 size_t wxMBConvUTF32swap::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 793     while (*(wxUint32
*)psz 
&& (!buf 
|| len 
< n
)) 
 797             ((char *)buf
)[0] = psz
[3]; 
 798             ((char *)buf
)[1] = psz
[2]; 
 799             ((char *)buf
)[2] = psz
[1]; 
 800             ((char *)buf
)[3] = psz
[0]; 
 804         psz 
+= sizeof(wxUint32
); 
 814 // swap 32bit String to 32bit MB 
 815 size_t wxMBConvUTF32swap::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
 819     while (*psz 
&& (!buf 
|| len 
< n
)) 
 823             *buf
++ = ((char *)psz
)[3]; 
 824             *buf
++ = ((char *)psz
)[2]; 
 825             *buf
++ = ((char *)psz
)[1]; 
 826             *buf
++ = ((char *)psz
)[0]; 
 828         len 
+= sizeof(wxUint32
); 
 832     if (buf 
&& len
<=n
-sizeof(wxUint32
)) 
 842 // ============================================================================ 
 843 // The classes doing conversion using the iconv_xxx() functions 
 844 // ============================================================================ 
 848 // VS: glibc 2.1.3 is broken in that iconv() conversion to/from UCS4 fails with E2BIG 
 849 //     if output buffer is _exactly_ as big as needed. Such case is (unless there's 
 850 //     yet another bug in glibc) the only case when iconv() returns with (size_t)-1 
 851 //     (which means error) and says there are 0 bytes left in the input buffer -- 
 852 //     when _real_ error occurs, bytes-left-in-input buffer is non-zero. Hence, 
 853 //     this alternative test for iconv() failure. 
 854 //     [This bug does not appear in glibc 2.2.] 
 855 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1 
 856 #define ICONV_FAILED(cres, bufLeft) ((cres == (size_t)-1) && \ 
 857                                      (errno != E2BIG || bufLeft != 0)) 
 859 #define ICONV_FAILED(cres, bufLeft)  (cres == (size_t)-1) 
 862 #define ICONV_CHAR_CAST(x)  ((ICONV_CONST char **)(x)) 
 864 // ---------------------------------------------------------------------------- 
 865 // wxMBConv_iconv: encapsulates an iconv character set 
 866 // ---------------------------------------------------------------------------- 
 868 class wxMBConv_iconv 
: public wxMBConv
 
 871     wxMBConv_iconv(const wxChar 
*name
); 
 872     virtual ~wxMBConv_iconv(); 
 874     virtual size_t MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const; 
 875     virtual size_t WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const; 
 878         { return (m2w 
!= (iconv_t
)-1) && (w2m 
!= (iconv_t
)-1); } 
 881     // the iconv handlers used to translate from multibyte to wide char and in 
 882     // the other direction 
 887     // the name (for iconv_open()) of a wide char charset -- if none is 
 888     // available on this machine, it will remain NULL 
 889     static const char *ms_wcCharsetName
; 
 891     // true if the wide char encoding we use (i.e. ms_wcCharsetName) has 
 892     // different endian-ness than the native one 
 893     static bool ms_wcNeedsSwap
; 
 896 const char *wxMBConv_iconv::ms_wcCharsetName 
= NULL
; 
 897 bool wxMBConv_iconv::ms_wcNeedsSwap 
= false; 
 899 wxMBConv_iconv::wxMBConv_iconv(const wxChar 
*name
) 
 901     // Do it the hard way 
 903     for (size_t i 
= 0; i 
< wxStrlen(name
)+1; i
++) 
 904         cname
[i
] = (char) name
[i
]; 
 906     // check for charset that represents wchar_t: 
 907     if (ms_wcCharsetName 
== NULL
) 
 909         ms_wcNeedsSwap 
= false; 
 911         // try charset with explicit bytesex info (e.g. "UCS-4LE"): 
 912         ms_wcCharsetName 
= WC_NAME_BEST
; 
 913         m2w 
= iconv_open(ms_wcCharsetName
, cname
); 
 915         if (m2w 
== (iconv_t
)-1) 
 917             // try charset w/o bytesex info (e.g. "UCS4") 
 918             // and check for bytesex ourselves: 
 919             ms_wcCharsetName 
= WC_NAME
; 
 920             m2w 
= iconv_open(ms_wcCharsetName
, cname
); 
 922             // last bet, try if it knows WCHAR_T pseudo-charset 
 923             if (m2w 
== (iconv_t
)-1) 
 925                 ms_wcCharsetName 
= "WCHAR_T"; 
 926                 m2w 
= iconv_open(ms_wcCharsetName
, cname
); 
 929             if (m2w 
!= (iconv_t
)-1) 
 931                 char    buf
[2], *bufPtr
; 
 932                 wchar_t wbuf
[2], *wbufPtr
; 
 940                 outsz 
= SIZEOF_WCHAR_T 
* 2; 
 944                 res 
= iconv(m2w
, ICONV_CHAR_CAST(&bufPtr
), &insz
, 
 945                             (char**)&wbufPtr
, &outsz
); 
 947                 if (ICONV_FAILED(res
, insz
)) 
 949                     ms_wcCharsetName 
= NULL
; 
 950                     wxLogLastError(wxT("iconv")); 
 951                     wxLogError(_("Conversion to charset '%s' doesn't work."), name
); 
 955                     ms_wcNeedsSwap 
= wbuf
[0] != (wchar_t)buf
[0]; 
 960                 ms_wcCharsetName 
= NULL
; 
 962                 // VS: we must not output an error here, since wxWidgets will safely 
 963                 //     fall back to using wxEncodingConverter. 
 964                 wxLogTrace(wxT("strconv"), wxT("Impossible to convert to/from charset '%s' with iconv, falling back to wxEncodingConverter."), name
); 
 968         wxLogTrace(wxT("strconv"), wxT("wchar_t charset is '%s', needs swap: %i"), ms_wcCharsetName
, ms_wcNeedsSwap
); 
 970     else // we already have ms_wcCharsetName 
 972         m2w 
= iconv_open(ms_wcCharsetName
, cname
); 
 975     // NB: don't ever pass NULL to iconv_open(), it may crash! 
 976     if ( ms_wcCharsetName 
) 
 978         w2m 
= iconv_open( cname
, ms_wcCharsetName
); 
 986 wxMBConv_iconv::~wxMBConv_iconv() 
 988     if ( m2w 
!= (iconv_t
)-1 ) 
 990     if ( w2m 
!= (iconv_t
)-1 ) 
 994 size_t wxMBConv_iconv::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
 996     size_t inbuf 
= strlen(psz
); 
 997     size_t outbuf 
= n 
* SIZEOF_WCHAR_T
; 
 999     // VS: Use these instead of psz, buf because iconv() modifies its arguments: 
1000     wchar_t *bufPtr 
= buf
; 
1001     const char *pszPtr 
= psz
; 
1005         // have destination buffer, convert there 
1007                      ICONV_CHAR_CAST(&pszPtr
), &inbuf
, 
1008                      (char**)&bufPtr
, &outbuf
); 
1009         res 
= n 
- (outbuf 
/ SIZEOF_WCHAR_T
); 
1013             // convert to native endianness 
1014             WC_BSWAP(buf 
/* _not_ bufPtr */, res
) 
1017         // NB: iconv was given only strlen(psz) characters on input, and so 
1018         //     it couldn't convert the trailing zero. Let's do it ourselves 
1019         //     if there's some room left for it in the output buffer. 
1025         // no destination buffer... convert using temp buffer 
1026         // to calculate destination buffer requirement 
1031             outbuf 
= 8*SIZEOF_WCHAR_T
; 
1034                          ICONV_CHAR_CAST(&pszPtr
), &inbuf
, 
1035                          (char**)&bufPtr
, &outbuf 
); 
1037             res 
+= 8-(outbuf
/SIZEOF_WCHAR_T
); 
1038         } while ((cres
==(size_t)-1) && (errno
==E2BIG
)); 
1041     if (ICONV_FAILED(cres
, inbuf
)) 
1043         //VS: it is ok if iconv fails, hence trace only 
1044         wxLogTrace(wxT("strconv"), wxT("iconv failed: %s"), wxSysErrorMsg(wxSysErrorCode())); 
1051 size_t wxMBConv_iconv::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
1053     size_t inbuf 
= wxWcslen(psz
) * SIZEOF_WCHAR_T
; 
1057     wchar_t *tmpbuf 
= 0; 
1061         // need to copy to temp buffer to switch endianness 
1062         // this absolutely doesn't rock! 
1063         // (no, doing WC_BSWAP twice on the original buffer won't help, as it 
1064         //  could be in read-only memory, or be accessed in some other thread) 
1065         tmpbuf
=(wchar_t*)malloc((inbuf
+1)*SIZEOF_WCHAR_T
); 
1066         memcpy(tmpbuf
,psz
,(inbuf
+1)*SIZEOF_WCHAR_T
); 
1067         WC_BSWAP(tmpbuf
, inbuf
) 
1073         // have destination buffer, convert there 
1074         cres 
= iconv( w2m
, ICONV_CHAR_CAST(&psz
), &inbuf
, &buf
, &outbuf 
); 
1078         // NB: iconv was given only wcslen(psz) characters on input, and so 
1079         //     it couldn't convert the trailing zero. Let's do it ourselves 
1080         //     if there's some room left for it in the output buffer. 
1086         // no destination buffer... convert using temp buffer 
1087         // to calculate destination buffer requirement 
1091             buf 
= tbuf
; outbuf 
= 16; 
1093             cres 
= iconv( w2m
, ICONV_CHAR_CAST(&psz
), &inbuf
, &buf
, &outbuf 
); 
1096         } while ((cres
==(size_t)-1) && (errno
==E2BIG
)); 
1104     if (ICONV_FAILED(cres
, inbuf
)) 
1106         //VS: it is ok if iconv fails, hence trace only 
1107         wxLogTrace(wxT("strconv"), wxT("iconv failed: %s"), wxSysErrorMsg(wxSysErrorCode())); 
1114 #endif // HAVE_ICONV 
1117 // ============================================================================ 
1118 // Win32 conversion classes 
1119 // ============================================================================ 
1121 #ifdef wxHAVE_WIN32_MB2WC 
1125 extern WXDLLIMPEXP_BASE 
long wxCharsetToCodepage(const wxChar 
*charset
); 
1126 extern WXDLLIMPEXP_BASE 
long wxEncodingToCodepage(wxFontEncoding encoding
); 
1129 class wxMBConv_win32 
: public wxMBConv
 
1134         m_CodePage 
= CP_ACP
; 
1138     wxMBConv_win32(const wxChar
* name
) 
1140         m_CodePage 
= wxCharsetToCodepage(name
); 
1143     wxMBConv_win32(wxFontEncoding encoding
) 
1145         m_CodePage 
= wxEncodingToCodepage(encoding
); 
1149     size_t MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
1151         // note that we have to use MB_ERR_INVALID_CHARS flag as it without it 
1152         // the behaviour is not compatible with the Unix version (using iconv) 
1153         // and break the library itself, e.g. wxTextInputStream::NextChar() 
1154         // wouldn't work if reading an incomplete MB char didn't result in an 
1156         const size_t len 
= ::MultiByteToWideChar
 
1158                                 m_CodePage
,     // code page 
1159                                 MB_ERR_INVALID_CHARS
, // flags: fall on error 
1160                                 psz
,            // input string 
1161                                 -1,             // its length (NUL-terminated) 
1162                                 buf
,            // output string 
1163                                 buf 
? n 
: 0     // size of output buffer 
1166         // note that it returns count of written chars for buf != NULL and size 
1167         // of the needed buffer for buf == NULL so in either case the length of 
1168         // the string (which never includes the terminating NUL) is one less 
1169         return len 
? len 
- 1 : (size_t)-1; 
1172     size_t WC2MB(char *buf
, const wchar_t *pwz
, size_t n
) const 
1175             we have a problem here: by default, WideCharToMultiByte() may 
1176             replace characters unrepresentable in the target code page with bad 
1177             quality approximations such as turning "1/2" symbol (U+00BD) into 
1178             "1" for the code pages which don't have it and we, obviously, want 
1179             to avoid this at any price 
1181             the trouble is that this function does it _silently_, i.e. it won't 
1182             even tell us whether it did or not... Win98/2000 and higher provide 
1183             WC_NO_BEST_FIT_CHARS but it doesn't work for the older systems and 
1184             we have to resort to a round trip, i.e. check that converting back 
1185             results in the same string -- this is, of course, expensive but 
1186             otherwise we simply can't be sure to not garble the data. 
1189         // determine if we can rely on WC_NO_BEST_FIT_CHARS: according to MSDN 
1190         // it doesn't work with CJK encodings (which we test for rather roughly 
1191         // here...) nor with UTF-7/8 nor, of course, with Windows versions not 
1193         BOOL usedDef 
wxDUMMY_INITIALIZE(false); 
1196         if ( CanUseNoBestFit() && m_CodePage 
< 50000 ) 
1198             // it's our lucky day 
1199             flags 
= WC_NO_BEST_FIT_CHARS
; 
1200             pUsedDef 
= &usedDef
; 
1202         else // old system or unsupported encoding 
1208         const size_t len 
= ::WideCharToMultiByte
 
1210                                 m_CodePage
,     // code page 
1211                                 flags
,          // either none or no best fit 
1212                                 pwz
,            // input string 
1213                                 -1,             // it is (wide) NUL-terminated 
1214                                 buf
,            // output buffer 
1215                                 buf 
? n 
: 0,    // and its size 
1216                                 NULL
,           // default "replacement" char 
1217                                 pUsedDef        
// [out] was it used? 
1222             // function totally failed 
1226         // if we were really converting, check if we succeeded 
1231                 // check if the conversion failed, i.e. if any replacements 
1236             else // we must resort to double tripping... 
1238                 wxWCharBuffer 
wcBuf(n
); 
1239                 if ( MB2WC(wcBuf
.data(), buf
, n
) == (size_t)-1 || 
1240                         wcscmp(wcBuf
, pwz
) != 0 ) 
1242                     // we didn't obtain the same thing we started from, hence 
1243                     // the conversion was lossy and we consider that it failed 
1249         // see the comment above for the reason of "len - 1" 
1253     bool IsOk() const { return m_CodePage 
!= -1; } 
1256     static bool CanUseNoBestFit() 
1258         static int s_isWin98Or2k 
= -1; 
1260         if ( s_isWin98Or2k 
== -1 ) 
1263             switch ( wxGetOsVersion(&verMaj
, &verMin
) ) 
1266                     s_isWin98Or2k 
= verMaj 
>= 4 && verMin 
>= 10; 
1270                     s_isWin98Or2k 
= verMaj 
>= 5; 
1274                     // unknown, be conseravtive by default 
1278             wxASSERT_MSG( s_isWin98Or2k 
!= -1, _T("should be set above") ); 
1281         return s_isWin98Or2k 
== 1; 
1287 #endif // wxHAVE_WIN32_MB2WC 
1289 // ============================================================================ 
1290 // Cocoa conversion classes 
1291 // ============================================================================ 
1293 #if defined(__WXCOCOA__) 
1295 // RN:  There is no UTF-32 support in either Core Foundation or 
1296 // Cocoa.  Strangely enough, internally Core Foundation uses 
1297 // UTF 32 internally quite a bit - its just not public (yet). 
1299 #include <CoreFoundation/CFString.h> 
1300 #include <CoreFoundation/CFStringEncodingExt.h> 
1302 CFStringEncoding 
wxCFStringEncFromFontEnc(wxFontEncoding encoding
) 
1304     CFStringEncoding enc 
= 0 ; 
1305     if ( encoding 
== wxFONTENCODING_DEFAULT 
) 
1308         encoding 
= wxFont::GetDefaultEncoding() ; 
1310         encoding 
= wxLocale::GetSystemEncoding() ; 
1313     else switch( encoding
) 
1315         case wxFONTENCODING_ISO8859_1 
: 
1316             enc 
= kCFStringEncodingISOLatin1 
; 
1318         case wxFONTENCODING_ISO8859_2 
: 
1319             enc 
= kCFStringEncodingISOLatin2
; 
1321         case wxFONTENCODING_ISO8859_3 
: 
1322             enc 
= kCFStringEncodingISOLatin3 
; 
1324         case wxFONTENCODING_ISO8859_4 
: 
1325             enc 
= kCFStringEncodingISOLatin4
; 
1327         case wxFONTENCODING_ISO8859_5 
: 
1328             enc 
= kCFStringEncodingISOLatinCyrillic
; 
1330         case wxFONTENCODING_ISO8859_6 
: 
1331             enc 
= kCFStringEncodingISOLatinArabic
; 
1333         case wxFONTENCODING_ISO8859_7 
: 
1334             enc 
= kCFStringEncodingISOLatinGreek
; 
1336         case wxFONTENCODING_ISO8859_8 
: 
1337             enc 
= kCFStringEncodingISOLatinHebrew
; 
1339         case wxFONTENCODING_ISO8859_9 
: 
1340             enc 
= kCFStringEncodingISOLatin5
; 
1342         case wxFONTENCODING_ISO8859_10 
: 
1343             enc 
= kCFStringEncodingISOLatin6
; 
1345         case wxFONTENCODING_ISO8859_11 
: 
1346             enc 
= kCFStringEncodingISOLatinThai
; 
1348         case wxFONTENCODING_ISO8859_13 
: 
1349             enc 
= kCFStringEncodingISOLatin7
; 
1351         case wxFONTENCODING_ISO8859_14 
: 
1352             enc 
= kCFStringEncodingISOLatin8
; 
1354         case wxFONTENCODING_ISO8859_15 
: 
1355             enc 
= kCFStringEncodingISOLatin9
; 
1358         case wxFONTENCODING_KOI8 
: 
1359             enc 
= kCFStringEncodingKOI8_R
; 
1361         case wxFONTENCODING_ALTERNATIVE 
: // MS-DOS CP866 
1362             enc 
= kCFStringEncodingDOSRussian
; 
1365 //      case wxFONTENCODING_BULGARIAN : 
1369         case wxFONTENCODING_CP437 
: 
1370             enc 
=kCFStringEncodingDOSLatinUS 
; 
1372         case wxFONTENCODING_CP850 
: 
1373             enc 
= kCFStringEncodingDOSLatin1
; 
1375         case wxFONTENCODING_CP852 
: 
1376             enc 
= kCFStringEncodingDOSLatin2
; 
1378         case wxFONTENCODING_CP855 
: 
1379             enc 
= kCFStringEncodingDOSCyrillic
; 
1381         case wxFONTENCODING_CP866 
: 
1382             enc 
=kCFStringEncodingDOSRussian 
; 
1384         case wxFONTENCODING_CP874 
: 
1385             enc 
= kCFStringEncodingDOSThai
; 
1387         case wxFONTENCODING_CP932 
: 
1388             enc 
= kCFStringEncodingDOSJapanese
; 
1390         case wxFONTENCODING_CP936 
: 
1391             enc 
=kCFStringEncodingDOSChineseSimplif 
; 
1393         case wxFONTENCODING_CP949 
: 
1394             enc 
= kCFStringEncodingDOSKorean
; 
1396         case wxFONTENCODING_CP950 
: 
1397             enc 
= kCFStringEncodingDOSChineseTrad
; 
1400         case wxFONTENCODING_CP1250 
: 
1401             enc 
= kCFStringEncodingWindowsLatin2
; 
1403         case wxFONTENCODING_CP1251 
: 
1404             enc 
=kCFStringEncodingWindowsCyrillic 
; 
1406         case wxFONTENCODING_CP1252 
: 
1407             enc 
=kCFStringEncodingWindowsLatin1 
; 
1409         case wxFONTENCODING_CP1253 
: 
1410             enc 
= kCFStringEncodingWindowsGreek
; 
1412         case wxFONTENCODING_CP1254 
: 
1413             enc 
= kCFStringEncodingWindowsLatin5
; 
1415         case wxFONTENCODING_CP1255 
: 
1416             enc 
=kCFStringEncodingWindowsHebrew 
; 
1418         case wxFONTENCODING_CP1256 
: 
1419             enc 
=kCFStringEncodingWindowsArabic 
; 
1421         case wxFONTENCODING_CP1257 
: 
1422             enc 
= kCFStringEncodingWindowsBalticRim
; 
1424         case wxFONTENCODING_UTF7 
: 
1425             enc 
= kCFStringEncodingNonLossyASCII 
; 
1427         case wxFONTENCODING_UTF8 
: 
1428             enc 
= kCFStringEncodingUTF8 
; 
1430         case wxFONTENCODING_EUC_JP 
: 
1431             enc 
= kCFStringEncodingEUC_JP
; 
1433         case wxFONTENCODING_UTF16 
: 
1434             enc 
= kCFStringEncodingUnicode 
; 
1436         case wxFONTENCODING_MACROMAN 
: 
1437             enc 
= kCFStringEncodingMacRoman 
; 
1439         case wxFONTENCODING_MACJAPANESE 
: 
1440             enc 
= kCFStringEncodingMacJapanese 
; 
1442         case wxFONTENCODING_MACCHINESETRAD 
: 
1443             enc 
= kCFStringEncodingMacChineseTrad 
; 
1445         case wxFONTENCODING_MACKOREAN 
: 
1446             enc 
= kCFStringEncodingMacKorean 
; 
1448         case wxFONTENCODING_MACARABIC 
: 
1449             enc 
= kCFStringEncodingMacArabic 
; 
1451         case wxFONTENCODING_MACHEBREW 
: 
1452             enc 
= kCFStringEncodingMacHebrew 
; 
1454         case wxFONTENCODING_MACGREEK 
: 
1455             enc 
= kCFStringEncodingMacGreek 
; 
1457         case wxFONTENCODING_MACCYRILLIC 
: 
1458             enc 
= kCFStringEncodingMacCyrillic 
; 
1460         case wxFONTENCODING_MACDEVANAGARI 
: 
1461             enc 
= kCFStringEncodingMacDevanagari 
; 
1463         case wxFONTENCODING_MACGURMUKHI 
: 
1464             enc 
= kCFStringEncodingMacGurmukhi 
; 
1466         case wxFONTENCODING_MACGUJARATI 
: 
1467             enc 
= kCFStringEncodingMacGujarati 
; 
1469         case wxFONTENCODING_MACORIYA 
: 
1470             enc 
= kCFStringEncodingMacOriya 
; 
1472         case wxFONTENCODING_MACBENGALI 
: 
1473             enc 
= kCFStringEncodingMacBengali 
; 
1475         case wxFONTENCODING_MACTAMIL 
: 
1476             enc 
= kCFStringEncodingMacTamil 
; 
1478         case wxFONTENCODING_MACTELUGU 
: 
1479             enc 
= kCFStringEncodingMacTelugu 
; 
1481         case wxFONTENCODING_MACKANNADA 
: 
1482             enc 
= kCFStringEncodingMacKannada 
; 
1484         case wxFONTENCODING_MACMALAJALAM 
: 
1485             enc 
= kCFStringEncodingMacMalayalam 
; 
1487         case wxFONTENCODING_MACSINHALESE 
: 
1488             enc 
= kCFStringEncodingMacSinhalese 
; 
1490         case wxFONTENCODING_MACBURMESE 
: 
1491             enc 
= kCFStringEncodingMacBurmese 
; 
1493         case wxFONTENCODING_MACKHMER 
: 
1494             enc 
= kCFStringEncodingMacKhmer 
; 
1496         case wxFONTENCODING_MACTHAI 
: 
1497             enc 
= kCFStringEncodingMacThai 
; 
1499         case wxFONTENCODING_MACLAOTIAN 
: 
1500             enc 
= kCFStringEncodingMacLaotian 
; 
1502         case wxFONTENCODING_MACGEORGIAN 
: 
1503             enc 
= kCFStringEncodingMacGeorgian 
; 
1505         case wxFONTENCODING_MACARMENIAN 
: 
1506             enc 
= kCFStringEncodingMacArmenian 
; 
1508         case wxFONTENCODING_MACCHINESESIMP 
: 
1509             enc 
= kCFStringEncodingMacChineseSimp 
; 
1511         case wxFONTENCODING_MACTIBETAN 
: 
1512             enc 
= kCFStringEncodingMacTibetan 
; 
1514         case wxFONTENCODING_MACMONGOLIAN 
: 
1515             enc 
= kCFStringEncodingMacMongolian 
; 
1517         case wxFONTENCODING_MACETHIOPIC 
: 
1518             enc 
= kCFStringEncodingMacEthiopic 
; 
1520         case wxFONTENCODING_MACCENTRALEUR 
: 
1521             enc 
= kCFStringEncodingMacCentralEurRoman 
; 
1523         case wxFONTENCODING_MACVIATNAMESE 
: 
1524             enc 
= kCFStringEncodingMacVietnamese 
; 
1526         case wxFONTENCODING_MACARABICEXT 
: 
1527             enc 
= kCFStringEncodingMacExtArabic 
; 
1529         case wxFONTENCODING_MACSYMBOL 
: 
1530             enc 
= kCFStringEncodingMacSymbol 
; 
1532         case wxFONTENCODING_MACDINGBATS 
: 
1533             enc 
= kCFStringEncodingMacDingbats 
; 
1535         case wxFONTENCODING_MACTURKISH 
: 
1536             enc 
= kCFStringEncodingMacTurkish 
; 
1538         case wxFONTENCODING_MACCROATIAN 
: 
1539             enc 
= kCFStringEncodingMacCroatian 
; 
1541         case wxFONTENCODING_MACICELANDIC 
: 
1542             enc 
= kCFStringEncodingMacIcelandic 
; 
1544         case wxFONTENCODING_MACROMANIAN 
: 
1545             enc 
= kCFStringEncodingMacRomanian 
; 
1547         case wxFONTENCODING_MACCELTIC 
: 
1548             enc 
= kCFStringEncodingMacCeltic 
; 
1550         case wxFONTENCODING_MACGAELIC 
: 
1551             enc 
= kCFStringEncodingMacGaelic 
; 
1553 //      case wxFONTENCODING_MACKEYBOARD : 
1554 //          enc = kCFStringEncodingMacKeyboardGlyphs ; 
1557             // because gcc is picky 
1563 wxFontEncoding 
wxFontEncFromCFStringEnc(CFStringEncoding encoding
) 
1565     wxFontEncoding enc 
= wxFONTENCODING_DEFAULT 
; 
1569         case kCFStringEncodingISOLatin1  
: 
1570             enc 
= wxFONTENCODING_ISO8859_1 
; 
1572         case kCFStringEncodingISOLatin2 
: 
1573             enc 
= wxFONTENCODING_ISO8859_2
; 
1575         case kCFStringEncodingISOLatin3 
: 
1576             enc 
= wxFONTENCODING_ISO8859_3 
; 
1578         case kCFStringEncodingISOLatin4 
: 
1579             enc 
= wxFONTENCODING_ISO8859_4
; 
1581         case kCFStringEncodingISOLatinCyrillic 
: 
1582             enc 
= wxFONTENCODING_ISO8859_5
; 
1584         case kCFStringEncodingISOLatinArabic 
: 
1585             enc 
= wxFONTENCODING_ISO8859_6
; 
1587         case kCFStringEncodingISOLatinGreek 
: 
1588             enc 
= wxFONTENCODING_ISO8859_7
; 
1590         case kCFStringEncodingISOLatinHebrew 
: 
1591             enc 
= wxFONTENCODING_ISO8859_8
; 
1593         case kCFStringEncodingISOLatin5 
: 
1594             enc 
= wxFONTENCODING_ISO8859_9
; 
1596         case kCFStringEncodingISOLatin6 
: 
1597             enc 
= wxFONTENCODING_ISO8859_10
; 
1599         case kCFStringEncodingISOLatin7 
: 
1600             enc 
= wxFONTENCODING_ISO8859_13
; 
1602         case kCFStringEncodingISOLatin8 
: 
1603             enc 
= wxFONTENCODING_ISO8859_14
; 
1605         case kCFStringEncodingISOLatin9 
: 
1606             enc 
=wxFONTENCODING_ISO8859_15 
; 
1609         case kCFStringEncodingKOI8_R 
: 
1610             enc 
= wxFONTENCODING_KOI8
; 
1614 //          enc = wxFONTENCODING_BULGARIAN; 
1617         case kCFStringEncodingDOSLatinUS 
: 
1618             enc 
= wxFONTENCODING_CP437
; 
1620         case kCFStringEncodingDOSLatin1 
: 
1621             enc 
= wxFONTENCODING_CP850
; 
1623         case kCFStringEncodingDOSLatin2 
: 
1624             enc 
=wxFONTENCODING_CP852 
; 
1626         case kCFStringEncodingDOSCyrillic 
: 
1627             enc 
= wxFONTENCODING_CP855
; 
1629         case kCFStringEncodingDOSRussian 
: 
1630             enc 
= wxFONTENCODING_CP866
; 
1632         case kCFStringEncodingDOSThai 
: 
1633             enc 
=wxFONTENCODING_CP874 
; 
1635         case kCFStringEncodingDOSJapanese 
: 
1636             enc 
= wxFONTENCODING_CP932
; 
1638         case kCFStringEncodingDOSChineseSimplif 
: 
1639             enc 
= wxFONTENCODING_CP936
; 
1641         case kCFStringEncodingDOSKorean 
: 
1642             enc 
= wxFONTENCODING_CP949
; 
1644         case kCFStringEncodingDOSChineseTrad 
: 
1645             enc 
= wxFONTENCODING_CP950
; 
1648         case kCFStringEncodingWindowsLatin2 
: 
1649             enc 
= wxFONTENCODING_CP1250
; 
1651         case kCFStringEncodingWindowsCyrillic 
: 
1652             enc 
= wxFONTENCODING_CP1251
; 
1654         case kCFStringEncodingWindowsLatin1 
: 
1655             enc 
= wxFONTENCODING_CP1252
; 
1657         case kCFStringEncodingWindowsGreek 
: 
1658             enc 
= wxFONTENCODING_CP1253
; 
1660         case kCFStringEncodingWindowsLatin5 
: 
1661             enc 
= wxFONTENCODING_CP1254
; 
1663         case kCFStringEncodingWindowsHebrew 
: 
1664             enc 
= wxFONTENCODING_CP1255
; 
1666         case kCFStringEncodingWindowsArabic 
: 
1667             enc 
= wxFONTENCODING_CP1256
; 
1669         case kCFStringEncodingWindowsBalticRim 
: 
1670             enc 
=wxFONTENCODING_CP1257 
; 
1672         case kCFStringEncodingEUC_JP 
: 
1673             enc 
= wxFONTENCODING_EUC_JP
; 
1675         case kCFStringEncodingUnicode 
: 
1676             enc 
= wxFONTENCODING_UTF16
; 
1678         case kCFStringEncodingMacRoman 
: 
1679             enc 
= wxFONTENCODING_MACROMAN 
; 
1681         case kCFStringEncodingMacJapanese 
: 
1682             enc 
= wxFONTENCODING_MACJAPANESE 
; 
1684         case kCFStringEncodingMacChineseTrad 
: 
1685             enc 
= wxFONTENCODING_MACCHINESETRAD 
; 
1687         case kCFStringEncodingMacKorean 
: 
1688             enc 
= wxFONTENCODING_MACKOREAN 
; 
1690         case kCFStringEncodingMacArabic 
: 
1691             enc 
=wxFONTENCODING_MACARABIC 
; 
1693         case kCFStringEncodingMacHebrew 
: 
1694             enc 
= wxFONTENCODING_MACHEBREW 
; 
1696         case kCFStringEncodingMacGreek 
: 
1697             enc 
= wxFONTENCODING_MACGREEK 
; 
1699         case kCFStringEncodingMacCyrillic 
: 
1700             enc 
= wxFONTENCODING_MACCYRILLIC 
; 
1702         case kCFStringEncodingMacDevanagari 
: 
1703             enc 
= wxFONTENCODING_MACDEVANAGARI 
; 
1705         case kCFStringEncodingMacGurmukhi 
: 
1706             enc 
= wxFONTENCODING_MACGURMUKHI 
; 
1708         case kCFStringEncodingMacGujarati 
: 
1709             enc 
= wxFONTENCODING_MACGUJARATI 
; 
1711         case kCFStringEncodingMacOriya 
: 
1712             enc 
=wxFONTENCODING_MACORIYA 
; 
1714         case kCFStringEncodingMacBengali 
: 
1715             enc 
=wxFONTENCODING_MACBENGALI 
; 
1717         case kCFStringEncodingMacTamil 
: 
1718             enc 
= wxFONTENCODING_MACTAMIL 
; 
1720         case kCFStringEncodingMacTelugu 
: 
1721             enc 
= wxFONTENCODING_MACTELUGU 
; 
1723         case kCFStringEncodingMacKannada 
: 
1724             enc 
= wxFONTENCODING_MACKANNADA 
; 
1726         case kCFStringEncodingMacMalayalam 
: 
1727             enc 
= wxFONTENCODING_MACMALAJALAM 
; 
1729         case kCFStringEncodingMacSinhalese 
: 
1730             enc 
= wxFONTENCODING_MACSINHALESE 
; 
1732         case kCFStringEncodingMacBurmese 
: 
1733             enc 
= wxFONTENCODING_MACBURMESE 
; 
1735         case kCFStringEncodingMacKhmer 
: 
1736             enc 
= wxFONTENCODING_MACKHMER 
; 
1738         case kCFStringEncodingMacThai 
: 
1739             enc 
= wxFONTENCODING_MACTHAI 
; 
1741         case kCFStringEncodingMacLaotian 
: 
1742             enc 
= wxFONTENCODING_MACLAOTIAN 
; 
1744         case kCFStringEncodingMacGeorgian 
: 
1745             enc 
= wxFONTENCODING_MACGEORGIAN 
; 
1747         case kCFStringEncodingMacArmenian 
: 
1748             enc 
= wxFONTENCODING_MACARMENIAN 
; 
1750         case kCFStringEncodingMacChineseSimp 
: 
1751             enc 
= wxFONTENCODING_MACCHINESESIMP 
; 
1753         case kCFStringEncodingMacTibetan 
: 
1754             enc 
= wxFONTENCODING_MACTIBETAN 
; 
1756         case kCFStringEncodingMacMongolian 
: 
1757             enc 
= wxFONTENCODING_MACMONGOLIAN 
; 
1759         case kCFStringEncodingMacEthiopic 
: 
1760             enc 
= wxFONTENCODING_MACETHIOPIC 
; 
1762         case kCFStringEncodingMacCentralEurRoman
: 
1763             enc 
= wxFONTENCODING_MACCENTRALEUR  
; 
1765         case kCFStringEncodingMacVietnamese
: 
1766             enc 
= wxFONTENCODING_MACVIATNAMESE  
; 
1768         case kCFStringEncodingMacExtArabic 
: 
1769             enc 
= wxFONTENCODING_MACARABICEXT 
; 
1771         case kCFStringEncodingMacSymbol 
: 
1772             enc 
= wxFONTENCODING_MACSYMBOL 
; 
1774         case kCFStringEncodingMacDingbats 
: 
1775             enc 
= wxFONTENCODING_MACDINGBATS 
; 
1777         case kCFStringEncodingMacTurkish 
: 
1778             enc 
= wxFONTENCODING_MACTURKISH 
; 
1780         case kCFStringEncodingMacCroatian 
: 
1781             enc 
= wxFONTENCODING_MACCROATIAN 
; 
1783         case kCFStringEncodingMacIcelandic 
: 
1784             enc 
= wxFONTENCODING_MACICELANDIC 
; 
1786         case kCFStringEncodingMacRomanian 
: 
1787             enc 
= wxFONTENCODING_MACROMANIAN 
; 
1789         case kCFStringEncodingMacCeltic 
: 
1790             enc 
= wxFONTENCODING_MACCELTIC 
; 
1792         case kCFStringEncodingMacGaelic 
: 
1793             enc 
= wxFONTENCODING_MACGAELIC 
; 
1795 //        case kCFStringEncodingMacKeyboardGlyphs : 
1796 //            enc = wxFONTENCODING_MACKEYBOARD ; 
1802 class wxMBConv_cocoa 
: public wxMBConv
 
1807         Init(CFStringGetSystemEncoding()) ; 
1810     wxMBConv_cocoa(const wxChar
* name
) 
1812         Init( wxCFStringEncFromFontEnc(wxFontMapper::Get()->CharsetToEncoding(name
, false) ) ) ; 
1815     wxMBConv_cocoa(wxFontEncoding encoding
) 
1817         Init( wxCFStringEncFromFontEnc(encoding
) ); 
1824     void Init( CFStringEncoding encoding
) 
1826         m_char_encoding 
= encoding 
; 
1827         m_unicode_encoding 
= kCFStringEncodingUnicode
; 
1830     size_t MB2WC(wchar_t * szOut
, const char * szUnConv
, size_t nOutSize
) const 
1834         size_t nBufSize 
= strlen(szUnConv
) + 1; 
1835         size_t nRealOutSize
; 
1837         UniChar
* szUniCharBuffer    
= (UniChar
*) szOut
; 
1838         wchar_t* szConvBuffer       
= szOut
; 
1840         if (szConvBuffer 
== NULL 
&& nOutSize 
!= 0) 
1842             szConvBuffer 
= new wchar_t[nOutSize
] ; 
1845 #if SIZEOF_WCHAR_T == 4 
1846         szUniCharBuffer 
= new UniChar
[nOutSize
]; 
1849         CFDataRef theData 
= CFDataCreateWithBytesNoCopy ( 
1851                                             (const UInt8
*)szUnConv
, 
1858         CFStringRef theString 
= CFStringCreateFromExternalRepresentation ( 
1864         wxASSERT(theString
); 
1868             nRealOutSize 
= CFStringGetLength(theString
) + 1; 
1869             CFRelease(theString
); 
1870             return nRealOutSize 
- 1; 
1873         CFRange theRange 
= { 0, CFStringGetLength(theString
) }; 
1875         CFStringGetCharacters(theString
, theRange
, szUniCharBuffer
); 
1878         nRealOutSize 
= (CFStringGetLength(theString
) + 1); 
1880         CFRelease(theString
); 
1882         szUniCharBuffer
[nRealOutSize
-1] = '\0' ; 
1884 #if SIZEOF_WCHAR_T == 4 
1885         wxMBConvUTF16 converter 
; 
1886         converter
.MB2WC(szConvBuffer  
, (const char*)szUniCharBuffer 
, nRealOutSize 
) ; 
1887         delete[] szUniCharBuffer
; 
1889         if ( szOut 
== NULL 
) 
1890             delete [] szConvBuffer
; 
1892         return nRealOutSize 
; 
1895     size_t WC2MB(char *szOut
, const wchar_t *szUnConv
, size_t nOutSize
) const 
1897         size_t nBufSize 
= wxWcslen(szUnConv
) + 1; 
1898         size_t nRealOutSize
; 
1899         char* szBuffer 
= szOut
; 
1900         UniChar
* szUniBuffer 
= (UniChar
*) szUnConv
; 
1905             nRealOutSize 
= ((nBufSize 
- 1) << 2)+1 ; 
1906             szBuffer 
= new char[ nRealOutSize 
] ; 
1909             nRealOutSize 
= nOutSize
; 
1911 #if SIZEOF_WCHAR_T == 4 
1912         wxMBConvUTF16BE converter 
; 
1913         nBufSize 
= converter
.WC2MB( NULL 
, szUnConv 
, 0 ); 
1914         szUniBuffer 
= new UniChar
[ (nBufSize 
/ sizeof(UniChar
)) + 1] ; 
1915         converter
.WC2MB( (char*) szUniBuffer 
, szUnConv
, nBufSize 
+ sizeof(UniChar
)) ; 
1916         nBufSize 
/= sizeof(UniChar
); 
1920         CFStringRef theString 
= CFStringCreateWithCharactersNoCopy( 
1927         wxASSERT(theString
); 
1929         //Note that CER puts a BOM when converting to unicode 
1930         //so we may want to check and use getchars instead in that case 
1931         CFDataRef theData 
= CFStringCreateExternalRepresentation( 
1935                                 0 //what to put in characters that can't be converted - 
1936                                     //0 tells CFString to return NULL if it meets such a character 
1942         CFRelease(theString
); 
1944         nRealOutSize 
= CFDataGetLength(theData
); 
1946         if ( szOut 
== NULL 
) 
1951 //TODO: This gets flagged as a non-malloced address by the debugger... 
1952 //#if SIZEOF_WCHAR_T == 4 
1953 //        delete[] szUniBuffer; 
1956             return nRealOutSize 
- 1; 
1959         CFRange theRange 
= {0, CFDataGetLength(theData
) }; 
1960         CFDataGetBytes(theData
, theRange
, (UInt8
*) szBuffer
); 
1964 //TODO: This gets flagged as a non-malloced address by the debugger... 
1965 //#if SIZEOF_WCHAR_T == 4 
1966 //        delete[] szUniBuffer; 
1968         return  nRealOutSize 
- 1; 
1973         //TODO: check for invalid en/de/coding 
1978     CFStringEncoding m_char_encoding 
; 
1979     CFStringEncoding m_unicode_encoding 
; 
1982 #endif // defined(__WXCOCOA__) 
1984 // ============================================================================ 
1985 // Mac conversion classes 
1986 // ============================================================================ 
1988 #if defined(__WXMAC__) && defined(TARGET_CARBON) 
1990 class wxMBConv_mac 
: public wxMBConv
 
1995         Init(CFStringGetSystemEncoding()) ; 
1998     wxMBConv_mac(const wxChar
* name
) 
2000         Init( wxMacGetSystemEncFromFontEnc(wxFontMapper::Get()->CharsetToEncoding(name
, false) ) ) ; 
2003     wxMBConv_mac(wxFontEncoding encoding
) 
2005         Init( wxMacGetSystemEncFromFontEnc(encoding
) ); 
2010         OSStatus status 
= noErr 
; 
2011         status 
= TECDisposeConverter(m_MB2WC_converter
); 
2012         status 
= TECDisposeConverter(m_WC2MB_converter
); 
2016     void Init( TextEncodingBase encoding
) 
2018         OSStatus status 
= noErr 
; 
2019         m_char_encoding 
= encoding 
; 
2020         m_unicode_encoding 
= CreateTextEncoding(kTextEncodingUnicodeDefault
,0,kUnicode16BitFormat
) ; 
2022         status 
= TECCreateConverter(&m_MB2WC_converter
, 
2024                                     m_unicode_encoding
); 
2025         status 
= TECCreateConverter(&m_WC2MB_converter
, 
2030     size_t MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
2032         OSStatus status 
= noErr 
; 
2033         ByteCount byteOutLen 
; 
2034         ByteCount byteInLen 
= strlen(psz
) ; 
2035         wchar_t *tbuf 
= NULL 
; 
2036         UniChar
* ubuf 
= NULL 
; 
2042             tbuf 
= (wchar_t*) malloc( n 
* SIZEOF_WCHAR_T
) ; 
2044         ByteCount byteBufferLen 
= n 
* sizeof( UniChar 
) ; 
2045 #if SIZEOF_WCHAR_T == 4 
2046         ubuf 
= (UniChar
*) malloc( byteBufferLen 
+ 2 ) ; 
2048         ubuf 
= (UniChar
*) (buf 
? buf 
: tbuf
) ; 
2050         status 
= TECConvertText(m_MB2WC_converter
, (ConstTextPtr
) psz 
, byteInLen
, &byteInLen
, 
2051           (TextPtr
) ubuf 
, byteBufferLen
, &byteOutLen
); 
2052 #if SIZEOF_WCHAR_T == 4 
2053         // we have to terminate here, because n might be larger for the trailing zero, and if UniChar 
2054         // is not properly terminated we get random characters at the end 
2055         ubuf
[byteOutLen 
/ sizeof( UniChar 
) ] = 0 ; 
2056         wxMBConvUTF16BE converter 
; 
2057         res 
= converter
.MB2WC( (buf 
? buf 
: tbuf
) , (const char*)ubuf 
, n 
) ; 
2060         res 
= byteOutLen 
/ sizeof( UniChar 
) ; 
2065         if ( buf  
&& res 
< n
) 
2071     size_t WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
2073         OSStatus status 
= noErr 
; 
2074         ByteCount byteOutLen 
; 
2075         ByteCount byteInLen 
= wxWcslen(psz
) * SIZEOF_WCHAR_T 
; 
2082             n 
= byteInLen 
<< 1 ; 
2083             tbuf 
= (char*) malloc( n 
) ; 
2086         ByteCount byteBufferLen 
= n 
; 
2087         UniChar
* ubuf 
= NULL 
; 
2088 #if SIZEOF_WCHAR_T == 4 
2089         wxMBConvUTF16BE converter 
; 
2090         size_t unicharlen 
= converter
.WC2MB( NULL 
, psz 
, 0 ) ; 
2091         byteInLen 
= unicharlen 
; 
2092         ubuf 
= (UniChar
*) malloc( byteInLen 
+ 2 ) ; 
2093         converter
.WC2MB( (char*) ubuf 
, psz
, unicharlen 
+ 2 ) ; 
2095         ubuf 
= (UniChar
*) psz 
; 
2097         status 
= TECConvertText(m_WC2MB_converter
, (ConstTextPtr
) ubuf 
, byteInLen
, &byteInLen
, 
2098             (TextPtr
) (buf 
? buf 
: tbuf
) , byteBufferLen
, &byteOutLen
); 
2099 #if SIZEOF_WCHAR_T == 4 
2105         size_t res 
= byteOutLen 
; 
2106         if ( buf  
&& res 
< n
) 
2113         { return m_MB2WC_converter 
!=  NULL 
&& m_WC2MB_converter 
!= NULL  
; } 
2116     TECObjectRef m_MB2WC_converter 
; 
2117     TECObjectRef m_WC2MB_converter 
; 
2119     TextEncodingBase m_char_encoding 
; 
2120     TextEncodingBase m_unicode_encoding 
; 
2123 #endif // defined(__WXMAC__) && defined(TARGET_CARBON) 
2125 // ============================================================================ 
2126 // wxEncodingConverter based conversion classes 
2127 // ============================================================================ 
2131 class wxMBConv_wxwin 
: public wxMBConv
 
2136         m_ok 
= m2w
.Init(m_enc
, wxFONTENCODING_UNICODE
) && 
2137                w2m
.Init(wxFONTENCODING_UNICODE
, m_enc
); 
2141     // temporarily just use wxEncodingConverter stuff, 
2142     // so that it works while a better implementation is built 
2143     wxMBConv_wxwin(const wxChar
* name
) 
2146             m_enc 
= wxFontMapper::Get()->CharsetToEncoding(name
, false); 
2148             m_enc 
= wxFONTENCODING_SYSTEM
; 
2153     wxMBConv_wxwin(wxFontEncoding enc
) 
2160     size_t MB2WC(wchar_t *buf
, const char *psz
, size_t WXUNUSED(n
)) const 
2162         size_t inbuf 
= strlen(psz
); 
2164             m2w
.Convert(psz
,buf
); 
2168     size_t WC2MB(char *buf
, const wchar_t *psz
, size_t WXUNUSED(n
)) const 
2170         const size_t inbuf 
= wxWcslen(psz
); 
2172             w2m
.Convert(psz
,buf
); 
2177     bool IsOk() const { return m_ok
; } 
2180     wxFontEncoding m_enc
; 
2181     wxEncodingConverter m2w
, w2m
; 
2183     // were we initialized successfully? 
2186     DECLARE_NO_COPY_CLASS(wxMBConv_wxwin
) 
2189 #endif // wxUSE_FONTMAP 
2191 // ============================================================================ 
2192 // wxCSConv implementation 
2193 // ============================================================================ 
2195 void wxCSConv::Init() 
2202 wxCSConv::wxCSConv(const wxChar 
*charset
) 
2211     m_encoding 
= wxFONTENCODING_SYSTEM
; 
2214 wxCSConv::wxCSConv(wxFontEncoding encoding
) 
2216     if ( encoding 
== wxFONTENCODING_MAX 
|| encoding 
== wxFONTENCODING_DEFAULT 
) 
2218         wxFAIL_MSG( _T("invalid encoding value in wxCSConv ctor") ); 
2220         encoding 
= wxFONTENCODING_SYSTEM
; 
2225     m_encoding 
= encoding
; 
2228 wxCSConv::~wxCSConv() 
2233 wxCSConv::wxCSConv(const wxCSConv
& conv
) 
2238     SetName(conv
.m_name
); 
2239     m_encoding 
= conv
.m_encoding
; 
2242 wxCSConv
& wxCSConv::operator=(const wxCSConv
& conv
) 
2246     SetName(conv
.m_name
); 
2247     m_encoding 
= conv
.m_encoding
; 
2252 void wxCSConv::Clear() 
2261 void wxCSConv::SetName(const wxChar 
*charset
) 
2265         m_name 
= wxStrdup(charset
); 
2270 wxMBConv 
*wxCSConv::DoCreate() const 
2272     // check for the special case of ASCII or ISO8859-1 charset: as we have 
2273     // special knowledge of it anyhow, we don't need to create a special 
2274     // conversion object 
2275     if ( m_encoding 
== wxFONTENCODING_ISO8859_1 
) 
2277         // don't convert at all 
2281     // we trust OS to do conversion better than we can so try external 
2282     // conversion methods first 
2284     // the full order is: 
2285     //      1. OS conversion (iconv() under Unix or Win32 API) 
2286     //      2. hard coded conversions for UTF 
2287     //      3. wxEncodingConverter as fall back 
2293 #endif // !wxUSE_FONTMAP 
2295         wxString 
name(m_name
); 
2299             name 
= wxFontMapper::Get()->GetEncodingName(m_encoding
); 
2300 #endif // wxUSE_FONTMAP 
2302         wxMBConv_iconv 
*conv 
= new wxMBConv_iconv(name
); 
2308 #endif // HAVE_ICONV 
2310 #ifdef wxHAVE_WIN32_MB2WC 
2313         wxMBConv_win32 
*conv 
= m_name 
? new wxMBConv_win32(m_name
) 
2314                                       : new wxMBConv_win32(m_encoding
); 
2323 #endif // wxHAVE_WIN32_MB2WC 
2324 #if defined(__WXMAC__) 
2326         if ( m_name 
|| ( m_encoding 
< wxFONTENCODING_UTF16BE 
) ) 
2329             wxMBConv_mac 
*conv 
= m_name 
? new wxMBConv_mac(m_name
) 
2330                                         : new wxMBConv_mac(m_encoding
); 
2338 #if defined(__WXCOCOA__) 
2340         if ( m_name 
|| ( m_encoding 
<= wxFONTENCODING_UTF16 
) ) 
2343             wxMBConv_cocoa 
*conv 
= m_name 
? new wxMBConv_cocoa(m_name
) 
2344                                           : new wxMBConv_cocoa(m_encoding
); 
2353     wxFontEncoding enc 
= m_encoding
; 
2355     if ( enc 
== wxFONTENCODING_SYSTEM 
&& m_name 
) 
2357         // use "false" to suppress interactive dialogs -- we can be called from 
2358         // anywhere and popping up a dialog from here is the last thing we want to 
2360         enc 
= wxFontMapper::Get()->CharsetToEncoding(m_name
, false); 
2362 #endif // wxUSE_FONTMAP 
2366         case wxFONTENCODING_UTF7
: 
2367              return new wxMBConvUTF7
; 
2369         case wxFONTENCODING_UTF8
: 
2370              return new wxMBConvUTF8
; 
2372         case wxFONTENCODING_UTF16BE
: 
2373              return new wxMBConvUTF16BE
; 
2375         case wxFONTENCODING_UTF16LE
: 
2376              return new wxMBConvUTF16LE
; 
2378         case wxFONTENCODING_UTF32BE
: 
2379              return new wxMBConvUTF32BE
; 
2381         case wxFONTENCODING_UTF32LE
: 
2382              return new wxMBConvUTF32LE
; 
2385              // nothing to do but put here to suppress gcc warnings 
2392         wxMBConv_wxwin 
*conv 
= m_name 
? new wxMBConv_wxwin(m_name
) 
2393                                       : new wxMBConv_wxwin(m_encoding
); 
2399 #endif // wxUSE_FONTMAP 
2401     // NB: This is a hack to prevent deadlock. What could otherwise happen 
2402     //     in Unicode build: wxConvLocal creation ends up being here 
2403     //     because of some failure and logs the error. But wxLog will try to 
2404     //     attach timestamp, for which it will need wxConvLocal (to convert 
2405     //     time to char* and then wchar_t*), but that fails, tries to log 
2406     //     error, but wxLog has a (already locked) critical section that 
2407     //     guards static buffer. 
2408     static bool alreadyLoggingError 
= false; 
2409     if (!alreadyLoggingError
) 
2411         alreadyLoggingError 
= true; 
2412         wxLogError(_("Cannot convert from the charset '%s'!"), 
2416                          wxFontMapper::GetEncodingDescription(m_encoding
).c_str() 
2417 #else // !wxUSE_FONTMAP 
2418                          wxString::Format(_("encoding %s"), m_encoding
).c_str() 
2419 #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP 
2421         alreadyLoggingError 
= false; 
2427 void wxCSConv::CreateConvIfNeeded() const 
2431         wxCSConv 
*self 
= (wxCSConv 
*)this; // const_cast 
2434         // if we don't have neither the name nor the encoding, use the default 
2435         // encoding for this system 
2436         if ( !m_name 
&& m_encoding 
== wxFONTENCODING_SYSTEM 
) 
2438             self
->m_name 
= wxStrdup(wxLocale::GetSystemEncodingName()); 
2440 #endif // wxUSE_INTL 
2442         self
->m_convReal 
= DoCreate(); 
2443         self
->m_deferred 
= false; 
2447 size_t wxCSConv::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const 
2449     CreateConvIfNeeded(); 
2452         return m_convReal
->MB2WC(buf
, psz
, n
); 
2455     size_t len 
= strlen(psz
); 
2459         for (size_t c 
= 0; c 
<= len
; c
++) 
2460             buf
[c
] = (unsigned char)(psz
[c
]); 
2466 size_t wxCSConv::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const 
2468     CreateConvIfNeeded(); 
2471         return m_convReal
->WC2MB(buf
, psz
, n
); 
2474     const size_t len 
= wxWcslen(psz
); 
2477         for (size_t c 
= 0; c 
<= len
; c
++) 
2481             buf
[c
] = (char)psz
[c
]; 
2486         for (size_t c 
= 0; c 
<= len
; c
++) 
2496 // ---------------------------------------------------------------------------- 
2498 // ---------------------------------------------------------------------------- 
2501     static wxMBConv_win32 wxConvLibcObj
; 
2502 #elif defined(__WXMAC__) && !defined(__MACH__) 
2503     static wxMBConv_mac wxConvLibcObj 
; 
2505     static wxMBConvLibc wxConvLibcObj
; 
2508 static wxCSConv 
wxConvLocalObj(wxFONTENCODING_SYSTEM
); 
2509 static wxCSConv 
wxConvISO8859_1Obj(wxFONTENCODING_ISO8859_1
); 
2510 static wxMBConvUTF7 wxConvUTF7Obj
; 
2511 static wxMBConvUTF8 wxConvUTF8Obj
; 
2514 WXDLLIMPEXP_DATA_BASE(wxMBConv
&) wxConvLibc 
= wxConvLibcObj
; 
2515 WXDLLIMPEXP_DATA_BASE(wxCSConv
&) wxConvLocal 
= wxConvLocalObj
; 
2516 WXDLLIMPEXP_DATA_BASE(wxCSConv
&) wxConvISO8859_1 
= wxConvISO8859_1Obj
; 
2517 WXDLLIMPEXP_DATA_BASE(wxMBConvUTF7
&) wxConvUTF7 
= wxConvUTF7Obj
; 
2518 WXDLLIMPEXP_DATA_BASE(wxMBConvUTF8
&) wxConvUTF8 
= wxConvUTF8Obj
; 
2519 WXDLLIMPEXP_DATA_BASE(wxMBConv 
*) wxConvCurrent 
= &wxConvLibcObj
; 
2521 #else // !wxUSE_WCHAR_T 
2523 // stand-ins in absence of wchar_t 
2524 WXDLLIMPEXP_DATA_BASE(wxMBConv
) wxConvLibc
, 
2529 #endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T