1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Unicode conversion classes
4 // Author: Ove Kaaven, Robert Roebling, Vadim Zeitlin, Vaclav Slavik,
5 // Ryan Norton, Fredrik Roubert (UTF7)
9 // Copyright: (c) 1999 Ove Kaaven, Robert Roebling, Vaclav Slavik
10 // (c) 2000-2003 Vadim Zeitlin
11 // (c) 2004 Ryan Norton, Fredrik Roubert
12 // Licence: wxWindows licence
13 /////////////////////////////////////////////////////////////////////////////
15 // ============================================================================
17 // ============================================================================
19 // ----------------------------------------------------------------------------
21 // ----------------------------------------------------------------------------
23 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
24 #pragma implementation "strconv.h"
27 // For compilers that support precompilation, includes "wx.h".
28 #include "wx/wxprec.h"
39 #include "wx/strconv.h"
44 #include "wx/msw/private.h"
48 #include "wx/msw/missing.h"
59 #if defined(__WIN32__) && !defined(__WXMICROWIN__)
60 #define wxHAVE_WIN32_MB2WC
61 #endif // __WIN32__ but !__WXMICROWIN__
63 // ----------------------------------------------------------------------------
65 // ----------------------------------------------------------------------------
75 #include "wx/encconv.h"
76 #include "wx/fontmap.h"
80 #include <ATSUnicode.h>
81 #include <TextCommon.h>
82 #include <TextEncodingConverter.h>
84 #include "wx/mac/private.h" // includes mac headers
86 // ----------------------------------------------------------------------------
88 // ----------------------------------------------------------------------------
90 #define BSWAP_UCS4(str, len) { unsigned _c; for (_c=0; _c<len; _c++) str[_c]=wxUINT32_SWAP_ALWAYS(str[_c]); }
91 #define BSWAP_UTF16(str, len) { unsigned _c; for (_c=0; _c<len; _c++) str[_c]=wxUINT16_SWAP_ALWAYS(str[_c]); }
93 #if SIZEOF_WCHAR_T == 4
94 #define WC_NAME "UCS4"
95 #define WC_BSWAP BSWAP_UCS4
96 #ifdef WORDS_BIGENDIAN
97 #define WC_NAME_BEST "UCS-4BE"
99 #define WC_NAME_BEST "UCS-4LE"
101 #elif SIZEOF_WCHAR_T == 2
102 #define WC_NAME "UTF16"
103 #define WC_BSWAP BSWAP_UTF16
105 #ifdef WORDS_BIGENDIAN
106 #define WC_NAME_BEST "UTF-16BE"
108 #define WC_NAME_BEST "UTF-16LE"
110 #else // sizeof(wchar_t) != 2 nor 4
111 // does this ever happen?
112 #error "Unknown sizeof(wchar_t): please report this to wx-dev@lists.wxwindows.org"
115 // ============================================================================
117 // ============================================================================
119 // ----------------------------------------------------------------------------
120 // UTF-16 en/decoding to/from UCS-4
121 // ----------------------------------------------------------------------------
124 static size_t encode_utf16(wxUint32 input
, wxUint16
*output
)
129 *output
= (wxUint16
) input
;
132 else if (input
>=0x110000)
140 *output
++ = (wxUint16
) ((input
>> 10)+0xd7c0);
141 *output
= (wxUint16
) ((input
&0x3ff)+0xdc00);
147 static size_t decode_utf16(const wxUint16
* input
, wxUint32
& output
)
149 if ((*input
<0xd800) || (*input
>0xdfff))
154 else if ((input
[1]<0xdc00) || (input
[1]>=0xdfff))
161 output
= ((input
[0] - 0xd7c0) << 10) + (input
[1] - 0xdc00);
167 // ----------------------------------------------------------------------------
169 // ----------------------------------------------------------------------------
171 wxMBConv::~wxMBConv()
173 // nothing to do here (necessary for Darwin linking probably)
176 const wxWCharBuffer
wxMBConv::cMB2WC(const char *psz
) const
180 // calculate the length of the buffer needed first
181 size_t nLen
= MB2WC(NULL
, psz
, 0);
182 if ( nLen
!= (size_t)-1 )
184 // now do the actual conversion
185 wxWCharBuffer
buf(nLen
);
186 nLen
= MB2WC(buf
.data(), psz
, nLen
+ 1); // with the trailing NULL
187 if ( nLen
!= (size_t)-1 )
194 wxWCharBuffer
buf((wchar_t *)NULL
);
199 const wxCharBuffer
wxMBConv::cWC2MB(const wchar_t *pwz
) const
203 size_t nLen
= WC2MB(NULL
, pwz
, 0);
204 if ( nLen
!= (size_t)-1 )
206 wxCharBuffer
buf(nLen
+3); // space for a wxUint32 trailing zero
207 nLen
= WC2MB(buf
.data(), pwz
, nLen
+ 4);
208 if ( nLen
!= (size_t)-1 )
215 wxCharBuffer
buf((char *)NULL
);
220 // ----------------------------------------------------------------------------
222 // ----------------------------------------------------------------------------
224 size_t wxMBConvLibc::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
226 return wxMB2WC(buf
, psz
, n
);
229 size_t wxMBConvLibc::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
231 return wxWC2MB(buf
, psz
, n
);
233 // ----------------------------------------------------------------------------
235 // ----------------------------------------------------------------------------
237 // Implementation (C) 2004 Fredrik Roubert
240 // BASE64 decoding table
242 static const unsigned char utf7unb64
[] =
244 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
245 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
246 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
247 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
248 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
249 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
250 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
251 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
252 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
253 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
254 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
255 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
256 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
257 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
258 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
259 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
260 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
261 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
262 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
263 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
264 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
265 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
266 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
267 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
268 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
269 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
270 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
271 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
272 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
273 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
274 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
275 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
278 size_t wxMBConvUTF7::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
283 while (*psz
&& ((!buf
) || (len
< n
)))
285 unsigned char cc
= *psz
++;
293 else if (*psz
== '-')
303 // BASE64 encoded string
307 for (lsb
= false, d
= 0, l
= 0;
308 (cc
= utf7unb64
[(unsigned char)*psz
]) != 0xff; psz
++)
312 for (l
+= 6; l
>= 8; lsb
= !lsb
)
314 c
= (d
>> (l
-= 8)) % 256;
330 if (buf
&& (len
< n
))
336 // BASE64 encoding table
338 static const unsigned char utf7enb64
[] =
340 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
341 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
342 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
343 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
344 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
345 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
346 'w', 'x', 'y', 'z', '0', '1', '2', '3',
347 '4', '5', '6', '7', '8', '9', '+', '/'
351 // UTF-7 encoding table
353 // 0 - Set D (directly encoded characters)
354 // 1 - Set O (optional direct characters)
355 // 2 - whitespace characters (optional)
356 // 3 - special characters
358 static const unsigned char utf7encode
[128] =
360 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3,
361 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
362 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 3, 0, 0, 0, 3,
363 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
364 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
365 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1,
366 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
367 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 3, 3
370 size_t wxMBConvUTF7::WC2MB(char *buf
, const wchar_t
371 *psz
, size_t n
) const
377 while (*psz
&& ((!buf
) || (len
< n
)))
380 if (cc
< 0x80 && utf7encode
[cc
] < 1)
388 else if (cc
> 0xffff)
390 // no surrogate pair generation (yet?)
401 // BASE64 encode string
402 unsigned int lsb
, d
, l
;
403 for (d
= 0, l
= 0;; psz
++)
405 for (lsb
= 0; lsb
< 2; lsb
++)
408 d
+= lsb
? cc
& 0xff : (cc
& 0xff00) >> 8;
410 for (l
+= 8; l
>= 6; )
414 *buf
++ = utf7enb64
[(d
>> l
) % 64];
419 if (!(cc
) || (cc
< 0x80 && utf7encode
[cc
] < 1))
425 *buf
++ = utf7enb64
[((d
% 16) << (6 - l
)) % 64];
434 if (buf
&& (len
< n
))
439 // ----------------------------------------------------------------------------
441 // ----------------------------------------------------------------------------
443 static wxUint32 utf8_max
[]=
444 { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff, 0xffffffff };
446 size_t wxMBConvUTF8::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
450 while (*psz
&& ((!buf
) || (len
< n
)))
452 unsigned char cc
= *psz
++, fc
= cc
;
454 for (cnt
= 0; fc
& 0x80; cnt
++)
468 // invalid UTF-8 sequence
473 unsigned ocnt
= cnt
- 1;
474 wxUint32 res
= cc
& (0x3f >> cnt
);
478 if ((cc
& 0xC0) != 0x80)
480 // invalid UTF-8 sequence
483 res
= (res
<< 6) | (cc
& 0x3f);
485 if (res
<= utf8_max
[ocnt
])
487 // illegal UTF-8 encoding
491 // cast is ok because wchar_t == wxUuint16 if WC_UTF16
492 size_t pa
= encode_utf16(res
, (wxUint16
*)buf
);
493 if (pa
== (size_t)-1)
502 #endif // WC_UTF16/!WC_UTF16
506 if (buf
&& (len
< n
))
511 size_t wxMBConvUTF8::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
515 while (*psz
&& ((!buf
) || (len
< n
)))
519 // cast is ok for WC_UTF16
520 size_t pa
= decode_utf16((const wxUint16
*)psz
, cc
);
521 psz
+= (pa
== (size_t)-1) ? 1 : pa
;
523 cc
=(*psz
++) & 0x7fffffff;
526 for (cnt
= 0; cc
> utf8_max
[cnt
]; cnt
++) {}
540 *buf
++ = (char) ((-128 >> cnt
) | ((cc
>> (cnt
* 6)) & (0x3f >> cnt
)));
542 *buf
++ = (char) (0x80 | ((cc
>> (cnt
* 6)) & 0x3f));
547 if (buf
&& (len
<n
)) *buf
= 0;
555 // ----------------------------------------------------------------------------
557 // ----------------------------------------------------------------------------
559 #ifdef WORDS_BIGENDIAN
560 #define wxMBConvUTF16straight wxMBConvUTF16BE
561 #define wxMBConvUTF16swap wxMBConvUTF16LE
563 #define wxMBConvUTF16swap wxMBConvUTF16BE
564 #define wxMBConvUTF16straight wxMBConvUTF16LE
570 // copy 16bit MB to 16bit String
571 size_t wxMBConvUTF16straight::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
575 while (*(wxUint16
*)psz
&& (!buf
|| len
< n
))
578 *buf
++ = *(wxUint16
*)psz
;
581 psz
+= sizeof(wxUint16
);
583 if (buf
&& len
<n
) *buf
=0;
589 // copy 16bit String to 16bit MB
590 size_t wxMBConvUTF16straight::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
594 while (*psz
&& (!buf
|| len
< n
))
598 *(wxUint16
*)buf
= *psz
;
599 buf
+= sizeof(wxUint16
);
601 len
+= sizeof(wxUint16
);
604 if (buf
&& len
<=n
-sizeof(wxUint16
)) *(wxUint16
*)buf
=0;
610 // swap 16bit MB to 16bit String
611 size_t wxMBConvUTF16swap::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
615 while (*(wxUint16
*)psz
&& (!buf
|| len
< n
))
619 ((char *)buf
)[0] = psz
[1];
620 ((char *)buf
)[1] = psz
[0];
624 psz
+= sizeof(wxUint16
);
626 if (buf
&& len
<n
) *buf
=0;
632 // swap 16bit MB to 16bit String
633 size_t wxMBConvUTF16swap::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
637 while (*psz
&& (!buf
|| len
< n
))
641 *buf
++ = ((char*)psz
)[1];
642 *buf
++ = ((char*)psz
)[0];
644 len
+= sizeof(wxUint16
);
647 if (buf
&& len
<=n
-sizeof(wxUint16
)) *(wxUint16
*)buf
=0;
656 // copy 16bit MB to 32bit String
657 size_t wxMBConvUTF16straight::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
661 while (*(wxUint16
*)psz
&& (!buf
|| len
< n
))
664 size_t pa
=decode_utf16((wxUint16
*)psz
, cc
);
665 if (pa
== (size_t)-1)
671 psz
+= pa
* sizeof(wxUint16
);
673 if (buf
&& len
<n
) *buf
=0;
679 // copy 32bit String to 16bit MB
680 size_t wxMBConvUTF16straight::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
684 while (*psz
&& (!buf
|| len
< n
))
687 size_t pa
=encode_utf16(*psz
, cc
);
689 if (pa
== (size_t)-1)
694 *(wxUint16
*)buf
= cc
[0];
695 buf
+= sizeof(wxUint16
);
698 *(wxUint16
*)buf
= cc
[1];
699 buf
+= sizeof(wxUint16
);
703 len
+= pa
*sizeof(wxUint16
);
706 if (buf
&& len
<=n
-sizeof(wxUint16
)) *(wxUint16
*)buf
=0;
712 // swap 16bit MB to 32bit String
713 size_t wxMBConvUTF16swap::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
717 while (*(wxUint16
*)psz
&& (!buf
|| len
< n
))
721 tmp
[0]=psz
[1]; tmp
[1]=psz
[0];
722 tmp
[2]=psz
[3]; tmp
[3]=psz
[2];
724 size_t pa
=decode_utf16((wxUint16
*)tmp
, cc
);
725 if (pa
== (size_t)-1)
732 psz
+= pa
* sizeof(wxUint16
);
734 if (buf
&& len
<n
) *buf
=0;
740 // swap 32bit String to 16bit MB
741 size_t wxMBConvUTF16swap::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
745 while (*psz
&& (!buf
|| len
< n
))
748 size_t pa
=encode_utf16(*psz
, cc
);
750 if (pa
== (size_t)-1)
755 *buf
++ = ((char*)cc
)[1];
756 *buf
++ = ((char*)cc
)[0];
759 *buf
++ = ((char*)cc
)[3];
760 *buf
++ = ((char*)cc
)[2];
764 len
+= pa
*sizeof(wxUint16
);
767 if (buf
&& len
<=n
-sizeof(wxUint16
)) *(wxUint16
*)buf
=0;
775 // ----------------------------------------------------------------------------
777 // ----------------------------------------------------------------------------
779 #ifdef WORDS_BIGENDIAN
780 #define wxMBConvUTF32straight wxMBConvUTF32BE
781 #define wxMBConvUTF32swap wxMBConvUTF32LE
783 #define wxMBConvUTF32swap wxMBConvUTF32BE
784 #define wxMBConvUTF32straight wxMBConvUTF32LE
788 WXDLLIMPEXP_DATA_BASE(wxMBConvUTF32LE
) wxConvUTF32LE
;
789 WXDLLIMPEXP_DATA_BASE(wxMBConvUTF32BE
) wxConvUTF32BE
;
794 // copy 32bit MB to 16bit String
795 size_t wxMBConvUTF32straight::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
799 while (*(wxUint32
*)psz
&& (!buf
|| len
< n
))
803 size_t pa
=encode_utf16(*(wxUint32
*)psz
, cc
);
804 if (pa
== (size_t)-1)
814 psz
+= sizeof(wxUint32
);
816 if (buf
&& len
<n
) *buf
=0;
822 // copy 16bit String to 32bit MB
823 size_t wxMBConvUTF32straight::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
827 while (*psz
&& (!buf
|| len
< n
))
831 // cast is ok for WC_UTF16
832 size_t pa
= decode_utf16((const wxUint16
*)psz
, cc
);
833 if (pa
== (size_t)-1)
838 *(wxUint32
*)buf
= cc
;
839 buf
+= sizeof(wxUint32
);
841 len
+= sizeof(wxUint32
);
845 if (buf
&& len
<=n
-sizeof(wxUint32
))
853 // swap 32bit MB to 16bit String
854 size_t wxMBConvUTF32swap::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
858 while (*(wxUint32
*)psz
&& (!buf
|| len
< n
))
861 tmp
[0] = psz
[3]; tmp
[1] = psz
[2];
862 tmp
[2] = psz
[1]; tmp
[3] = psz
[0];
867 size_t pa
=encode_utf16(*(wxUint32
*)tmp
, cc
);
868 if (pa
== (size_t)-1)
878 psz
+= sizeof(wxUint32
);
888 // swap 16bit String to 32bit MB
889 size_t wxMBConvUTF32swap::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
893 while (*psz
&& (!buf
|| len
< n
))
897 // cast is ok for WC_UTF16
898 size_t pa
=decode_utf16((const wxUint16
*)psz
, *(wxUint32
*)cc
);
899 if (pa
== (size_t)-1)
909 len
+= sizeof(wxUint32
);
913 if (buf
&& len
<=n
-sizeof(wxUint32
))
922 // copy 32bit MB to 32bit String
923 size_t wxMBConvUTF32straight::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
927 while (*(wxUint32
*)psz
&& (!buf
|| len
< n
))
930 *buf
++ = *(wxUint32
*)psz
;
932 psz
+= sizeof(wxUint32
);
942 // copy 32bit String to 32bit MB
943 size_t wxMBConvUTF32straight::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
947 while (*psz
&& (!buf
|| len
< n
))
951 *(wxUint32
*)buf
= *psz
;
952 buf
+= sizeof(wxUint32
);
955 len
+= sizeof(wxUint32
);
959 if (buf
&& len
<=n
-sizeof(wxUint32
))
966 // swap 32bit MB to 32bit String
967 size_t wxMBConvUTF32swap::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
971 while (*(wxUint32
*)psz
&& (!buf
|| len
< n
))
975 ((char *)buf
)[0] = psz
[3];
976 ((char *)buf
)[1] = psz
[2];
977 ((char *)buf
)[2] = psz
[1];
978 ((char *)buf
)[3] = psz
[0];
982 psz
+= sizeof(wxUint32
);
992 // swap 32bit String to 32bit MB
993 size_t wxMBConvUTF32swap::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
997 while (*psz
&& (!buf
|| len
< n
))
1001 *buf
++ = ((char *)psz
)[3];
1002 *buf
++ = ((char *)psz
)[2];
1003 *buf
++ = ((char *)psz
)[1];
1004 *buf
++ = ((char *)psz
)[0];
1006 len
+= sizeof(wxUint32
);
1010 if (buf
&& len
<=n
-sizeof(wxUint32
))
1020 // ============================================================================
1021 // The classes doing conversion using the iconv_xxx() functions
1022 // ============================================================================
1026 // VS: glibc 2.1.3 is broken in that iconv() conversion to/from UCS4 fails with E2BIG
1027 // if output buffer is _exactly_ as big as needed. Such case is (unless there's
1028 // yet another bug in glibc) the only case when iconv() returns with (size_t)-1
1029 // (which means error) and says there are 0 bytes left in the input buffer --
1030 // when _real_ error occurs, bytes-left-in-input buffer is non-zero. Hence,
1031 // this alternative test for iconv() failure.
1032 // [This bug does not appear in glibc 2.2.]
1033 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1
1034 #define ICONV_FAILED(cres, bufLeft) ((cres == (size_t)-1) && \
1035 (errno != E2BIG || bufLeft != 0))
1037 #define ICONV_FAILED(cres, bufLeft) (cres == (size_t)-1)
1040 #define ICONV_CHAR_CAST(x) ((ICONV_CONST char **)(x))
1042 // ----------------------------------------------------------------------------
1043 // wxMBConv_iconv: encapsulates an iconv character set
1044 // ----------------------------------------------------------------------------
1046 class wxMBConv_iconv
: public wxMBConv
1049 wxMBConv_iconv(const wxChar
*name
);
1050 virtual ~wxMBConv_iconv();
1052 virtual size_t MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const;
1053 virtual size_t WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const;
1056 { return (m2w
!= (iconv_t
)-1) && (w2m
!= (iconv_t
)-1); }
1059 // the iconv handlers used to translate from multibyte to wide char and in
1060 // the other direction
1065 // the name (for iconv_open()) of a wide char charset -- if none is
1066 // available on this machine, it will remain NULL
1067 static const char *ms_wcCharsetName
;
1069 // true if the wide char encoding we use (i.e. ms_wcCharsetName) has
1070 // different endian-ness than the native one
1071 static bool ms_wcNeedsSwap
;
1074 const char *wxMBConv_iconv::ms_wcCharsetName
= NULL
;
1075 bool wxMBConv_iconv::ms_wcNeedsSwap
= false;
1077 wxMBConv_iconv::wxMBConv_iconv(const wxChar
*name
)
1079 // Do it the hard way
1081 for (size_t i
= 0; i
< wxStrlen(name
)+1; i
++)
1082 cname
[i
] = (char) name
[i
];
1084 // check for charset that represents wchar_t:
1085 if (ms_wcCharsetName
== NULL
)
1087 ms_wcNeedsSwap
= false;
1089 // try charset with explicit bytesex info (e.g. "UCS-4LE"):
1090 ms_wcCharsetName
= WC_NAME_BEST
;
1091 m2w
= iconv_open(ms_wcCharsetName
, cname
);
1093 if (m2w
== (iconv_t
)-1)
1095 // try charset w/o bytesex info (e.g. "UCS4")
1096 // and check for bytesex ourselves:
1097 ms_wcCharsetName
= WC_NAME
;
1098 m2w
= iconv_open(ms_wcCharsetName
, cname
);
1100 // last bet, try if it knows WCHAR_T pseudo-charset
1101 if (m2w
== (iconv_t
)-1)
1103 ms_wcCharsetName
= "WCHAR_T";
1104 m2w
= iconv_open(ms_wcCharsetName
, cname
);
1107 if (m2w
!= (iconv_t
)-1)
1109 char buf
[2], *bufPtr
;
1110 wchar_t wbuf
[2], *wbufPtr
;
1118 outsz
= SIZEOF_WCHAR_T
* 2;
1122 res
= iconv(m2w
, ICONV_CHAR_CAST(&bufPtr
), &insz
,
1123 (char**)&wbufPtr
, &outsz
);
1125 if (ICONV_FAILED(res
, insz
))
1127 ms_wcCharsetName
= NULL
;
1128 wxLogLastError(wxT("iconv"));
1129 wxLogError(_("Conversion to charset '%s' doesn't work."), name
);
1133 ms_wcNeedsSwap
= wbuf
[0] != (wchar_t)buf
[0];
1138 ms_wcCharsetName
= NULL
;
1140 // VS: we must not output an error here, since wxWidgets will safely
1141 // fall back to using wxEncodingConverter.
1142 wxLogTrace(wxT("strconv"), wxT("Impossible to convert to/from charset '%s' with iconv, falling back to wxEncodingConverter."), name
);
1146 wxLogTrace(wxT("strconv"), wxT("wchar_t charset is '%s', needs swap: %i"), ms_wcCharsetName
, ms_wcNeedsSwap
);
1148 else // we already have ms_wcCharsetName
1150 m2w
= iconv_open(ms_wcCharsetName
, cname
);
1153 // NB: don't ever pass NULL to iconv_open(), it may crash!
1154 if ( ms_wcCharsetName
)
1156 w2m
= iconv_open( cname
, ms_wcCharsetName
);
1164 wxMBConv_iconv::~wxMBConv_iconv()
1166 if ( m2w
!= (iconv_t
)-1 )
1168 if ( w2m
!= (iconv_t
)-1 )
1172 size_t wxMBConv_iconv::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
1174 size_t inbuf
= strlen(psz
);
1175 size_t outbuf
= n
* SIZEOF_WCHAR_T
;
1177 // VS: Use these instead of psz, buf because iconv() modifies its arguments:
1178 wchar_t *bufPtr
= buf
;
1179 const char *pszPtr
= psz
;
1183 // have destination buffer, convert there
1185 ICONV_CHAR_CAST(&pszPtr
), &inbuf
,
1186 (char**)&bufPtr
, &outbuf
);
1187 res
= n
- (outbuf
/ SIZEOF_WCHAR_T
);
1191 // convert to native endianness
1192 WC_BSWAP(buf
/* _not_ bufPtr */, res
)
1195 // NB: iconv was given only strlen(psz) characters on input, and so
1196 // it couldn't convert the trailing zero. Let's do it ourselves
1197 // if there's some room left for it in the output buffer.
1203 // no destination buffer... convert using temp buffer
1204 // to calculate destination buffer requirement
1209 outbuf
= 8*SIZEOF_WCHAR_T
;
1212 ICONV_CHAR_CAST(&pszPtr
), &inbuf
,
1213 (char**)&bufPtr
, &outbuf
);
1215 res
+= 8-(outbuf
/SIZEOF_WCHAR_T
);
1216 } while ((cres
==(size_t)-1) && (errno
==E2BIG
));
1219 if (ICONV_FAILED(cres
, inbuf
))
1221 //VS: it is ok if iconv fails, hence trace only
1222 wxLogTrace(wxT("strconv"), wxT("iconv failed: %s"), wxSysErrorMsg(wxSysErrorCode()));
1229 size_t wxMBConv_iconv::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
1231 size_t inbuf
= wxWcslen(psz
) * SIZEOF_WCHAR_T
;
1235 wchar_t *tmpbuf
= 0;
1239 // need to copy to temp buffer to switch endianness
1240 // this absolutely doesn't rock!
1241 // (no, doing WC_BSWAP twice on the original buffer won't help, as it
1242 // could be in read-only memory, or be accessed in some other thread)
1243 tmpbuf
=(wchar_t*)malloc((inbuf
+1)*SIZEOF_WCHAR_T
);
1244 memcpy(tmpbuf
,psz
,(inbuf
+1)*SIZEOF_WCHAR_T
);
1245 WC_BSWAP(tmpbuf
, inbuf
)
1251 // have destination buffer, convert there
1252 cres
= iconv( w2m
, ICONV_CHAR_CAST(&psz
), &inbuf
, &buf
, &outbuf
);
1256 // NB: iconv was given only wcslen(psz) characters on input, and so
1257 // it couldn't convert the trailing zero. Let's do it ourselves
1258 // if there's some room left for it in the output buffer.
1264 // no destination buffer... convert using temp buffer
1265 // to calculate destination buffer requirement
1269 buf
= tbuf
; outbuf
= 16;
1271 cres
= iconv( w2m
, ICONV_CHAR_CAST(&psz
), &inbuf
, &buf
, &outbuf
);
1274 } while ((cres
==(size_t)-1) && (errno
==E2BIG
));
1282 if (ICONV_FAILED(cres
, inbuf
))
1284 //VS: it is ok if iconv fails, hence trace only
1285 wxLogTrace(wxT("strconv"), wxT("iconv failed: %s"), wxSysErrorMsg(wxSysErrorCode()));
1292 #endif // HAVE_ICONV
1295 // ============================================================================
1296 // Win32 conversion classes
1297 // ============================================================================
1299 #ifdef wxHAVE_WIN32_MB2WC
1303 extern WXDLLIMPEXP_BASE
long wxCharsetToCodepage(const wxChar
*charset
);
1304 extern WXDLLIMPEXP_BASE
long wxEncodingToCodepage(wxFontEncoding encoding
);
1307 class wxMBConv_win32
: public wxMBConv
1312 m_CodePage
= CP_ACP
;
1316 wxMBConv_win32(const wxChar
* name
)
1318 m_CodePage
= wxCharsetToCodepage(name
);
1321 wxMBConv_win32(wxFontEncoding encoding
)
1323 m_CodePage
= wxEncodingToCodepage(encoding
);
1327 size_t MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
1329 // note that we have to use MB_ERR_INVALID_CHARS flag as it without it
1330 // the behaviour is not compatible with the Unix version (using iconv)
1331 // and break the library itself, e.g. wxTextInputStream::NextChar()
1332 // wouldn't work if reading an incomplete MB char didn't result in an
1334 const size_t len
= ::MultiByteToWideChar
1336 m_CodePage
, // code page
1337 MB_ERR_INVALID_CHARS
, // flags: fall on error
1338 psz
, // input string
1339 -1, // its length (NUL-terminated)
1340 buf
, // output string
1341 buf
? n
: 0 // size of output buffer
1344 // note that it returns count of written chars for buf != NULL and size
1345 // of the needed buffer for buf == NULL so in either case the length of
1346 // the string (which never includes the terminating NUL) is one less
1347 return len
? len
- 1 : (size_t)-1;
1350 size_t WC2MB(char *buf
, const wchar_t *pwz
, size_t n
) const
1353 we have a problem here: by default, WideCharToMultiByte() may
1354 replace characters unrepresentable in the target code page with bad
1355 quality approximations such as turning "1/2" symbol (U+00BD) into
1356 "1" for the code pages which don't have it and we, obviously, want
1357 to avoid this at any price
1359 the trouble is that this function does it _silently_, i.e. it won't
1360 even tell us whether it did or not... Win98/2000 and higher provide
1361 WC_NO_BEST_FIT_CHARS but it doesn't work for the older systems and
1362 we have to resort to a round trip, i.e. check that converting back
1363 results in the same string -- this is, of course, expensive but
1364 otherwise we simply can't be sure to not garble the data.
1367 // determine if we can rely on WC_NO_BEST_FIT_CHARS: according to MSDN
1368 // it doesn't work with CJK encodings (which we test for rather roughly
1369 // here...) nor with UTF-7/8 nor, of course, with Windows versions not
1371 BOOL usedDef
wxDUMMY_INITIALIZE(false);
1374 if ( CanUseNoBestFit() && m_CodePage
< 50000 )
1376 // it's our lucky day
1377 flags
= WC_NO_BEST_FIT_CHARS
;
1378 pUsedDef
= &usedDef
;
1380 else // old system or unsupported encoding
1386 const size_t len
= ::WideCharToMultiByte
1388 m_CodePage
, // code page
1389 flags
, // either none or no best fit
1390 pwz
, // input string
1391 -1, // it is (wide) NUL-terminated
1392 buf
, // output buffer
1393 buf
? n
: 0, // and its size
1394 NULL
, // default "replacement" char
1395 pUsedDef
// [out] was it used?
1400 // function totally failed
1404 // if we were really converting, check if we succeeded
1409 // check if the conversion failed, i.e. if any replacements
1414 else // we must resort to double tripping...
1416 wxWCharBuffer
wcBuf(n
);
1417 if ( MB2WC(wcBuf
.data(), buf
, n
) == (size_t)-1 ||
1418 wcscmp(wcBuf
, pwz
) != 0 )
1420 // we didn't obtain the same thing we started from, hence
1421 // the conversion was lossy and we consider that it failed
1427 // see the comment above for the reason of "len - 1"
1431 bool IsOk() const { return m_CodePage
!= -1; }
1434 static bool CanUseNoBestFit()
1436 static int s_isWin98Or2k
= -1;
1438 if ( s_isWin98Or2k
== -1 )
1441 switch ( wxGetOsVersion(&verMaj
, &verMin
) )
1444 s_isWin98Or2k
= verMaj
>= 4 && verMin
>= 10;
1448 s_isWin98Or2k
= verMaj
>= 5;
1452 // unknown, be conseravtive by default
1456 wxASSERT_MSG( s_isWin98Or2k
!= -1, _T("should be set above") );
1459 return s_isWin98Or2k
== 1;
1465 #endif // wxHAVE_WIN32_MB2WC
1467 // ============================================================================
1468 // Cocoa conversion classes
1469 // ============================================================================
1471 #if defined(__WXCOCOA__)
1473 // RN: There is no UTF-32 support in either Core Foundation or
1474 // Cocoa. Strangely enough, internally Core Foundation uses
1475 // UTF 32 internally quite a bit - its just not public (yet).
1477 #include <CoreFoundation/CFString.h>
1478 #include <CoreFoundation/CFStringEncodingExt.h>
1480 CFStringEncoding
wxCFStringEncFromFontEnc(wxFontEncoding encoding
)
1482 CFStringEncoding enc
= 0 ;
1483 if ( encoding
== wxFONTENCODING_DEFAULT
)
1486 encoding
= wxFont::GetDefaultEncoding() ;
1488 encoding
= wxLocale::GetSystemEncoding() ;
1491 else switch( encoding
)
1493 case wxFONTENCODING_ISO8859_1
:
1494 enc
= kCFStringEncodingISOLatin1
;
1496 case wxFONTENCODING_ISO8859_2
:
1497 enc
= kCFStringEncodingISOLatin2
;
1499 case wxFONTENCODING_ISO8859_3
:
1500 enc
= kCFStringEncodingISOLatin3
;
1502 case wxFONTENCODING_ISO8859_4
:
1503 enc
= kCFStringEncodingISOLatin4
;
1505 case wxFONTENCODING_ISO8859_5
:
1506 enc
= kCFStringEncodingISOLatinCyrillic
;
1508 case wxFONTENCODING_ISO8859_6
:
1509 enc
= kCFStringEncodingISOLatinArabic
;
1511 case wxFONTENCODING_ISO8859_7
:
1512 enc
= kCFStringEncodingISOLatinGreek
;
1514 case wxFONTENCODING_ISO8859_8
:
1515 enc
= kCFStringEncodingISOLatinHebrew
;
1517 case wxFONTENCODING_ISO8859_9
:
1518 enc
= kCFStringEncodingISOLatin5
;
1520 case wxFONTENCODING_ISO8859_10
:
1521 enc
= kCFStringEncodingISOLatin6
;
1523 case wxFONTENCODING_ISO8859_11
:
1524 enc
= kCFStringEncodingISOLatinThai
;
1526 case wxFONTENCODING_ISO8859_13
:
1527 enc
= kCFStringEncodingISOLatin7
;
1529 case wxFONTENCODING_ISO8859_14
:
1530 enc
= kCFStringEncodingISOLatin8
;
1532 case wxFONTENCODING_ISO8859_15
:
1533 enc
= kCFStringEncodingISOLatin9
;
1536 case wxFONTENCODING_KOI8
:
1537 enc
= kCFStringEncodingKOI8_R
;
1539 case wxFONTENCODING_ALTERNATIVE
: // MS-DOS CP866
1540 enc
= kCFStringEncodingDOSRussian
;
1543 // case wxFONTENCODING_BULGARIAN :
1547 case wxFONTENCODING_CP437
:
1548 enc
=kCFStringEncodingDOSLatinUS
;
1550 case wxFONTENCODING_CP850
:
1551 enc
= kCFStringEncodingDOSLatin1
;
1553 case wxFONTENCODING_CP852
:
1554 enc
= kCFStringEncodingDOSLatin2
;
1556 case wxFONTENCODING_CP855
:
1557 enc
= kCFStringEncodingDOSCyrillic
;
1559 case wxFONTENCODING_CP866
:
1560 enc
=kCFStringEncodingDOSRussian
;
1562 case wxFONTENCODING_CP874
:
1563 enc
= kCFStringEncodingDOSThai
;
1565 case wxFONTENCODING_CP932
:
1566 enc
= kCFStringEncodingDOSJapanese
;
1568 case wxFONTENCODING_CP936
:
1569 enc
=kCFStringEncodingDOSChineseSimplif
;
1571 case wxFONTENCODING_CP949
:
1572 enc
= kCFStringEncodingDOSKorean
;
1574 case wxFONTENCODING_CP950
:
1575 enc
= kCFStringEncodingDOSChineseTrad
;
1578 case wxFONTENCODING_CP1250
:
1579 enc
= kCFStringEncodingWindowsLatin2
;
1581 case wxFONTENCODING_CP1251
:
1582 enc
=kCFStringEncodingWindowsCyrillic
;
1584 case wxFONTENCODING_CP1252
:
1585 enc
=kCFStringEncodingWindowsLatin1
;
1587 case wxFONTENCODING_CP1253
:
1588 enc
= kCFStringEncodingWindowsGreek
;
1590 case wxFONTENCODING_CP1254
:
1591 enc
= kCFStringEncodingWindowsLatin5
;
1593 case wxFONTENCODING_CP1255
:
1594 enc
=kCFStringEncodingWindowsHebrew
;
1596 case wxFONTENCODING_CP1256
:
1597 enc
=kCFStringEncodingWindowsArabic
;
1599 case wxFONTENCODING_CP1257
:
1600 enc
= kCFStringEncodingWindowsBalticRim
;
1602 case wxFONTENCODING_UTF7
:
1603 enc
= kCFStringEncodingNonLossyASCII
;
1605 case wxFONTENCODING_UTF8
:
1606 enc
= kCFStringEncodingUTF8
;
1608 case wxFONTENCODING_EUC_JP
:
1609 enc
= kCFStringEncodingEUC_JP
;
1611 case wxFONTENCODING_UTF16
:
1612 enc
= kCFStringEncodingUnicode
;
1614 case wxFONTENCODING_MACROMAN
:
1615 enc
= kCFStringEncodingMacRoman
;
1617 case wxFONTENCODING_MACJAPANESE
:
1618 enc
= kCFStringEncodingMacJapanese
;
1620 case wxFONTENCODING_MACCHINESETRAD
:
1621 enc
= kCFStringEncodingMacChineseTrad
;
1623 case wxFONTENCODING_MACKOREAN
:
1624 enc
= kCFStringEncodingMacKorean
;
1626 case wxFONTENCODING_MACARABIC
:
1627 enc
= kCFStringEncodingMacArabic
;
1629 case wxFONTENCODING_MACHEBREW
:
1630 enc
= kCFStringEncodingMacHebrew
;
1632 case wxFONTENCODING_MACGREEK
:
1633 enc
= kCFStringEncodingMacGreek
;
1635 case wxFONTENCODING_MACCYRILLIC
:
1636 enc
= kCFStringEncodingMacCyrillic
;
1638 case wxFONTENCODING_MACDEVANAGARI
:
1639 enc
= kCFStringEncodingMacDevanagari
;
1641 case wxFONTENCODING_MACGURMUKHI
:
1642 enc
= kCFStringEncodingMacGurmukhi
;
1644 case wxFONTENCODING_MACGUJARATI
:
1645 enc
= kCFStringEncodingMacGujarati
;
1647 case wxFONTENCODING_MACORIYA
:
1648 enc
= kCFStringEncodingMacOriya
;
1650 case wxFONTENCODING_MACBENGALI
:
1651 enc
= kCFStringEncodingMacBengali
;
1653 case wxFONTENCODING_MACTAMIL
:
1654 enc
= kCFStringEncodingMacTamil
;
1656 case wxFONTENCODING_MACTELUGU
:
1657 enc
= kCFStringEncodingMacTelugu
;
1659 case wxFONTENCODING_MACKANNADA
:
1660 enc
= kCFStringEncodingMacKannada
;
1662 case wxFONTENCODING_MACMALAJALAM
:
1663 enc
= kCFStringEncodingMacMalayalam
;
1665 case wxFONTENCODING_MACSINHALESE
:
1666 enc
= kCFStringEncodingMacSinhalese
;
1668 case wxFONTENCODING_MACBURMESE
:
1669 enc
= kCFStringEncodingMacBurmese
;
1671 case wxFONTENCODING_MACKHMER
:
1672 enc
= kCFStringEncodingMacKhmer
;
1674 case wxFONTENCODING_MACTHAI
:
1675 enc
= kCFStringEncodingMacThai
;
1677 case wxFONTENCODING_MACLAOTIAN
:
1678 enc
= kCFStringEncodingMacLaotian
;
1680 case wxFONTENCODING_MACGEORGIAN
:
1681 enc
= kCFStringEncodingMacGeorgian
;
1683 case wxFONTENCODING_MACARMENIAN
:
1684 enc
= kCFStringEncodingMacArmenian
;
1686 case wxFONTENCODING_MACCHINESESIMP
:
1687 enc
= kCFStringEncodingMacChineseSimp
;
1689 case wxFONTENCODING_MACTIBETAN
:
1690 enc
= kCFStringEncodingMacTibetan
;
1692 case wxFONTENCODING_MACMONGOLIAN
:
1693 enc
= kCFStringEncodingMacMongolian
;
1695 case wxFONTENCODING_MACETHIOPIC
:
1696 enc
= kCFStringEncodingMacEthiopic
;
1698 case wxFONTENCODING_MACCENTRALEUR
:
1699 enc
= kCFStringEncodingMacCentralEurRoman
;
1701 case wxFONTENCODING_MACVIATNAMESE
:
1702 enc
= kCFStringEncodingMacVietnamese
;
1704 case wxFONTENCODING_MACARABICEXT
:
1705 enc
= kCFStringEncodingMacExtArabic
;
1707 case wxFONTENCODING_MACSYMBOL
:
1708 enc
= kCFStringEncodingMacSymbol
;
1710 case wxFONTENCODING_MACDINGBATS
:
1711 enc
= kCFStringEncodingMacDingbats
;
1713 case wxFONTENCODING_MACTURKISH
:
1714 enc
= kCFStringEncodingMacTurkish
;
1716 case wxFONTENCODING_MACCROATIAN
:
1717 enc
= kCFStringEncodingMacCroatian
;
1719 case wxFONTENCODING_MACICELANDIC
:
1720 enc
= kCFStringEncodingMacIcelandic
;
1722 case wxFONTENCODING_MACROMANIAN
:
1723 enc
= kCFStringEncodingMacRomanian
;
1725 case wxFONTENCODING_MACCELTIC
:
1726 enc
= kCFStringEncodingMacCeltic
;
1728 case wxFONTENCODING_MACGAELIC
:
1729 enc
= kCFStringEncodingMacGaelic
;
1731 // case wxFONTENCODING_MACKEYBOARD :
1732 // enc = kCFStringEncodingMacKeyboardGlyphs ;
1735 // because gcc is picky
1741 wxFontEncoding
wxFontEncFromCFStringEnc(CFStringEncoding encoding
)
1743 wxFontEncoding enc
= wxFONTENCODING_DEFAULT
;
1747 case kCFStringEncodingISOLatin1
:
1748 enc
= wxFONTENCODING_ISO8859_1
;
1750 case kCFStringEncodingISOLatin2
:
1751 enc
= wxFONTENCODING_ISO8859_2
;
1753 case kCFStringEncodingISOLatin3
:
1754 enc
= wxFONTENCODING_ISO8859_3
;
1756 case kCFStringEncodingISOLatin4
:
1757 enc
= wxFONTENCODING_ISO8859_4
;
1759 case kCFStringEncodingISOLatinCyrillic
:
1760 enc
= wxFONTENCODING_ISO8859_5
;
1762 case kCFStringEncodingISOLatinArabic
:
1763 enc
= wxFONTENCODING_ISO8859_6
;
1765 case kCFStringEncodingISOLatinGreek
:
1766 enc
= wxFONTENCODING_ISO8859_7
;
1768 case kCFStringEncodingISOLatinHebrew
:
1769 enc
= wxFONTENCODING_ISO8859_8
;
1771 case kCFStringEncodingISOLatin5
:
1772 enc
= wxFONTENCODING_ISO8859_9
;
1774 case kCFStringEncodingISOLatin6
:
1775 enc
= wxFONTENCODING_ISO8859_10
;
1777 case kCFStringEncodingISOLatin7
:
1778 enc
= wxFONTENCODING_ISO8859_13
;
1780 case kCFStringEncodingISOLatin8
:
1781 enc
= wxFONTENCODING_ISO8859_14
;
1783 case kCFStringEncodingISOLatin9
:
1784 enc
=wxFONTENCODING_ISO8859_15
;
1787 case kCFStringEncodingKOI8_R
:
1788 enc
= wxFONTENCODING_KOI8
;
1792 // enc = wxFONTENCODING_BULGARIAN;
1795 case kCFStringEncodingDOSLatinUS
:
1796 enc
= wxFONTENCODING_CP437
;
1798 case kCFStringEncodingDOSLatin1
:
1799 enc
= wxFONTENCODING_CP850
;
1801 case kCFStringEncodingDOSLatin2
:
1802 enc
=wxFONTENCODING_CP852
;
1804 case kCFStringEncodingDOSCyrillic
:
1805 enc
= wxFONTENCODING_CP855
;
1807 case kCFStringEncodingDOSRussian
:
1808 enc
= wxFONTENCODING_CP866
;
1810 case kCFStringEncodingDOSThai
:
1811 enc
=wxFONTENCODING_CP874
;
1813 case kCFStringEncodingDOSJapanese
:
1814 enc
= wxFONTENCODING_CP932
;
1816 case kCFStringEncodingDOSChineseSimplif
:
1817 enc
= wxFONTENCODING_CP936
;
1819 case kCFStringEncodingDOSKorean
:
1820 enc
= wxFONTENCODING_CP949
;
1822 case kCFStringEncodingDOSChineseTrad
:
1823 enc
= wxFONTENCODING_CP950
;
1826 case kCFStringEncodingWindowsLatin2
:
1827 enc
= wxFONTENCODING_CP1250
;
1829 case kCFStringEncodingWindowsCyrillic
:
1830 enc
= wxFONTENCODING_CP1251
;
1832 case kCFStringEncodingWindowsLatin1
:
1833 enc
= wxFONTENCODING_CP1252
;
1835 case kCFStringEncodingWindowsGreek
:
1836 enc
= wxFONTENCODING_CP1253
;
1838 case kCFStringEncodingWindowsLatin5
:
1839 enc
= wxFONTENCODING_CP1254
;
1841 case kCFStringEncodingWindowsHebrew
:
1842 enc
= wxFONTENCODING_CP1255
;
1844 case kCFStringEncodingWindowsArabic
:
1845 enc
= wxFONTENCODING_CP1256
;
1847 case kCFStringEncodingWindowsBalticRim
:
1848 enc
=wxFONTENCODING_CP1257
;
1850 case kCFStringEncodingEUC_JP
:
1851 enc
= wxFONTENCODING_EUC_JP
;
1853 case kCFStringEncodingUnicode
:
1854 enc
= wxFONTENCODING_UTF16
;
1856 case kCFStringEncodingMacRoman
:
1857 enc
= wxFONTENCODING_MACROMAN
;
1859 case kCFStringEncodingMacJapanese
:
1860 enc
= wxFONTENCODING_MACJAPANESE
;
1862 case kCFStringEncodingMacChineseTrad
:
1863 enc
= wxFONTENCODING_MACCHINESETRAD
;
1865 case kCFStringEncodingMacKorean
:
1866 enc
= wxFONTENCODING_MACKOREAN
;
1868 case kCFStringEncodingMacArabic
:
1869 enc
=wxFONTENCODING_MACARABIC
;
1871 case kCFStringEncodingMacHebrew
:
1872 enc
= wxFONTENCODING_MACHEBREW
;
1874 case kCFStringEncodingMacGreek
:
1875 enc
= wxFONTENCODING_MACGREEK
;
1877 case kCFStringEncodingMacCyrillic
:
1878 enc
= wxFONTENCODING_MACCYRILLIC
;
1880 case kCFStringEncodingMacDevanagari
:
1881 enc
= wxFONTENCODING_MACDEVANAGARI
;
1883 case kCFStringEncodingMacGurmukhi
:
1884 enc
= wxFONTENCODING_MACGURMUKHI
;
1886 case kCFStringEncodingMacGujarati
:
1887 enc
= wxFONTENCODING_MACGUJARATI
;
1889 case kCFStringEncodingMacOriya
:
1890 enc
=wxFONTENCODING_MACORIYA
;
1892 case kCFStringEncodingMacBengali
:
1893 enc
=wxFONTENCODING_MACBENGALI
;
1895 case kCFStringEncodingMacTamil
:
1896 enc
= wxFONTENCODING_MACTAMIL
;
1898 case kCFStringEncodingMacTelugu
:
1899 enc
= wxFONTENCODING_MACTELUGU
;
1901 case kCFStringEncodingMacKannada
:
1902 enc
= wxFONTENCODING_MACKANNADA
;
1904 case kCFStringEncodingMacMalayalam
:
1905 enc
= wxFONTENCODING_MACMALAJALAM
;
1907 case kCFStringEncodingMacSinhalese
:
1908 enc
= wxFONTENCODING_MACSINHALESE
;
1910 case kCFStringEncodingMacBurmese
:
1911 enc
= wxFONTENCODING_MACBURMESE
;
1913 case kCFStringEncodingMacKhmer
:
1914 enc
= wxFONTENCODING_MACKHMER
;
1916 case kCFStringEncodingMacThai
:
1917 enc
= wxFONTENCODING_MACTHAI
;
1919 case kCFStringEncodingMacLaotian
:
1920 enc
= wxFONTENCODING_MACLAOTIAN
;
1922 case kCFStringEncodingMacGeorgian
:
1923 enc
= wxFONTENCODING_MACGEORGIAN
;
1925 case kCFStringEncodingMacArmenian
:
1926 enc
= wxFONTENCODING_MACARMENIAN
;
1928 case kCFStringEncodingMacChineseSimp
:
1929 enc
= wxFONTENCODING_MACCHINESESIMP
;
1931 case kCFStringEncodingMacTibetan
:
1932 enc
= wxFONTENCODING_MACTIBETAN
;
1934 case kCFStringEncodingMacMongolian
:
1935 enc
= wxFONTENCODING_MACMONGOLIAN
;
1937 case kCFStringEncodingMacEthiopic
:
1938 enc
= wxFONTENCODING_MACETHIOPIC
;
1940 case kCFStringEncodingMacCentralEurRoman
:
1941 enc
= wxFONTENCODING_MACCENTRALEUR
;
1943 case kCFStringEncodingMacVietnamese
:
1944 enc
= wxFONTENCODING_MACVIATNAMESE
;
1946 case kCFStringEncodingMacExtArabic
:
1947 enc
= wxFONTENCODING_MACARABICEXT
;
1949 case kCFStringEncodingMacSymbol
:
1950 enc
= wxFONTENCODING_MACSYMBOL
;
1952 case kCFStringEncodingMacDingbats
:
1953 enc
= wxFONTENCODING_MACDINGBATS
;
1955 case kCFStringEncodingMacTurkish
:
1956 enc
= wxFONTENCODING_MACTURKISH
;
1958 case kCFStringEncodingMacCroatian
:
1959 enc
= wxFONTENCODING_MACCROATIAN
;
1961 case kCFStringEncodingMacIcelandic
:
1962 enc
= wxFONTENCODING_MACICELANDIC
;
1964 case kCFStringEncodingMacRomanian
:
1965 enc
= wxFONTENCODING_MACROMANIAN
;
1967 case kCFStringEncodingMacCeltic
:
1968 enc
= wxFONTENCODING_MACCELTIC
;
1970 case kCFStringEncodingMacGaelic
:
1971 enc
= wxFONTENCODING_MACGAELIC
;
1973 // case kCFStringEncodingMacKeyboardGlyphs :
1974 // enc = wxFONTENCODING_MACKEYBOARD ;
1980 class wxMBConv_cocoa
: public wxMBConv
1985 Init(CFStringGetSystemEncoding()) ;
1988 wxMBConv_cocoa(const wxChar
* name
)
1990 Init( wxCFStringEncFromFontEnc(wxFontMapper::Get()->CharsetToEncoding(name
, false) ) ) ;
1993 wxMBConv_cocoa(wxFontEncoding encoding
)
1995 Init( wxCFStringEncFromFontEnc(encoding
) );
2002 void Init( CFStringEncoding encoding
)
2004 m_char_encoding
= encoding
;
2005 m_unicode_encoding
= kCFStringEncodingUnicode
;
2008 size_t MB2WC(wchar_t * szOut
, const char * szUnConv
, size_t nOutSize
) const
2012 size_t nBufSize
= strlen(szUnConv
) + 1;
2013 size_t nRealOutSize
;
2015 UniChar
* szUniCharBuffer
= (UniChar
*) szOut
;
2016 wchar_t* szConvBuffer
= szOut
;
2018 if (szConvBuffer
== NULL
&& nOutSize
!= 0)
2020 szConvBuffer
= new wchar_t[nOutSize
] ;
2023 #if SIZEOF_WCHAR_T == 4
2024 szUniCharBuffer
= new UniChar
[nOutSize
];
2027 CFDataRef theData
= CFDataCreateWithBytesNoCopy (
2029 (const UInt8
*)szUnConv
,
2036 CFStringRef theString
= CFStringCreateFromExternalRepresentation (
2042 wxASSERT(theString
);
2046 nRealOutSize
= CFStringGetLength(theString
) + 1;
2047 CFRelease(theString
);
2048 return nRealOutSize
- 1;
2051 CFRange theRange
= { 0, CFStringGetLength(theString
) };
2053 CFStringGetCharacters(theString
, theRange
, szUniCharBuffer
);
2056 nRealOutSize
= (CFStringGetLength(theString
) + 1);
2058 CFRelease(theString
);
2060 szUniCharBuffer
[nRealOutSize
-1] = '\0' ;
2062 #if SIZEOF_WCHAR_T == 4
2063 wxMBConvUTF16 converter
;
2064 converter
.MB2WC(szConvBuffer
, (const char*)szUniCharBuffer
, nRealOutSize
) ;
2065 delete[] szUniCharBuffer
;
2067 if ( szOut
== NULL
)
2068 delete [] szConvBuffer
;
2070 return nRealOutSize
;
2073 size_t WC2MB(char *szOut
, const wchar_t *szUnConv
, size_t nOutSize
) const
2075 size_t nBufSize
= wxWcslen(szUnConv
) + 1;
2076 size_t nRealOutSize
;
2077 char* szBuffer
= szOut
;
2078 UniChar
* szUniBuffer
= (UniChar
*) szUnConv
;
2083 nRealOutSize
= wxString::WorstEncodingCase(nBufSize
- 1, *this)+1 ;
2084 szBuffer
= new char[ nRealOutSize
] ;
2087 nRealOutSize
= nOutSize
;
2089 #if SIZEOF_WCHAR_T == 4
2090 wxMBConvUTF16BE converter
;
2091 nBufSize
= converter
.WC2MB( NULL
, szUnConv
, 0 );
2092 szUniBuffer
= new UniChar
[ (nBufSize
/ sizeof(UniChar
)) + 1] ;
2093 converter
.WC2MB( (char*) szUniBuffer
, szUnConv
, nBufSize
+ sizeof(UniChar
)) ;
2094 nBufSize
/= sizeof(UniChar
);
2098 CFStringRef theString
= CFStringCreateWithCharactersNoCopy(
2105 wxASSERT(theString
);
2107 //Note that CER puts a BOM when converting to unicode
2108 //so we may want to check and use getchars instead in that case
2109 CFDataRef theData
= CFStringCreateExternalRepresentation(
2113 0 //what to put in characters that can't be converted -
2114 //0 tells CFString to return NULL if it meets such a character
2120 CFRelease(theString
);
2122 nRealOutSize
= CFDataGetLength(theData
);
2124 if ( szOut
== NULL
)
2129 //TODO: This gets flagged as a non-malloced address by the debugger...
2130 //#if SIZEOF_WCHAR_T == 4
2131 // delete[] szUniBuffer;
2134 return nRealOutSize
- 1;
2137 CFRange theRange
= {0, CFDataGetLength(theData
) };
2138 CFDataGetBytes(theData
, theRange
, (UInt8
*) szBuffer
);
2142 //TODO: This gets flagged as a non-malloced address by the debugger...
2143 //#if SIZEOF_WCHAR_T == 4
2144 // delete[] szUniBuffer;
2146 return nRealOutSize
- 1;
2151 //TODO: check for invalid en/de/coding
2156 CFStringEncoding m_char_encoding
;
2157 CFStringEncoding m_unicode_encoding
;
2160 #endif // defined(__WXCOCOA__)
2162 // ============================================================================
2163 // Mac conversion classes
2164 // ============================================================================
2166 #if defined(__WXMAC__) && defined(TARGET_CARBON)
2168 class wxMBConv_mac
: public wxMBConv
2173 Init(CFStringGetSystemEncoding()) ;
2176 wxMBConv_mac(const wxChar
* name
)
2178 Init( wxMacGetSystemEncFromFontEnc(wxFontMapper::Get()->CharsetToEncoding(name
, false) ) ) ;
2181 wxMBConv_mac(wxFontEncoding encoding
)
2183 Init( wxMacGetSystemEncFromFontEnc(encoding
) );
2188 OSStatus status
= noErr
;
2189 status
= TECDisposeConverter(m_MB2WC_converter
);
2190 status
= TECDisposeConverter(m_WC2MB_converter
);
2194 void Init( TextEncodingBase encoding
)
2196 OSStatus status
= noErr
;
2197 m_char_encoding
= encoding
;
2198 m_unicode_encoding
= CreateTextEncoding(kTextEncodingUnicodeDefault
,0,kUnicode16BitFormat
) ;
2200 status
= TECCreateConverter(&m_MB2WC_converter
,
2202 m_unicode_encoding
);
2203 status
= TECCreateConverter(&m_WC2MB_converter
,
2208 size_t MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
2210 OSStatus status
= noErr
;
2211 ByteCount byteOutLen
;
2212 ByteCount byteInLen
= strlen(psz
) ;
2213 wchar_t *tbuf
= NULL
;
2214 UniChar
* ubuf
= NULL
;
2220 tbuf
= (wchar_t*) malloc( n
* SIZEOF_WCHAR_T
) ;
2222 ByteCount byteBufferLen
= n
* sizeof( UniChar
) ;
2223 #if SIZEOF_WCHAR_T == 4
2224 ubuf
= (UniChar
*) malloc( byteBufferLen
+ 2 ) ;
2226 ubuf
= (UniChar
*) (buf
? buf
: tbuf
) ;
2228 status
= TECConvertText(m_MB2WC_converter
, (ConstTextPtr
) psz
, byteInLen
, &byteInLen
,
2229 (TextPtr
) ubuf
, byteBufferLen
, &byteOutLen
);
2230 #if SIZEOF_WCHAR_T == 4
2231 // we have to terminate here, because n might be larger for the trailing zero, and if UniChar
2232 // is not properly terminated we get random characters at the end
2233 ubuf
[byteOutLen
/ sizeof( UniChar
) ] = 0 ;
2234 wxMBConvUTF16BE converter
;
2235 res
= converter
.MB2WC( (buf
? buf
: tbuf
) , (const char*)ubuf
, n
) ;
2238 res
= byteOutLen
/ sizeof( UniChar
) ;
2243 if ( buf
&& res
< n
)
2249 size_t WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
2251 OSStatus status
= noErr
;
2252 ByteCount byteOutLen
;
2253 ByteCount byteInLen
= wxWcslen(psz
) * SIZEOF_WCHAR_T
;
2260 n
= wxString::WorstEncodingCase(byteInLen
/ SIZEOF_WCHAR_T
, *this) + SIZEOF_WCHAR_T
;
2261 tbuf
= (char*) malloc( n
) ;
2264 ByteCount byteBufferLen
= n
;
2265 UniChar
* ubuf
= NULL
;
2266 #if SIZEOF_WCHAR_T == 4
2267 wxMBConvUTF16BE converter
;
2268 size_t unicharlen
= converter
.WC2MB( NULL
, psz
, 0 ) ;
2269 byteInLen
= unicharlen
;
2270 ubuf
= (UniChar
*) malloc( byteInLen
+ 2 ) ;
2271 converter
.WC2MB( (char*) ubuf
, psz
, unicharlen
+ 2 ) ;
2273 ubuf
= (UniChar
*) psz
;
2275 status
= TECConvertText(m_WC2MB_converter
, (ConstTextPtr
) ubuf
, byteInLen
, &byteInLen
,
2276 (TextPtr
) (buf
? buf
: tbuf
) , byteBufferLen
, &byteOutLen
);
2277 #if SIZEOF_WCHAR_T == 4
2283 size_t res
= byteOutLen
;
2284 if ( buf
&& res
< n
)
2291 { return m_MB2WC_converter
!= NULL
&& m_WC2MB_converter
!= NULL
; }
2294 TECObjectRef m_MB2WC_converter
;
2295 TECObjectRef m_WC2MB_converter
;
2297 TextEncodingBase m_char_encoding
;
2298 TextEncodingBase m_unicode_encoding
;
2301 #endif // defined(__WXMAC__) && defined(TARGET_CARBON)
2303 // ============================================================================
2304 // wxEncodingConverter based conversion classes
2305 // ============================================================================
2309 class wxMBConv_wxwin
: public wxMBConv
2314 m_ok
= m2w
.Init(m_enc
, wxFONTENCODING_UNICODE
) &&
2315 w2m
.Init(wxFONTENCODING_UNICODE
, m_enc
);
2319 // temporarily just use wxEncodingConverter stuff,
2320 // so that it works while a better implementation is built
2321 wxMBConv_wxwin(const wxChar
* name
)
2324 m_enc
= wxFontMapper::Get()->CharsetToEncoding(name
, false);
2326 m_enc
= wxFONTENCODING_SYSTEM
;
2331 wxMBConv_wxwin(wxFontEncoding enc
)
2338 size_t MB2WC(wchar_t *buf
, const char *psz
, size_t WXUNUSED(n
)) const
2340 size_t inbuf
= strlen(psz
);
2342 m2w
.Convert(psz
,buf
);
2346 size_t WC2MB(char *buf
, const wchar_t *psz
, size_t WXUNUSED(n
)) const
2348 const size_t inbuf
= wxWcslen(psz
);
2350 w2m
.Convert(psz
,buf
);
2355 bool IsOk() const { return m_ok
; }
2358 wxFontEncoding m_enc
;
2359 wxEncodingConverter m2w
, w2m
;
2361 // were we initialized successfully?
2364 DECLARE_NO_COPY_CLASS(wxMBConv_wxwin
)
2367 #endif // wxUSE_FONTMAP
2369 // ============================================================================
2370 // wxCSConv implementation
2371 // ============================================================================
2373 void wxCSConv::Init()
2380 wxCSConv::wxCSConv(const wxChar
*charset
)
2389 m_encoding
= wxFONTENCODING_SYSTEM
;
2392 wxCSConv::wxCSConv(wxFontEncoding encoding
)
2394 if ( encoding
== wxFONTENCODING_MAX
|| encoding
== wxFONTENCODING_DEFAULT
)
2396 wxFAIL_MSG( _T("invalid encoding value in wxCSConv ctor") );
2398 encoding
= wxFONTENCODING_SYSTEM
;
2403 m_encoding
= encoding
;
2406 wxCSConv::~wxCSConv()
2411 wxCSConv::wxCSConv(const wxCSConv
& conv
)
2416 SetName(conv
.m_name
);
2417 m_encoding
= conv
.m_encoding
;
2420 wxCSConv
& wxCSConv::operator=(const wxCSConv
& conv
)
2424 SetName(conv
.m_name
);
2425 m_encoding
= conv
.m_encoding
;
2430 void wxCSConv::Clear()
2439 void wxCSConv::SetName(const wxChar
*charset
)
2443 m_name
= wxStrdup(charset
);
2448 wxMBConv
*wxCSConv::DoCreate() const
2450 // check for the special case of ASCII or ISO8859-1 charset: as we have
2451 // special knowledge of it anyhow, we don't need to create a special
2452 // conversion object
2453 if ( m_encoding
== wxFONTENCODING_ISO8859_1
)
2455 // don't convert at all
2459 // we trust OS to do conversion better than we can so try external
2460 // conversion methods first
2462 // the full order is:
2463 // 1. OS conversion (iconv() under Unix or Win32 API)
2464 // 2. hard coded conversions for UTF
2465 // 3. wxEncodingConverter as fall back
2471 #endif // !wxUSE_FONTMAP
2473 wxString
name(m_name
);
2477 name
= wxFontMapper::Get()->GetEncodingName(m_encoding
);
2478 #endif // wxUSE_FONTMAP
2480 wxMBConv_iconv
*conv
= new wxMBConv_iconv(name
);
2486 #endif // HAVE_ICONV
2488 #ifdef wxHAVE_WIN32_MB2WC
2491 wxMBConv_win32
*conv
= m_name
? new wxMBConv_win32(m_name
)
2492 : new wxMBConv_win32(m_encoding
);
2501 #endif // wxHAVE_WIN32_MB2WC
2502 #if defined(__WXMAC__)
2504 if ( m_name
|| ( m_encoding
< wxFONTENCODING_UTF16BE
) )
2507 wxMBConv_mac
*conv
= m_name
? new wxMBConv_mac(m_name
)
2508 : new wxMBConv_mac(m_encoding
);
2516 #if defined(__WXCOCOA__)
2518 if ( m_name
|| ( m_encoding
<= wxFONTENCODING_UTF16
) )
2521 wxMBConv_cocoa
*conv
= m_name
? new wxMBConv_cocoa(m_name
)
2522 : new wxMBConv_cocoa(m_encoding
);
2531 wxFontEncoding enc
= m_encoding
;
2533 if ( enc
== wxFONTENCODING_SYSTEM
&& m_name
)
2535 // use "false" to suppress interactive dialogs -- we can be called from
2536 // anywhere and popping up a dialog from here is the last thing we want to
2538 enc
= wxFontMapper::Get()->CharsetToEncoding(m_name
, false);
2540 #endif // wxUSE_FONTMAP
2544 case wxFONTENCODING_UTF7
:
2545 return new wxMBConvUTF7
;
2547 case wxFONTENCODING_UTF8
:
2548 return new wxMBConvUTF8
;
2550 case wxFONTENCODING_UTF16BE
:
2551 return new wxMBConvUTF16BE
;
2553 case wxFONTENCODING_UTF16LE
:
2554 return new wxMBConvUTF16LE
;
2556 case wxFONTENCODING_UTF32BE
:
2557 return new wxMBConvUTF32BE
;
2559 case wxFONTENCODING_UTF32LE
:
2560 return new wxMBConvUTF32LE
;
2563 // nothing to do but put here to suppress gcc warnings
2570 wxMBConv_wxwin
*conv
= m_name
? new wxMBConv_wxwin(m_name
)
2571 : new wxMBConv_wxwin(m_encoding
);
2577 #endif // wxUSE_FONTMAP
2579 // NB: This is a hack to prevent deadlock. What could otherwise happen
2580 // in Unicode build: wxConvLocal creation ends up being here
2581 // because of some failure and logs the error. But wxLog will try to
2582 // attach timestamp, for which it will need wxConvLocal (to convert
2583 // time to char* and then wchar_t*), but that fails, tries to log
2584 // error, but wxLog has a (already locked) critical section that
2585 // guards static buffer.
2586 static bool alreadyLoggingError
= false;
2587 if (!alreadyLoggingError
)
2589 alreadyLoggingError
= true;
2590 wxLogError(_("Cannot convert from the charset '%s'!"),
2594 wxFontMapper::GetEncodingDescription(m_encoding
).c_str()
2595 #else // !wxUSE_FONTMAP
2596 wxString::Format(_("encoding %s"), m_encoding
).c_str()
2597 #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
2599 alreadyLoggingError
= false;
2605 void wxCSConv::CreateConvIfNeeded() const
2609 wxCSConv
*self
= (wxCSConv
*)this; // const_cast
2612 // if we don't have neither the name nor the encoding, use the default
2613 // encoding for this system
2614 if ( !m_name
&& m_encoding
== wxFONTENCODING_SYSTEM
)
2616 self
->m_name
= wxStrdup(wxLocale::GetSystemEncodingName());
2618 #endif // wxUSE_INTL
2620 self
->m_convReal
= DoCreate();
2621 self
->m_deferred
= false;
2625 size_t wxCSConv::MB2WC(wchar_t *buf
, const char *psz
, size_t n
) const
2627 CreateConvIfNeeded();
2630 return m_convReal
->MB2WC(buf
, psz
, n
);
2633 size_t len
= strlen(psz
);
2637 for (size_t c
= 0; c
<= len
; c
++)
2638 buf
[c
] = (unsigned char)(psz
[c
]);
2644 size_t wxCSConv::WC2MB(char *buf
, const wchar_t *psz
, size_t n
) const
2646 CreateConvIfNeeded();
2649 return m_convReal
->WC2MB(buf
, psz
, n
);
2652 const size_t len
= wxWcslen(psz
);
2655 for (size_t c
= 0; c
<= len
; c
++)
2659 buf
[c
] = (char)psz
[c
];
2664 for (size_t c
= 0; c
<= len
; c
++)
2674 // ----------------------------------------------------------------------------
2676 // ----------------------------------------------------------------------------
2679 static wxMBConv_win32 wxConvLibcObj
;
2680 #elif defined(__WXMAC__) && !defined(__MACH__)
2681 static wxMBConv_mac wxConvLibcObj
;
2683 static wxMBConvLibc wxConvLibcObj
;
2686 static wxCSConv
wxConvLocalObj(wxFONTENCODING_SYSTEM
);
2687 static wxCSConv
wxConvISO8859_1Obj(wxFONTENCODING_ISO8859_1
);
2688 static wxMBConvUTF7 wxConvUTF7Obj
;
2689 static wxMBConvUTF8 wxConvUTF8Obj
;
2692 WXDLLIMPEXP_DATA_BASE(wxMBConv
&) wxConvLibc
= wxConvLibcObj
;
2693 WXDLLIMPEXP_DATA_BASE(wxCSConv
&) wxConvLocal
= wxConvLocalObj
;
2694 WXDLLIMPEXP_DATA_BASE(wxCSConv
&) wxConvISO8859_1
= wxConvISO8859_1Obj
;
2695 WXDLLIMPEXP_DATA_BASE(wxMBConvUTF7
&) wxConvUTF7
= wxConvUTF7Obj
;
2696 WXDLLIMPEXP_DATA_BASE(wxMBConvUTF8
&) wxConvUTF8
= wxConvUTF8Obj
;
2697 WXDLLIMPEXP_DATA_BASE(wxMBConv
*) wxConvCurrent
= &wxConvLibcObj
;
2699 #else // !wxUSE_WCHAR_T
2701 // stand-ins in absence of wchar_t
2702 WXDLLIMPEXP_DATA_BASE(wxMBConv
) wxConvLibc
,
2707 #endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T